diff -Nru openjdk-17-17.0.5+8/debian/changelog openjdk-17-17.0.6+10/debian/changelog --- openjdk-17-17.0.5+8/debian/changelog 2022-10-24 12:44:46.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/changelog 2023-01-20 08:56:27.000000000 +0000 @@ -1,8 +1,26 @@ -openjdk-17 (17.0.5+8-2ubuntu1~22.04) jammy-security; urgency=medium +openjdk-17 (17.0.6+10-0ubuntu1~22.04) jammy-security; urgency=medium - * Upload to Ubuntu 22.04 LTS. + * Upload to Ubuntu 22.04. - -- Matthias Klose Mon, 24 Oct 2022 14:44:46 +0200 + -- Vladimir Petko Fri, 20 Jan 2023 21:56:27 +1300 + +openjdk-17 (17.0.6+10-0ubuntu1) lunar; urgency=medium + + * OpenJDK 17.0.6 release, build 10. + - CVE-2023-21835, CVE-2023-21843 + - Release notes: + https://www.oracle.com/java/technologies/javase/17-0-6-relnotes.html + * debian/patches/*: Refreshed patches for the new release and dropped unused + patches. + * debian/rules: add lunar to jtreg version selection. + + -- Vladimir Petko Thu, 19 Jan 2023 21:34:14 +1300 + +openjdk-17 (17.0.5+8-2ubuntu1) kinetic-security; urgency=medium + + * Handle jtreg package name for backports. + + -- Matthias Klose Mon, 24 Oct 2022 18:33:55 +0200 openjdk-17 (17.0.5+8-2) unstable; urgency=medium diff -Nru openjdk-17-17.0.5+8/debian/control openjdk-17-17.0.6+10/debian/control --- openjdk-17-17.0.5+8/debian/control 2022-10-24 12:44:46.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/control 2023-01-17 23:05:30.000000000 +0000 @@ -1,7 +1,8 @@ Source: openjdk-17 Section: java Priority: optional -Maintainer: OpenJDK Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: OpenJDK Team Uploaders: Matthias Klose Build-Depends: debhelper (>= 11), m4, lsb-release, zip, unzip, @@ -9,7 +10,7 @@ time, strip-nondeterminism, debugedit (>= 4.16), jtreg6 (>= 6+1-0~) , testng , xvfb , xauth , xfonts-base , libgl1-mesa-dri [!x32] , xfwm4 , x11-xkb-utils , dbus-x11 , autoconf, automake, autotools-dev, ant, ant-optional, - g++-11 , + g++-12 , openjdk-17-jdk-headless:native | openjdk-16-jdk-headless:native, libxtst-dev, libxi-dev, libxt-dev, libxaw7-dev, libxrender-dev, libcups2-dev, libasound2-dev, liblcms2-dev, libfreetype6-dev (>= 2.2.1), libxinerama-dev, libkrb5-dev, xsltproc, libpcsclite-dev, libxrandr-dev, libelf-dev, libfontconfig1-dev, libgtk2.0-0 | libgtk-3-0, libharfbuzz-dev, libffi-dev, diff -Nru openjdk-17-17.0.5+8/debian/control.in openjdk-17-17.0.6+10/debian/control.in --- openjdk-17-17.0.5+8/debian/control.in 2021-06-17 11:30:11.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/control.in 2023-01-17 23:05:30.000000000 +0000 @@ -1,7 +1,8 @@ Source: @basename@ Section: java Priority: optional -Maintainer: OpenJDK Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: OpenJDK Team Uploaders: Matthias Klose Build-Depends: @bd_debhelper@ m4, lsb-release, zip, unzip, diff -Nru openjdk-17-17.0.5+8/debian/patches/accessible-toolkit.diff openjdk-17-17.0.6+10/debian/patches/accessible-toolkit.diff --- openjdk-17-17.0.5+8/debian/patches/accessible-toolkit.diff 2015-06-16 09:38:27.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/accessible-toolkit.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ ---- a/jdk/src/share/classes/java/awt/Toolkit.java -+++ b/jdk/src/share/classes/java/awt/Toolkit.java -@@ -894,7 +894,11 @@ - return null; - } - }); -- loadAssistiveTechnologies(); -+ try { -+ loadAssistiveTechnologies(); -+ } catch ( AWTError error) { -+ // ignore silently -+ } - } finally { - // Make sure to always re-enable the JIT. - java.lang.Compiler.enable(); diff -Nru openjdk-17-17.0.5+8/debian/patches/adlc-parser.diff openjdk-17-17.0.6+10/debian/patches/adlc-parser.diff --- openjdk-17-17.0.5+8/debian/patches/adlc-parser.diff 2020-12-03 15:52:04.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/adlc-parser.diff 2023-01-18 04:17:28.000000000 +0000 @@ -1,11 +1,22 @@ # DP: fixes an uninitialized memory issue in adlc --- a/src/hotspot/share/adlc/formsopt.cpp +++ b/src/hotspot/share/adlc/formsopt.cpp -@@ -445,6 +445,7 @@ FrameForm::FrameForm() { +@@ -436,6 +436,10 @@ + //==============================Frame Handling================================= + //------------------------------FrameForm-------------------------------------- + FrameForm::FrameForm() { ++ _sync_stack_slots = NULL; ++ _inline_cache_reg = NULL; ++ _interpreter_frame_pointer_reg = NULL; ++ _cisc_spilling_operand_name = NULL; + _frame_pointer = NULL; + _c_frame_pointer = NULL; + _alignment = NULL; +@@ -444,7 +448,6 @@ + _varargs_C_out_slots_killed = NULL; _return_value = NULL; _c_return_value = NULL; - _interpreter_frame_pointer_reg = NULL; -+ _cisc_spilling_operand_name = NULL; +- _interpreter_frame_pointer_reg = NULL; } FrameForm::~FrameForm() { diff -Nru openjdk-17-17.0.5+8/debian/patches/default-jvm-cfg.diff openjdk-17-17.0.6+10/debian/patches/default-jvm-cfg.diff --- openjdk-17-17.0.5+8/debian/patches/default-jvm-cfg.diff 2022-05-02 18:22:39.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/default-jvm-cfg.diff 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/src/java.base/share/native/libjli/java.c +++ b/src/java.base/share/native/libjli/java.c -@@ -2079,7 +2079,7 @@ jint +@@ -1997,7 +1997,7 @@ ReadKnownVMs(const char *jvmCfgName, jboolean speculative) { FILE *jvmCfg; @@ -9,7 +9,7 @@ int cnt = 0; int lineno = 0; jlong start = 0, end = 0; -@@ -2094,6 +2094,11 @@ ReadKnownVMs(const char *jvmCfgName, jbo +@@ -2012,6 +2012,11 @@ jvmCfg = fopen(jvmCfgName, "r"); if (jvmCfg == NULL) { diff -Nru openjdk-17-17.0.5+8/debian/patches/enumipv6-fix.diff openjdk-17-17.0.6+10/debian/patches/enumipv6-fix.diff --- openjdk-17-17.0.5+8/debian/patches/enumipv6-fix.diff 2015-06-16 09:38:27.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/enumipv6-fix.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- openjdk/jdk/src/solaris/native/java/net/NetworkInterface.c~ 2012-02-15 09:26:50.000000000 +0100 -+++ openjdk/jdk/src/solaris/native/java/net/NetworkInterface.c 2012-02-26 14:13:22.602107361 +0100 -@@ -1105,7 +1105,7 @@ - uint8_t ipv6addr[16]; - - if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { -- while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", -+ while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %x %x %x %x %20s\n", - addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], - &if_idx, &plen, &scope, &dad_status, devname) != EOF) { - diff -Nru openjdk-17-17.0.5+8/debian/patches/generated-headers.patch openjdk-17-17.0.6+10/debian/patches/generated-headers.patch --- openjdk-17-17.0.5+8/debian/patches/generated-headers.patch 2021-05-27 09:29:16.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/generated-headers.patch 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk +++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk -@@ -289,7 +289,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIB +@@ -290,7 +290,7 @@ INCLUDE_FILES := $(BUILD_LIBLCMS_INCLUDE_FILES), \ OPTIMIZATION := HIGHEST, \ CFLAGS := $(CFLAGS_JDKLIB) \ @@ -9,7 +9,7 @@ CFLAGS_windows := -DCMS_IS_WINDOWS_, \ EXTRA_HEADER_DIRS := \ common/awt/debug \ -@@ -337,7 +337,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIB +@@ -338,7 +338,7 @@ NAME := javajpeg, \ INCLUDE_FILES := $(BUILD_LIBJAVAJPEG_INCLUDE_FILES), \ OPTIMIZATION := HIGHEST, \ diff -Nru openjdk-17-17.0.5+8/debian/patches/hotspot-disable-exec-shield-workaround.diff openjdk-17-17.0.6+10/debian/patches/hotspot-disable-exec-shield-workaround.diff --- openjdk-17-17.0.5+8/debian/patches/hotspot-disable-exec-shield-workaround.diff 2021-05-27 09:29:10.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/hotspot-disable-exec-shield-workaround.diff 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp -@@ -635,7 +635,7 @@ void os::verify_stack_alignment() { +@@ -651,7 +651,7 @@ * updates (JDK-8023956). */ void os::workaround_expand_exec_shield_cs_limit() { diff -Nru openjdk-17-17.0.5+8/debian/patches/hotspot-disable-werror.diff openjdk-17-17.0.6+10/debian/patches/hotspot-disable-werror.diff --- openjdk-17-17.0.5+8/debian/patches/hotspot-disable-werror.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/hotspot-disable-werror.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- a/src/hotspot/make/linux/makefiles/gcc.make -+++ b/src/hotspot/make/linux/makefiles/gcc.make -@@ -203,7 +203,7 @@ else - endif - - # Compiler warnings are treated as errors --WARNINGS_ARE_ERRORS ?= -Werror -Wno-error=format -+WARNINGS_ARE_ERRORS ?= - - ifeq ($(USE_CLANG), true) - # However we need to clean the code up before we can unrestrictedly enable this option with Clang diff -Nru openjdk-17-17.0.5+8/debian/patches/hotspot-set-compiler.diff openjdk-17-17.0.6+10/debian/patches/hotspot-set-compiler.diff --- openjdk-17-17.0.5+8/debian/patches/hotspot-set-compiler.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/hotspot-set-compiler.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- a/src/hotspot/make/linux/makefiles/gcc.make -+++ b/src/hotspot/make/linux/makefiles/gcc.make -@@ -39,7 +39,7 @@ - ifeq ($(USE_CLANG), true) - CXX = clang++ - CC = clang -- else -+ else ifeq ($(CXX),) - CXX = g++ - CC = gcc - endif diff -Nru openjdk-17-17.0.5+8/debian/patches/hotspot-warn-no-errformat.diff openjdk-17-17.0.6+10/debian/patches/hotspot-warn-no-errformat.diff --- openjdk-17-17.0.5+8/debian/patches/hotspot-warn-no-errformat.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/hotspot-warn-no-errformat.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ ---- a/src/hotspot/make/solaris/makefiles/gcc.make -+++ b/src/hotspot/make/solaris/makefiles/gcc.make -@@ -117,7 +117,7 @@ endif - - - # Compiler warnings are treated as errors --WARNINGS_ARE_ERRORS ?= -Werror -+WARNINGS_ARE_ERRORS ?= -Werror -Wno-error=format - - # Enable these warnings. See 'info gcc' about details on these options - WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef -Wformat=2 ---- a/src/hotspot/make/linux/makefiles/gcc.make -+++ b/src/hotspot/make/linux/makefiles/gcc.make -@@ -203,7 +203,7 @@ else - endif - - # Compiler warnings are treated as errors --WARNINGS_ARE_ERRORS ?= -Werror -+WARNINGS_ARE_ERRORS ?= -Werror -Wno-error=format - - ifeq ($(USE_CLANG), true) - # However we need to clean the code up before we can unrestrictedly enable this option with Clang diff -Nru openjdk-17-17.0.5+8/debian/patches/include-all-srcs.diff openjdk-17-17.0.6+10/debian/patches/include-all-srcs.diff --- openjdk-17-17.0.5+8/debian/patches/include-all-srcs.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/include-all-srcs.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ ---- a/src/jdk/make/CreateJars.gmk -+++ b/src/jdk/make/CreateJars.gmk -@@ -569,38 +569,12 @@ - ########################################################################################## - - SRC_ZIP_INCLUDES = \ -- com/sun/corba \ -- com/sun/image/codec/jpeg \ -- com/sun/imageio \ -- com/sun/java_cup \ -- com/sun/javadoc \ -- com/sun/java/swing \ -- com/sun/jmx \ -- com/sun/naming \ -- com/sun/org/apache \ -- com/sun/security/auth \ -- com/sun/security/jgss \ -- com/sun/source \ -+ com \ - java \ -- javax/accessibility \ -- javax/annotation \ -- javax/imageio \ -- javax/lang \ -- javax/management \ -- javax/naming \ -- javax/print \ -- javax/rmi \ -- javax/script \ -- javax/security \ -- javax/sound \ -- javax/sql \ -- javax/swing \ -- javax/tools \ -- javax/xml \ -- org/ietf \ -- org/omg \ -- org/w3c/dom \ -- org/xml/sax \ -+ javax \ -+ jdk \ -+ org \ -+ sun \ - # - - SRC_ZIP_SRCS = $(JDK_TOPDIR)/src/share/classes $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes -@@ -632,7 +606,6 @@ - $(eval $(call SetupZipArchive,BUILD_SRC_ZIP, \ - SRC := $(SRC_ZIP_SRCS) $(IMAGES_OUTPUTDIR)/src, \ - INCLUDES := $(SRC_ZIP_INCLUDES) launcher, \ -- EXCLUDES := javax/swing/beaninfo, \ - SUFFIXES := .java .c .h, \ - ZIP := $(IMAGES_OUTPUTDIR)/src.zip, \ - EXTRA_DEPS := $(LAUNCHER_ZIP_SRC))) diff -Nru openjdk-17-17.0.5+8/debian/patches/java-access-bridge-security.diff openjdk-17-17.0.6+10/debian/patches/java-access-bridge-security.diff --- openjdk-17-17.0.5+8/debian/patches/java-access-bridge-security.diff 2015-06-16 09:38:27.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/java-access-bridge-security.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -# patch only used for builds with java-access-bridge support - ---- openjdk/jdk/src/share/lib/security/java.security-linux -+++ openjdk/jdk/src/share/lib/security/java.security-linux -@@ -149,7 +149,9 @@ - com.sun.org.apache.xml.internal.security.,\ - com.sun.org.glassfish.,\ - org.jcp.xml.dsig.internal.,\ -- oracle.jrockit.jfr. -+ oracle.jrockit.jfr.,\ -+ org.GNOME.Accessibility.,\ -+ org.GNOME.Bonobo. - # - # List of comma-separated packages that start with or equal this string - # will cause a security exception to be thrown when diff -Nru openjdk-17-17.0.5+8/debian/patches/jaw-classpath.diff openjdk-17-17.0.6+10/debian/patches/jaw-classpath.diff --- openjdk-17-17.0.5+8/debian/patches/jaw-classpath.diff 2022-07-20 09:27:43.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/jaw-classpath.diff 2023-01-17 22:36:38.000000000 +0000 @@ -2,7 +2,7 @@ --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp -@@ -461,6 +461,7 @@ void os::init_system_properties_values() +@@ -464,6 +464,7 @@ if (!set_boot_path('/', ':')) { vm_exit_during_initialization("Failed setting boot class path.", NULL); } diff -Nru openjdk-17-17.0.5+8/debian/patches/jdk-pulseaudio.diff openjdk-17-17.0.6+10/debian/patches/jdk-pulseaudio.diff --- openjdk-17-17.0.5+8/debian/patches/jdk-pulseaudio.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/jdk-pulseaudio.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ ---- a/src/jdk/src/java.desktop/share/conf/sound.properties -+++ b/src/jdk/src/java.desktop/share/conf/sound.properties -@@ -37,3 +37,13 @@ - # Specify the default Receiver by provider and name: - # javax.sound.midi.Receiver=com.sun.media.sound.MidiProvider#SunMIDI1 - # -+ -+javax.sound.sampled.Clip=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider -+javax.sound.sampled.Port=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider -+javax.sound.sampled.SourceDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider -+javax.sound.sampled.TargetDataLine=org.classpath.icedtea.pulseaudio.PulseAudioMixerProvider -+ -+#javax.sound.sampled.Clip=com.sun.media.sound.DirectAudioDeviceProvider -+#javax.sound.sampled.Port=com.sun.media.sound.PortMixerProvider -+#javax.sound.sampled.SourceDataLine=com.sun.media.sound.DirectAudioDeviceProvider -+#javax.sound.sampled.TargetDataLine=com.sun.media.sound.DirectAudioDeviceProvider diff -Nru openjdk-17-17.0.5+8/debian/patches/jexec.diff openjdk-17-17.0.6+10/debian/patches/jexec.diff --- openjdk-17-17.0.5+8/debian/patches/jexec.diff 2020-03-20 14:44:00.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/jexec.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ ---- a/src/java.base/unix/native/launcher/jexec.c -+++ b/src/java.base/unix/native/launcher/jexec.c -@@ -168,9 +168,10 @@ int main(int argc, const char * argv[]) - - /* Get the path to the java binary, which is in a known position relative - * to our current position, which is in argv[0]. */ -- if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) { -+ if (getJavaPath(JDK_BASE_DIR "/lib/jexec", java, RELATIVE_DEPTH) != 0) { - errorExit(errno, MISSING_JAVA_MSG); - } -+ argi++; - alen = (argc + 2) * (sizeof (const char *)); - if (alen <= 0 || alen > INT_MAX / sizeof(char *)) { - errorExit(errno, BAD_ARG_MSG); ---- a/make/launcher/Launcher-java.base.gmk -+++ b/make/launcher/Launcher-java.base.gmk -@@ -56,6 +56,9 @@ $(eval $(call SetupBuildLauncher, keytoo - ################################################################################ - - ifeq ($(call isTargetOs, linux), true) -+ ifeq (,$(DEBIAN_JDK_BASE_DIR)) -+ $(error DEBIAN_JDK_BASE_DIR must be defined for jexec build) -+ endif - $(eval $(call SetupJdkExecutable, BUILD_JEXEC, \ - NAME := jexec, \ - SRC := $(TOPDIR)/src/$(MODULE)/unix/native/launcher, \ -@@ -63,7 +66,7 @@ ifeq ($(call isTargetOs, linux), true) - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKEXE) \ - -I$(TOPDIR)/src/$(MODULE)/share/native/libjli, \ -- CFLAGS_linux := -fPIC, \ -+ CFLAGS_linux := -fPIC '-DJDK_BASE_DIR="$(DEBIAN_JDK_BASE_DIR)"', \ - CFLAGS_solaris := -KPIC, \ - LDFLAGS := $(LDFLAGS_JDKEXE), \ - OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \ diff -Nru openjdk-17-17.0.5+8/debian/patches/multiple-pkcs11-library-init.diff openjdk-17-17.0.6+10/debian/patches/multiple-pkcs11-library-init.diff --- openjdk-17-17.0.5+8/debian/patches/multiple-pkcs11-library-init.diff 2022-05-02 18:22:44.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/multiple-pkcs11-library-init.diff 2023-01-17 22:36:38.000000000 +0000 @@ -7,7 +7,7 @@ --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java -@@ -52,6 +52,7 @@ final class Config { +@@ -52,6 +52,7 @@ static final int ERR_HALT = 1; static final int ERR_IGNORE_ALL = 2; static final int ERR_IGNORE_LIB = 3; @@ -15,7 +15,7 @@ // same as allowSingleThreadedModules but controlled via a system property // and applied to all providers. if set to false, no SunPKCS11 instances -@@ -1019,6 +1020,8 @@ final class Config { +@@ -1023,6 +1024,8 @@ handleStartupErrors = ERR_IGNORE_LIB; } else if (val.equals("halt")) { handleStartupErrors = ERR_HALT; @@ -26,7 +26,7 @@ } --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java -@@ -179,26 +179,37 @@ public final class SunPKCS11 extends Aut +@@ -179,26 +179,37 @@ String nssLibraryDirectory = config.getNssLibraryDirectory(); String nssSecmodDirectory = config.getNssSecmodDirectory(); boolean nssOptimizeSpace = config.getNssOptimizeSpace(); diff -Nru openjdk-17-17.0.5+8/debian/patches/no-pch-build.diff openjdk-17-17.0.6+10/debian/patches/no-pch-build.diff --- openjdk-17-17.0.5+8/debian/patches/no-pch-build.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/no-pch-build.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ ---- a/src/hotspot/src/share/vm/oops/arrayKlassKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/arrayKlassKlass.cpp 2013-04-15 13:57:24.992929086 +0200 -@@ -30,6 +30,7 @@ - #include "runtime/handles.inline.hpp" - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/oops/constantPoolKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/constantPoolKlass.cpp 2013-04-15 14:02:52.143087149 +0200 -@@ -49,6 +49,7 @@ - #endif - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/oops/cpCacheKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/cpCacheKlass.cpp 2013-04-15 14:04:45.219838633 +0200 -@@ -35,6 +35,7 @@ - #include "runtime/handles.inline.hpp" - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/oops/instanceKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/instanceKlass.cpp 2013-04-15 14:07:55.861109867 +0200 -@@ -70,6 +70,7 @@ - #include "gc_implementation/g1/g1RemSet.inline.hpp" - #include "gc_implementation/g1/heapRegionSeq.inline.hpp" - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "oops/oop.pcgc.inline.hpp" ---- a/src/hotspot/src/share/vm/oops/instanceKlassKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/instanceKlassKlass.cpp 2013-04-15 14:08:53.541485528 +0200 -@@ -44,6 +44,7 @@ - #include "runtime/fieldDescriptor.hpp" - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp 2013-04-15 14:10:11.162003798 +0200 -@@ -42,6 +42,7 @@ - #include "gc_implementation/g1/g1RemSet.inline.hpp" - #include "gc_implementation/g1/heapRegionSeq.inline.hpp" - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "oops/oop.pcgc.inline.hpp" ---- a/src/hotspot/src/share/vm/oops/instanceRefKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/instanceRefKlass.cpp 2013-04-15 14:11:11.726403390 +0200 -@@ -39,6 +39,7 @@ - #include "gc_implementation/g1/g1RemSet.inline.hpp" - #include "gc_implementation/g1/heapRegionSeq.inline.hpp" - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "oops/oop.pcgc.inline.hpp" ---- a/src/hotspot/src/share/vm/oops/klassKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/klassKlass.cpp 2013-04-15 14:13:01.999133769 +0200 -@@ -42,6 +42,7 @@ - #include "runtime/handles.inline.hpp" - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/oops/objArrayKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/objArrayKlass.cpp 2013-04-15 14:16:10.616389484 +0200 -@@ -47,6 +47,7 @@ - #include "gc_implementation/g1/g1RemSet.inline.hpp" - #include "gc_implementation/g1/heapRegionSeq.inline.hpp" - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psCompactionManager.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" ---- a/src/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp 2013-04-15 14:17:01.800729154 +0200 -@@ -33,6 +33,7 @@ - #include "oops/oop.inline2.hpp" - #ifndef SERIALGC - #include "gc_implementation/parNew/parOopClosures.inline.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" - #include "memory/cardTableRS.hpp" ---- a/src/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp~ 2013-03-04 22:51:00.000000000 +0100 -+++ b/src/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp 2013-04-15 14:20:24.782079605 +0200 -@@ -28,6 +28,7 @@ - #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" - #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" - #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" -+#include "gc_implementation/parallelScavenge/psOldGen.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.hpp" - #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" - #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" diff -Nru openjdk-17-17.0.5+8/debian/patches/nspr+nss-headers.diff openjdk-17-17.0.6+10/debian/patches/nspr+nss-headers.diff --- openjdk-17-17.0.5+8/debian/patches/nspr+nss-headers.diff 2021-05-27 09:32:57.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/nspr+nss-headers.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,9090 +0,0 @@ -Replace header files in src/jdk.crypto.cryptoki/share/native/libj2pkcs11. - -Import from NSPR 4.29: - - prcpucfg.h - - prtypes.h - -Import from NSS 2.63: - - pkcs11.h - - pkcs11f.h - - pkcs11n.h - - pkcs11p.h - - pkcs11t.h - - pkcs11u.h - -src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h: - - Remove macro CK_PTR - - Remove macro CK_DEFINE_FUNCTION - - Remove macro CK_DECLARE_FUNCTION - - Remove macro CK_DECLARE_FUNCTION_POINTER - - Remove macro CK_CALLBACK_FUNCTION - -src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h: - - use CK_TRUE/CK_FALSE instead of TRUE/FALSE - -src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c: - - FIXME: CKM_KEA_DERIVE is undefined - -src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c: - - FIXME: CKM_CAMELLIA_CTR is undefined - - ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h -@@ -1,10 +1,15 @@ --/* Copyright (c) OASIS Open 2016-2019. All Rights Reserved. -- * Distributed under the terms of the OASIS IPR Policy, -- * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY -- * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A -- * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+/* -+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document -+ * is granted provided that it is identified as "RSA Security In.c Public-Key -+ * Cryptography Standards (PKCS)" in all material mentioning or referencing -+ * this document. -+ * -+ * The latest version of this header can be found at: -+ * http://www.rsalabs.com/pkcs/pkcs-11/index.html - */ -- - #ifndef _PKCS11_H_ - #define _PKCS11_H_ 1 - -@@ -13,20 +18,21 @@ extern "C" { - #endif - - /* Before including this file (pkcs11.h) (or pkcs11t.h by -- * itself), 5 platform-specific macros must be defined. These -+ * itself), 6 platform-specific macros must be defined. These - * macros are described below, and typical definitions for them - * are also given. Be advised that these definitions can depend - * on both the platform and the compiler used (and possibly also -- * on whether a Cryptoki library is linked statically or -+ * on whether a PKCS #11 library is linked statically or - * dynamically). - * -- * In addition to defining these 5 macros, the packing convention -- * for Cryptoki structures should be set. The Cryptoki -+ * In addition to defining these 6 macros, the packing convention -+ * for PKCS #11 structures should be set. The PKCS #11 - * convention on packing is that structures should be 1-byte - * aligned. - * -- * If you're using Windows this might be done by using the following -- * preprocessor directive before including pkcs11.h or pkcs11t.h: -+ * In a Win32 environment, this might be done by using the -+ * following preprocessor directive before including pkcs11.h -+ * or pkcs11t.h: - * - * #pragma pack(push, cryptoki, 1) - * -@@ -35,8 +41,8 @@ extern "C" { - * - * #pragma pack(pop, cryptoki) - * -- * In a UNIX environment, you're on your own for this. You might -- * not need to do (or be able to do!) anything. -+ * In a UNIX environment, you're on your own here. You might -+ * not need to do anything. - * - * - * Now for the macros: -@@ -47,17 +53,42 @@ extern "C" { - * - * typedef CK_BYTE CK_PTR CK_BYTE_PTR; - * -- * If you're using windows, it might be defined by: -+ * In a Win32 environment, it might be defined by - * - * #define CK_PTR * - * -- * In a typical UNIX environment, it might be defined by: -+ * In a UNIX environment, it might be defined by - * - * #define CK_PTR * - * - * -- * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes -- * an importable Cryptoki library function declaration out of a -+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes -+ * an exportable PKCS #11 library function definition out of a -+ * return type and a function name. It should be used in the -+ * following fashion to define the exposed PKCS #11 functions in -+ * a PKCS #11 library: -+ * -+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( -+ * CK_VOID_PTR pReserved -+ * ) -+ * { -+ * ... -+ * } -+ * -+ * For defining a function in a Win32 PKCS #11 .dll, it might be -+ * defined by -+ * -+ * #define CK_DEFINE_FUNCTION(returnType, name) \ -+ * returnType __declspec(dllexport) name -+ * -+ * In a UNIX environment, it might be defined by -+ * -+ * #define CK_DEFINE_FUNCTION(returnType, name) \ -+ * returnType name -+ * -+ * -+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes -+ * an importable PKCS #11 library function declaration out of a - * return type and a function name. It should be used in the - * following fashion: - * -@@ -65,49 +96,49 @@ extern "C" { - * CK_VOID_PTR pReserved - * ); - * -- * If you're using Windows to declare a function in a Win32 cryptoki .dll, -- * it might be defined by: -+ * For declaring a function in a Win32 PKCS #11 .dll, it might -+ * be defined by - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType __declspec(dllimport) name - * -- * In a UNIX environment, it might be defined by: -+ * In a UNIX environment, it might be defined by - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType name - * - * -- * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro -- * which makes a Cryptoki API function pointer declaration or -+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro -+ * which makes a PKCS #11 API function pointer declaration or - * function pointer type declaration out of a return type and a - * function name. It should be used in the following fashion: - * -- * // Define funcPtr to be a pointer to a Cryptoki API function -+ * // Define funcPtr to be a pointer to a PKCS #11 API function - * // taking arguments args and returning CK_RV. - * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); - * - * or - * - * // Define funcPtrType to be the type of a pointer to a -- * // Cryptoki API function taking arguments args and returning -+ * // PKCS #11 API function taking arguments args and returning - * // CK_RV, and then define funcPtr to be a variable of type - * // funcPtrType. - * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); - * funcPtrType funcPtr; - * -- * If you're using Windows to access -- * functions in a Win32 Cryptoki .dll, in might be defined by: -+ * For accessing functions in a Win32 PKCS #11 .dll, in might be -+ * defined by - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType __declspec(dllimport) (* name) - * -- * In a UNIX environment, it might be defined by: -+ * In a UNIX environment, it might be defined by - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType (* name) - * - * -- * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes -+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes - * a function pointer type for an application callback out of - * a return type for the callback and a name for the callback. - * It should be used in the following fashion: -@@ -121,77 +152,76 @@ extern "C" { - * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); - * myCallbackType myCallback; - * -- * If you're using Windows, it might be defined by: -+ * In a Win32 environment, it might be defined by - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) - * -- * In a UNIX environment, it might be defined by: -+ * In a UNIX environment, it might be defined by - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) - * - * -- * 5. NULL_PTR: This macro is the value of a NULL pointer. -+ * 6. NULL_PTR: This macro is the value of a NULL pointer. - * - * In any ANSI/ISO C environment (and in many others as well), -- * this should best be defined by -+ * this should be defined by - * - * #ifndef NULL_PTR - * #define NULL_PTR 0 - * #endif - */ - -- --/* All the various Cryptoki types and #define'd values are in the -- * file pkcs11t.h. -- */ -+/* All the various PKCS #11 types and #define'd values are in the -+ * file pkcs11t.h. */ - #include "pkcs11t.h" - --#define __PASTE(x,y) x##y -+#define __PASTE(x, y) x##y - -+#ifndef CK_PKCS11_3_0 -+/* remember that we set it so we can unset it at the end */ -+#define __NSS_CK_PKCS11_3_IMPLICIT 1 -+#define CK_PKCS11_3_0 1 -+#endif - - /* ============================================================== - * Define the "extern" form of all the entry points. - * ============================================================== - */ - --#define CK_NEED_ARG_LIST 1 -+#define CK_NEED_ARG_LIST 1 - #define CK_PKCS11_FUNCTION_INFO(name) \ -- extern CK_DECLARE_FUNCTION(CK_RV, name) -+ CK_DECLARE_FUNCTION(CK_RV, name) - --/* pkcs11f.h has all the information about the Cryptoki -- * function prototypes. -- */ -+/* pkcs11f.h has all the information about the PKCS #11 -+ * function prototypes. */ - #include "pkcs11f.h" - - #undef CK_NEED_ARG_LIST - #undef CK_PKCS11_FUNCTION_INFO - -- - /* ============================================================== - * Define the typedef form of all the entry points. That is, for -- * each Cryptoki function C_XXX, define a type CK_C_XXX which is -+ * each PKCS #11 function C_XXX, define a type CK_C_XXX which is - * a pointer to that kind of function. - * ============================================================== - */ - --#define CK_NEED_ARG_LIST 1 -+#define CK_NEED_ARG_LIST 1 - #define CK_PKCS11_FUNCTION_INFO(name) \ -- typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) -+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_, name)) - --/* pkcs11f.h has all the information about the Cryptoki -- * function prototypes. -- */ -+/* pkcs11f.h has all the information about the PKCS #11 -+ * function prototypes. */ - #include "pkcs11f.h" - - #undef CK_NEED_ARG_LIST - #undef CK_PKCS11_FUNCTION_INFO - -- - /* ============================================================== -- * Define structed vector of entry points. A CK_FUNCTION_LIST -- * contains a CK_VERSION indicating a library's Cryptoki version -+ * Define structed vector of entry points. A CK_FUNCTION_3_0_LIST -+ * contains a CK_VERSION indicating a library's PKCS #11 version - * and then a whole slew of function pointers to the routines in - * the library. This type was declared, but not defined, in - * pkcs11t.h. -@@ -199,39 +229,41 @@ extern "C" { - */ - - #define CK_PKCS11_FUNCTION_INFO(name) \ -- __PASTE(CK_,name) name; -+ __PASTE(CK_, name) \ -+ name; - --/* Create the 3.0 Function list */ -+#include "pkcs11p.h" - struct CK_FUNCTION_LIST_3_0 { - -- CK_VERSION version; /* Cryptoki version */ -+ CK_VERSION version; /* PKCS #11 version */ - --/* Pile all the function pointers into the CK_FUNCTION_LIST. */ --/* pkcs11f.h has all the information about the Cryptoki -- * function prototypes. -- */ -+/* Pile all the function pointers into the CK_FUNCTION_LIST_3_0. */ -+/* pkcs11f.h has all the information about the PKCS #11 -+ * function prototypes. */ - #include "pkcs11f.h" -- - }; - - #define CK_PKCS11_2_0_ONLY 1 - --/* Continue to define the old CK_FUNCTION_LIST */ -+/* now define the 2.0 function list */ - struct CK_FUNCTION_LIST { - -- CK_VERSION version; /* Cryptoki version */ -+ CK_VERSION version; /* PKCS #11 version */ - - /* Pile all the function pointers into the CK_FUNCTION_LIST. */ --/* pkcs11f.h has all the information about the Cryptoki -- * function prototypes. -- */ -+/* pkcs11f.h has all the information about the PKCS #11 -+ * function prototypes. */ - #include "pkcs11f.h" -- - }; -+#include "pkcs11u.h" - - #undef CK_PKCS11_FUNCTION_INFO - #undef CK_PKCS11_2_0_ONLY - -+#ifdef __NSS_CK_PKCS11_3_IMPLICIT -+#undef CK_PKCS11_3_0 -+#undef __NSS_CK_PKCS11_3_IMPLICIT -+#endif - - #undef __PASTE - -@@ -239,6 +271,4 @@ struct CK_FUNCTION_LIST { - } - #endif - --#endif /* _PKCS11_H_ */ -- -- -+#endif ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h -@@ -1,1197 +1,1044 @@ --/* Copyright (c) OASIS Open 2016, 2019. All Rights Reserved./ -- * /Distributed under the terms of the OASIS IPR Policy, -- * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY -- * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A -- * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. -- */ -- --/* Latest version of the specification: -- * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html -- */ -- --/* This header file contains pretty much everything about all the -- * Cryptoki function prototypes. Because this information is -- * used for more than just declaring function prototypes, the -- * order of the functions appearing herein is important, and -- * should not be altered. -- */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+/* -+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document -+ * is granted provided that it is identified as "RSA Security In.c Public-Key -+ * Cryptography Standards (PKCS)" in all material mentioning or referencing -+ * this document. -+ */ -+/* This function contains pretty much everything about all the */ -+/* PKCS #11 function prototypes. Because this information is */ -+/* used for more than just declaring function prototypes, the */ -+/* order of the functions appearing herein is important, and */ -+/* should not be altered. */ - - /* General-purpose */ - --/* C_Initialize initializes the Cryptoki library. */ -+/* C_Initialize initializes the PKCS #11 library. */ - CK_PKCS11_FUNCTION_INFO(C_Initialize) - #ifdef CK_NEED_ARG_LIST - ( -- CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets -- * cast to CK_C_INITIALIZE_ARGS_PTR -- * and dereferenced -- */ --); -+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets -+ * cast to CK_C_INITIALIZE_ARGS_PTR -+ * and dereferenced */ -+ ); - #endif - -- - /* C_Finalize indicates that an application is done with the -- * Cryptoki library. -- */ -+ * PKCS #11 library. */ - CK_PKCS11_FUNCTION_INFO(C_Finalize) - #ifdef CK_NEED_ARG_LIST - ( -- CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ --); -+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ -+ ); - #endif - -- --/* C_GetInfo returns general information about Cryptoki. */ -+/* C_GetInfo returns general information about PKCS #11. */ - CK_PKCS11_FUNCTION_INFO(C_GetInfo) - #ifdef CK_NEED_ARG_LIST - ( -- CK_INFO_PTR pInfo /* location that receives information */ --); -+ CK_INFO_PTR pInfo /* location that receives information */ -+ ); - #endif - -- - /* C_GetFunctionList returns the function list. */ - CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) - #ifdef CK_NEED_ARG_LIST - ( -- CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to -- * function list -- */ --); -+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to -+ * function list */ -+ ); - #endif - -- -- - /* Slot and token management */ - - /* C_GetSlotList obtains a list of slots in the system. */ - CK_PKCS11_FUNCTION_INFO(C_GetSlotList) - #ifdef CK_NEED_ARG_LIST - ( -- CK_BBOOL tokenPresent, /* only slots with tokens */ -- CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ -- CK_ULONG_PTR pulCount /* receives number of slots */ --); -+ CK_BBOOL tokenPresent, /* only slots with tokens? */ -+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ -+ CK_ULONG_PTR pulCount /* receives number of slots */ -+ ); - #endif - -- - /* C_GetSlotInfo obtains information about a particular slot in -- * the system. -- */ -+ * the system. */ - CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID, /* the ID of the slot */ -- CK_SLOT_INFO_PTR pInfo /* receives the slot information */ --); -+ CK_SLOT_ID slotID, /* the ID of the slot */ -+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */ -+ ); - #endif - -- - /* C_GetTokenInfo obtains information about a particular token -- * in the system. -- */ -+ * in the system. */ - CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID, /* ID of the token's slot */ -- CK_TOKEN_INFO_PTR pInfo /* receives the token information */ --); -+ CK_SLOT_ID slotID, /* ID of the token's slot */ -+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */ -+ ); - #endif - -- - /* C_GetMechanismList obtains a list of mechanism types -- * supported by a token. -- */ -+ * supported by a token. */ - CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID, /* ID of token's slot */ -- CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ -- CK_ULONG_PTR pulCount /* gets # of mechs. */ --); -+ CK_SLOT_ID slotID, /* ID of token's slot */ -+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ -+ CK_ULONG_PTR pulCount /* gets # of mechs. */ -+ ); - #endif - -- - /* C_GetMechanismInfo obtains information about a particular -- * mechanism possibly supported by a token. -- */ -+ * mechanism possibly supported by a token. */ - CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID, /* ID of the token's slot */ -- CK_MECHANISM_TYPE type, /* type of mechanism */ -- CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ --); -+ CK_SLOT_ID slotID, /* ID of the token's slot */ -+ CK_MECHANISM_TYPE type, /* type of mechanism */ -+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ -+ ); - #endif - -- - /* C_InitToken initializes a token. */ - CK_PKCS11_FUNCTION_INFO(C_InitToken) - #ifdef CK_NEED_ARG_LIST -+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */ - ( -- CK_SLOT_ID slotID, /* ID of the token's slot */ -- CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ -- CK_ULONG ulPinLen, /* length in bytes of the PIN */ -- CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ --); -+ CK_SLOT_ID slotID, /* ID of the token's slot */ -+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ -+ CK_ULONG ulPinLen, /* length in bytes of the PIN */ -+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ -+ ); - #endif - -- - /* C_InitPIN initializes the normal user's PIN. */ - CK_PKCS11_FUNCTION_INFO(C_InitPIN) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ -- CK_ULONG ulPinLen /* length in bytes of the PIN */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ -+ CK_ULONG ulPinLen /* length in bytes of the PIN */ -+ ); - #endif - -- - /* C_SetPIN modifies the PIN of the user who is logged in. */ - CK_PKCS11_FUNCTION_INFO(C_SetPIN) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ -- CK_ULONG ulOldLen, /* length of the old PIN */ -- CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ -- CK_ULONG ulNewLen /* length of the new PIN */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ -+ CK_ULONG ulOldLen, /* length of the old PIN */ -+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ -+ CK_ULONG ulNewLen /* length of the new PIN */ -+ ); - #endif - -- -- - /* Session management */ - - /* C_OpenSession opens a session between an application and a -- * token. -- */ -+ * token. */ - CK_PKCS11_FUNCTION_INFO(C_OpenSession) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID, /* the slot's ID */ -- CK_FLAGS flags, /* from CK_SESSION_INFO */ -- CK_VOID_PTR pApplication, /* passed to callback */ -- CK_NOTIFY Notify, /* callback function */ -- CK_SESSION_HANDLE_PTR phSession /* gets session handle */ --); -+ CK_SLOT_ID slotID, /* the slot's ID */ -+ CK_FLAGS flags, /* from CK_SESSION_INFO */ -+ CK_VOID_PTR pApplication, /* passed to callback */ -+ CK_NOTIFY Notify, /* callback function */ -+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */ -+ ); - #endif - -- - /* C_CloseSession closes a session between an application and a -- * token. -- */ -+ * token. */ - CK_PKCS11_FUNCTION_INFO(C_CloseSession) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession /* the session's handle */ -+ ); - #endif - -- - /* C_CloseAllSessions closes all sessions with a token. */ - CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SLOT_ID slotID /* the token's slot */ --); -+ CK_SLOT_ID slotID /* the token's slot */ -+ ); - #endif - -- - /* C_GetSessionInfo obtains information about the session. */ - CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_SESSION_INFO_PTR pInfo /* receives session info */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_SESSION_INFO_PTR pInfo /* receives session info */ -+ ); - #endif - -- - /* C_GetOperationState obtains the state of the cryptographic operation -- * in a session. -- */ -+ * in a session. */ - CK_PKCS11_FUNCTION_INFO(C_GetOperationState) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pOperationState, /* gets state */ -- CK_ULONG_PTR pulOperationStateLen /* gets state length */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pOperationState, /* gets state */ -+ CK_ULONG_PTR pulOperationStateLen /* gets state length */ -+ ); - #endif - -- - /* C_SetOperationState restores the state of the cryptographic -- * operation in a session. -- */ -+ * operation in a session. */ - CK_PKCS11_FUNCTION_INFO(C_SetOperationState) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pOperationState, /* holds state */ -- CK_ULONG ulOperationStateLen, /* holds state length */ -- CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ -- CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pOperationState, /* holds state */ -+ CK_ULONG ulOperationStateLen, /* holds state length */ -+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ -+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ -+ ); - #endif - -- - /* C_Login logs a user into a token. */ - CK_PKCS11_FUNCTION_INFO(C_Login) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_USER_TYPE userType, /* the user type */ -- CK_UTF8CHAR_PTR pPin, /* the user's PIN */ -- CK_ULONG ulPinLen /* the length of the PIN */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_USER_TYPE userType, /* the user type */ -+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */ -+ CK_ULONG ulPinLen /* the length of the PIN */ -+ ); - #endif - -- - /* C_Logout logs a user out from a token. */ - CK_PKCS11_FUNCTION_INFO(C_Logout) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession /* the session's handle */ -+ ); - #endif - -- -- - /* Object management */ - - /* C_CreateObject creates a new object. */ - CK_PKCS11_FUNCTION_INFO(C_CreateObject) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ -- CK_ULONG ulCount, /* attributes in template */ -- CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ -+ CK_ULONG ulCount, /* attributes in template */ -+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ -+ ); - #endif - -- - /* C_CopyObject copies an object, creating a new object for the -- * copy. -- */ -+ * copy. */ - CK_PKCS11_FUNCTION_INFO(C_CopyObject) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hObject, /* the object's handle */ -- CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ -- CK_ULONG ulCount, /* attributes in template */ -- CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hObject, /* the object's handle */ -+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ -+ CK_ULONG ulCount, /* attributes in template */ -+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ -+ ); - #endif - -- - /* C_DestroyObject destroys an object. */ - CK_PKCS11_FUNCTION_INFO(C_DestroyObject) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hObject /* the object's handle */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hObject /* the object's handle */ -+ ); - #endif - -- - /* C_GetObjectSize gets the size of an object in bytes. */ - CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hObject, /* the object's handle */ -- CK_ULONG_PTR pulSize /* receives size of object */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hObject, /* the object's handle */ -+ CK_ULONG_PTR pulSize /* receives size of object */ -+ ); - #endif - -- - /* C_GetAttributeValue obtains the value of one or more object -- * attributes. -- */ -+ * attributes. */ - CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hObject, /* the object's handle */ -- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ -- CK_ULONG ulCount /* attributes in template */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hObject, /* the object's handle */ -+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ -+ CK_ULONG ulCount /* attributes in template */ -+ ); - #endif - -- - /* C_SetAttributeValue modifies the value of one or more object -- * attributes. -- */ -+ * attributes */ - CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hObject, /* the object's handle */ -- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ -- CK_ULONG ulCount /* attributes in template */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hObject, /* the object's handle */ -+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ -+ CK_ULONG ulCount /* attributes in template */ -+ ); - #endif - -- - /* C_FindObjectsInit initializes a search for token and session -- * objects that match a template. -- */ -+ * objects that match a template. */ - CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ -- CK_ULONG ulCount /* attrs in search template */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ -+ CK_ULONG ulCount /* attrs in search template */ -+ ); - #endif - -- - /* C_FindObjects continues a search for token and session - * objects that match a template, obtaining additional object -- * handles. -- */ -+ * handles. */ - CK_PKCS11_FUNCTION_INFO(C_FindObjects) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ -- CK_ULONG ulMaxObjectCount, /* max handles to get */ -- CK_ULONG_PTR pulObjectCount /* actual # returned */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ -+ CK_ULONG ulMaxObjectCount, /* max handles to get */ -+ CK_ULONG_PTR pulObjectCount /* actual # returned */ -+ ); - #endif - -- - /* C_FindObjectsFinal finishes a search for token and session -- * objects. -- */ -+ * objects. */ - CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession /* the session's handle */ -+ ); - #endif - -- -- - /* Encryption and decryption */ - - /* C_EncryptInit initializes an encryption operation. */ - CK_PKCS11_FUNCTION_INFO(C_EncryptInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of encryption key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ -+ CK_OBJECT_HANDLE hKey /* handle of encryption key */ -+ ); - #endif - -- - /* C_Encrypt encrypts single-part data. */ - CK_PKCS11_FUNCTION_INFO(C_Encrypt) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pData, /* the plaintext data */ -- CK_ULONG ulDataLen, /* bytes of plaintext */ -- CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ -- CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pData, /* the plaintext data */ -+ CK_ULONG ulDataLen, /* bytes of plaintext */ -+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ -+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ -+ ); - #endif - -- - /* C_EncryptUpdate continues a multiple-part encryption -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pPart, /* the plaintext data */ -- CK_ULONG ulPartLen, /* plaintext data len */ -- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pPart, /* the plaintext data */ -+ CK_ULONG ulPartLen, /* plaintext data len */ -+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ -+ ); - #endif - -- - /* C_EncryptFinal finishes a multiple-part encryption -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session handle */ -- CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ -- CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ --); -+ CK_SESSION_HANDLE hSession, /* session handle */ -+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ -+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ -+ ); - #endif - -- - /* C_DecryptInit initializes a decryption operation. */ - CK_PKCS11_FUNCTION_INFO(C_DecryptInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of decryption key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ -+ CK_OBJECT_HANDLE hKey /* handle of decryption key */ -+ ); - #endif - -- - /* C_Decrypt decrypts encrypted data in a single part. */ - CK_PKCS11_FUNCTION_INFO(C_Decrypt) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pEncryptedData, /* ciphertext */ -- CK_ULONG ulEncryptedDataLen, /* ciphertext length */ -- CK_BYTE_PTR pData, /* gets plaintext */ -- CK_ULONG_PTR pulDataLen /* gets p-text size */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pEncryptedData, /* ciphertext */ -+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */ -+ CK_BYTE_PTR pData, /* gets plaintext */ -+ CK_ULONG_PTR pulDataLen /* gets p-text size */ -+ ); - #endif - -- - /* C_DecryptUpdate continues a multiple-part decryption -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pEncryptedPart, /* encrypted data */ -- CK_ULONG ulEncryptedPartLen, /* input length */ -- CK_BYTE_PTR pPart, /* gets plaintext */ -- CK_ULONG_PTR pulPartLen /* p-text size */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */ -+ CK_ULONG ulEncryptedPartLen, /* input length */ -+ CK_BYTE_PTR pPart, /* gets plaintext */ -+ CK_ULONG_PTR pulPartLen /* p-text size */ -+ ); - #endif - -- - /* C_DecryptFinal finishes a multiple-part decryption -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pLastPart, /* gets plaintext */ -- CK_ULONG_PTR pulLastPartLen /* p-text size */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pLastPart, /* gets plaintext */ -+ CK_ULONG_PTR pulLastPartLen /* p-text size */ -+ ); - #endif - -- -- - /* Message digesting */ - - /* C_DigestInit initializes a message-digesting operation. */ - CK_PKCS11_FUNCTION_INFO(C_DigestInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ -+ ); - #endif - -- - /* C_Digest digests data in a single part. */ - CK_PKCS11_FUNCTION_INFO(C_Digest) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pData, /* data to be digested */ -- CK_ULONG ulDataLen, /* bytes of data to digest */ -- CK_BYTE_PTR pDigest, /* gets the message digest */ -- CK_ULONG_PTR pulDigestLen /* gets digest length */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pData, /* data to be digested */ -+ CK_ULONG ulDataLen, /* bytes of data to digest */ -+ CK_BYTE_PTR pDigest, /* gets the message digest */ -+ CK_ULONG_PTR pulDigestLen /* gets digest length */ -+ ); - #endif - -- - /* C_DigestUpdate continues a multiple-part message-digesting -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pPart, /* data to be digested */ -- CK_ULONG ulPartLen /* bytes of data to be digested */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pPart, /* data to be digested */ -+ CK_ULONG ulPartLen /* bytes of data to be digested */ -+ ); - #endif - -- - /* C_DigestKey continues a multi-part message-digesting - * operation, by digesting the value of a secret key as part of -- * the data already digested. -- */ -+ * the data already digested. */ - CK_PKCS11_FUNCTION_INFO(C_DigestKey) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_OBJECT_HANDLE hKey /* secret key to digest */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_OBJECT_HANDLE hKey /* secret key to digest */ -+ ); - #endif - -- - /* C_DigestFinal finishes a multiple-part message-digesting -- * operation. -- */ -+ * operation. */ - CK_PKCS11_FUNCTION_INFO(C_DigestFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pDigest, /* gets the message digest */ -- CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pDigest, /* gets the message digest */ -+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ -+ ); - #endif - -- -- - /* Signing and MACing */ - - /* C_SignInit initializes a signature (private key encryption) - * operation, where the signature is (will be) an appendix to - * the data, and plaintext cannot be recovered from the -- * signature. -- */ -+ *signature. */ - CK_PKCS11_FUNCTION_INFO(C_SignInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of signature key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ -+ CK_OBJECT_HANDLE hKey /* handle of signature key */ -+ ); - #endif - -- - /* C_Sign signs (encrypts with private key) data in a single - * part, where the signature is (will be) an appendix to the -- * data, and plaintext cannot be recovered from the signature. -- */ -+ * data, and plaintext cannot be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_Sign) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pData, /* the data to sign */ -- CK_ULONG ulDataLen, /* count of bytes to sign */ -- CK_BYTE_PTR pSignature, /* gets the signature */ -- CK_ULONG_PTR pulSignatureLen /* gets signature length */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pData, /* the data to sign */ -+ CK_ULONG ulDataLen, /* count of bytes to sign */ -+ CK_BYTE_PTR pSignature, /* gets the signature */ -+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ -+ ); - #endif - -- - /* C_SignUpdate continues a multiple-part signature operation, - * where the signature is (will be) an appendix to the data, -- * and plaintext cannot be recovered from the signature. -- */ -+ * and plaintext cannot be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_SignUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pPart, /* the data to sign */ -- CK_ULONG ulPartLen /* count of bytes to sign */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pPart, /* the data to sign */ -+ CK_ULONG ulPartLen /* count of bytes to sign */ -+ ); - #endif - -- - /* C_SignFinal finishes a multiple-part signature operation, -- * returning the signature. -- */ -+ * returning the signature. */ - CK_PKCS11_FUNCTION_INFO(C_SignFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pSignature, /* gets the signature */ -- CK_ULONG_PTR pulSignatureLen /* gets signature length */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pSignature, /* gets the signature */ -+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ -+ ); - #endif - -- - /* C_SignRecoverInit initializes a signature operation, where -- * the data can be recovered from the signature. -- */ -+ * the data can be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of the signature key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ -+ CK_OBJECT_HANDLE hKey /* handle of the signature key */ -+ ); - #endif - -- - /* C_SignRecover signs data in a single operation, where the -- * data can be recovered from the signature. -- */ -+ * data can be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_SignRecover) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pData, /* the data to sign */ -- CK_ULONG ulDataLen, /* count of bytes to sign */ -- CK_BYTE_PTR pSignature, /* gets the signature */ -- CK_ULONG_PTR pulSignatureLen /* gets signature length */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pData, /* the data to sign */ -+ CK_ULONG ulDataLen, /* count of bytes to sign */ -+ CK_BYTE_PTR pSignature, /* gets the signature */ -+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ -+ ); - #endif - -- -- - /* Verifying signatures and MACs */ - - /* C_VerifyInit initializes a verification operation, where the - * signature is an appendix to the data, and plaintext cannot -- * cannot be recovered from the signature (e.g. DSA). -- */ -+ * cannot be recovered from the signature (e.g. DSA). */ - CK_PKCS11_FUNCTION_INFO(C_VerifyInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ -- CK_OBJECT_HANDLE hKey /* verification key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ -+ CK_OBJECT_HANDLE hKey /* verification key */ -+ ); - #endif - -- - /* C_Verify verifies a signature in a single-part operation, - * where the signature is an appendix to the data, and plaintext -- * cannot be recovered from the signature. -- */ -+ * cannot be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_Verify) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pData, /* signed data */ -- CK_ULONG ulDataLen, /* length of signed data */ -- CK_BYTE_PTR pSignature, /* signature */ -- CK_ULONG ulSignatureLen /* signature length*/ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pData, /* signed data */ -+ CK_ULONG ulDataLen, /* length of signed data */ -+ CK_BYTE_PTR pSignature, /* signature */ -+ CK_ULONG ulSignatureLen /* signature length*/ -+ ); - #endif - -- - /* C_VerifyUpdate continues a multiple-part verification - * operation, where the signature is an appendix to the data, -- * and plaintext cannot be recovered from the signature. -- */ -+ * and plaintext cannot be recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pPart, /* signed data */ -- CK_ULONG ulPartLen /* length of signed data */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pPart, /* signed data */ -+ CK_ULONG ulPartLen /* length of signed data */ -+ ); - #endif - -- - /* C_VerifyFinal finishes a multiple-part verification -- * operation, checking the signature. -- */ -+ * operation, checking the signature. */ - CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pSignature, /* signature to verify */ -- CK_ULONG ulSignatureLen /* signature length */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pSignature, /* signature to verify */ -+ CK_ULONG ulSignatureLen /* signature length */ -+ ); - #endif - -- - /* C_VerifyRecoverInit initializes a signature verification -- * operation, where the data is recovered from the signature. -- */ -+ * operation, where the data is recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ -- CK_OBJECT_HANDLE hKey /* verification key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ -+ CK_OBJECT_HANDLE hKey /* verification key */ -+ ); - #endif - -- - /* C_VerifyRecover verifies a signature in a single-part -- * operation, where the data is recovered from the signature. -- */ -+ * operation, where the data is recovered from the signature. */ - CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pSignature, /* signature to verify */ -- CK_ULONG ulSignatureLen, /* signature length */ -- CK_BYTE_PTR pData, /* gets signed data */ -- CK_ULONG_PTR pulDataLen /* gets signed data len */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pSignature, /* signature to verify */ -+ CK_ULONG ulSignatureLen, /* signature length */ -+ CK_BYTE_PTR pData, /* gets signed data */ -+ CK_ULONG_PTR pulDataLen /* gets signed data len */ -+ ); - #endif - -- -- - /* Dual-function cryptographic operations */ - - /* C_DigestEncryptUpdate continues a multiple-part digesting -- * and encryption operation. -- */ -+ * and encryption operation. */ - CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pPart, /* the plaintext data */ -- CK_ULONG ulPartLen, /* plaintext length */ -- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pPart, /* the plaintext data */ -+ CK_ULONG ulPartLen, /* plaintext length */ -+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -+ ); - #endif - -- - /* C_DecryptDigestUpdate continues a multiple-part decryption and -- * digesting operation. -- */ -+ * digesting operation. */ - CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pEncryptedPart, /* ciphertext */ -- CK_ULONG ulEncryptedPartLen, /* ciphertext length */ -- CK_BYTE_PTR pPart, /* gets plaintext */ -- CK_ULONG_PTR pulPartLen /* gets plaintext len */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ -+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ -+ CK_BYTE_PTR pPart, /* gets plaintext */ -+ CK_ULONG_PTR pulPartLen /* gets plaintext len */ -+ ); - #endif - -- - /* C_SignEncryptUpdate continues a multiple-part signing and -- * encryption operation. -- */ -+ * encryption operation. */ - CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pPart, /* the plaintext data */ -- CK_ULONG ulPartLen, /* plaintext length */ -- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pPart, /* the plaintext data */ -+ CK_ULONG ulPartLen, /* plaintext length */ -+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ -+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -+ ); - #endif - -- - /* C_DecryptVerifyUpdate continues a multiple-part decryption and -- * verify operation. -- */ -+ * verify operation. */ - CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_BYTE_PTR pEncryptedPart, /* ciphertext */ -- CK_ULONG ulEncryptedPartLen, /* ciphertext length */ -- CK_BYTE_PTR pPart, /* gets plaintext */ -- CK_ULONG_PTR pulPartLen /* gets p-text length */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ -+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ -+ CK_BYTE_PTR pPart, /* gets plaintext */ -+ CK_ULONG_PTR pulPartLen /* gets p-text length */ -+ ); - #endif - -- -- - /* Key management */ - - /* C_GenerateKey generates a secret key, creating a new key -- * object. -- */ -+ * object. */ - CK_PKCS11_FUNCTION_INFO(C_GenerateKey) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* key generation mech. */ -- CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ -- CK_ULONG ulCount, /* # of attrs in template */ -- CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */ -+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ -+ CK_ULONG ulCount, /* # of attrs in template */ -+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ -+ ); - #endif - -- - /* C_GenerateKeyPair generates a public-key/private-key pair, -- * creating new key objects. -- */ -+ * creating new key objects. */ - CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session handle */ -- CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ -- CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ -- CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ -- CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ -- CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ -- CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ -- CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ --); -+ CK_SESSION_HANDLE hSession, /* session handle */ -+ CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ -+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ -+ CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ -+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ -+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ -+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ -+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ -+ ); - #endif - -- - /* C_WrapKey wraps (i.e., encrypts) a key. */ - CK_PKCS11_FUNCTION_INFO(C_WrapKey) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ -- CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ -- CK_OBJECT_HANDLE hKey, /* key to be wrapped */ -- CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ -- CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ -+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ -+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */ -+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ -+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ -+ ); - #endif - -- - /* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new -- * key object. -- */ -+ * key object. */ - CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ -- CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ -- CK_BYTE_PTR pWrappedKey, /* the wrapped key */ -- CK_ULONG ulWrappedKeyLen, /* wrapped key len */ -- CK_ATTRIBUTE_PTR pTemplate, /* new key template */ -- CK_ULONG ulAttributeCount, /* template length */ -- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ -+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ -+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */ -+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */ -+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ -+ CK_ULONG ulAttributeCount, /* template length */ -+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -+ ); - #endif - -- - /* C_DeriveKey derives a key from a base key, creating a new key -- * object. -- */ -+ * object. */ - CK_PKCS11_FUNCTION_INFO(C_DeriveKey) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* session's handle */ -- CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ -- CK_OBJECT_HANDLE hBaseKey, /* base key */ -- CK_ATTRIBUTE_PTR pTemplate, /* new key template */ -- CK_ULONG ulAttributeCount, /* template length */ -- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ --); -+ CK_SESSION_HANDLE hSession, /* session's handle */ -+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ -+ CK_OBJECT_HANDLE hBaseKey, /* base key */ -+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ -+ CK_ULONG ulAttributeCount, /* template length */ -+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -+ ); - #endif - -- -- - /* Random number generation */ - - /* C_SeedRandom mixes additional seed material into the token's -- * random number generator. -- */ -+ * random number generator. */ - CK_PKCS11_FUNCTION_INFO(C_SeedRandom) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR pSeed, /* the seed material */ -- CK_ULONG ulSeedLen /* length of seed material */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR pSeed, /* the seed material */ -+ CK_ULONG ulSeedLen /* length of seed material */ -+ ); - #endif - -- - /* C_GenerateRandom generates random data. */ - CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_BYTE_PTR RandomData, /* receives the random data */ -- CK_ULONG ulRandomLen /* # of bytes to generate */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_BYTE_PTR RandomData, /* receives the random data */ -+ CK_ULONG ulRandomLen /* # of bytes to generate */ -+ ); - #endif - -- -- - /* Parallel function management */ - - /* C_GetFunctionStatus is a legacy function; it obtains an - * updated status of a function running in parallel with an -- * application. -- */ -+ * application. */ - CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession /* the session's handle */ -+ ); - #endif - -- - /* C_CancelFunction is a legacy function; it cancels a function -- * running in parallel. -- */ -+ * running in parallel. */ - CK_PKCS11_FUNCTION_INFO(C_CancelFunction) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession /* the session's handle */ -+ ); - #endif - -+/* Functions added in for PKCS #11 Version 2.01 or later */ - - /* C_WaitForSlotEvent waits for a slot event (token insertion, -- * removal, etc.) to occur. -- */ -+ * removal, etc.) to occur. */ - CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) - #ifdef CK_NEED_ARG_LIST - ( -- CK_FLAGS flags, /* blocking/nonblocking flag */ -- CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ -- CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ --); -+ CK_FLAGS flags, /* blocking/nonblocking flag */ -+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ -+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ -+ ); - #endif - --#ifndef CK_PKCS11_2_0_ONLY --/* C_GetInterfaceList returns all the interfaces supported by the module*/ -+#if defined(CK_PKCS11_3_0) && !defined(CK_PKCS11_2_0_ONLY) - CK_PKCS11_FUNCTION_INFO(C_GetInterfaceList) - #ifdef CK_NEED_ARG_LIST - ( -- CK_INTERFACE_PTR pInterfacesList, /* returned interfaces */ -- CK_ULONG_PTR pulCount /* number of interfaces returned */ --); -+ CK_INTERFACE_PTR interfaces, -+ CK_ULONG_PTR pulCount); - #endif - --/* C_GetInterface returns a specific interface from the module. */ - CK_PKCS11_FUNCTION_INFO(C_GetInterface) - #ifdef CK_NEED_ARG_LIST - ( -- CK_UTF8CHAR_PTR pInterfaceName, /* name of the interface */ -- CK_VERSION_PTR pVersion, /* version of the interface */ -- CK_INTERFACE_PTR_PTR ppInterface, /* returned interface */ -- CK_FLAGS flags /* flags controlling the semantics -- * of the interface */ --); -+ CK_UTF8CHAR_PTR pInterfaceName, -+ CK_VERSION_PTR pVersion, -+ CK_INTERFACE_PTR_PTR ppInterface, -+ CK_FLAGS flags); - #endif - - CK_PKCS11_FUNCTION_INFO(C_LoginUser) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_USER_TYPE userType, /* the user type */ -- CK_UTF8CHAR_PTR pPin, /* the user's PIN */ -- CK_ULONG ulPinLen, /* the length of the PIN */ -- CK_UTF8CHAR_PTR pUsername, /* the user's name */ -- CK_ULONG ulUsernameLen /*the length of the user's name */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_USER_TYPE userType, -+ CK_CHAR_PTR pPin, -+ CK_ULONG ulPinLen, -+ CK_UTF8CHAR_PTR pUsername, -+ CK_ULONG ulUsernameLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_SessionCancel) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_FLAGS flags /* flags control which sessions are cancelled */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_FLAGS flags); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageEncryptInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of encryption key */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey); - #endif - - CK_PKCS11_FUNCTION_INFO(C_EncryptMessage) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ -- CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ -- CK_BYTE_PTR pPlaintext, /* plain text */ -- CK_ULONG ulPlaintextLen, /* plain text length */ -- CK_BYTE_PTR pCiphertext, /* gets cipher text */ -- CK_ULONG_PTR pulCiphertextLen /* gets cipher text length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pAssociatedData, -+ CK_ULONG ulAssociatedDataLen, -+ CK_BYTE_PTR pPlaintext, -+ CK_ULONG ulPlaintextLen, -+ CK_BYTE_PTR pCiphertext, -+ CK_ULONG_PTR pulCiphertextLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_EncryptMessageBegin) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ -- CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pAssociatedData, -+ CK_ULONG ulAssociatedDataLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_EncryptMessageNext) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pPlaintextPart, /* plain text */ -- CK_ULONG ulPlaintextPartLen, /* plain text length */ -- CK_BYTE_PTR pCiphertextPart, /* gets cipher text */ -- CK_ULONG_PTR pulCiphertextPartLen, /* gets cipher text length */ -- CK_FLAGS flags /* multi mode flag */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pPlaintextPart, -+ CK_ULONG ulPlaintextPartLen, -+ CK_BYTE_PTR pCiphertextPart, -+ CK_ULONG_PTR pulCiphertextPartLen, -+ CK_FLAGS flags); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageEncryptFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageDecryptInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of decryption key */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey); - #endif - - CK_PKCS11_FUNCTION_INFO(C_DecryptMessage) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ -- CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ -- CK_BYTE_PTR pCiphertext, /* cipher text */ -- CK_ULONG ulCiphertextLen, /* cipher text length */ -- CK_BYTE_PTR pPlaintext, /* gets plain text */ -- CK_ULONG_PTR pulPlaintextLen /* gets plain text length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pAssociatedData, -+ CK_ULONG ulAssociatedDataLen, -+ CK_BYTE_PTR pCiphertext, -+ CK_ULONG ulCiphertextLen, -+ CK_BYTE_PTR pPlaintext, -+ CK_ULONG_PTR pulPlaintextLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_DecryptMessageBegin) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ -- CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pAssociatedData, -+ CK_ULONG ulAssociatedDataLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_DecryptMessageNext) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pCiphertextPart, /* cipher text */ -- CK_ULONG ulCiphertextPartLen, /* cipher text length */ -- CK_BYTE_PTR pPlaintextPart, /* gets plain text */ -- CK_ULONG_PTR pulPlaintextPartLen, /* gets plain text length */ -- CK_FLAGS flags /* multi mode flag */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pCiphertextPart, -+ CK_ULONG ulCiphertextPartLen, -+ CK_BYTE_PTR pPlaintextPart, -+ CK_ULONG_PTR pulPlaintextPartLen, -+ CK_FLAGS flags); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageDecryptFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageSignInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of signing key */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey); - #endif - - CK_PKCS11_FUNCTION_INFO(C_SignMessage) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pData, /* data to sign */ -- CK_ULONG ulDataLen, /* data to sign length */ -- CK_BYTE_PTR pSignature, /* gets signature */ -- CK_ULONG_PTR pulSignatureLen /* gets signature length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ -+ CK_BYTE_PTR pSignature, -+ CK_ULONG_PTR pulSignatureLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_SignMessageBegin) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen /* length of message specific parameter */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_SignMessageNext) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pData, /* data to sign */ -- CK_ULONG ulDataLen, /* data to sign length */ -- CK_BYTE_PTR pSignature, /* gets signature */ -- CK_ULONG_PTR pulSignatureLen /* gets signature length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG_PTR pulSignatureLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageSignFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageVerifyInit) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ -- CK_OBJECT_HANDLE hKey /* handle of signing key */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_MECHANISM_PTR pMechanism, -+ CK_OBJECT_HANDLE hKey); - #endif - - CK_PKCS11_FUNCTION_INFO(C_VerifyMessage) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pData, /* data to sign */ -- CK_ULONG ulDataLen, /* data to sign length */ -- CK_BYTE_PTR pSignature, /* signature */ -- CK_ULONG ulSignatureLen /* signature length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG ulSignatureLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_VerifyMessageBegin) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen /* length of message specific parameter */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_VerifyMessageNext) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_VOID_PTR pParameter, /* message specific parameter */ -- CK_ULONG ulParameterLen, /* length of message specific parameter */ -- CK_BYTE_PTR pData, /* data to sign */ -- CK_ULONG ulDataLen, /* data to sign length */ -- CK_BYTE_PTR pSignature, /* signature */ -- CK_ULONG ulSignatureLen /* signature length */ --); -+ CK_SESSION_HANDLE hSession, -+ CK_VOID_PTR pParameter, -+ CK_ULONG ulParameterLen, -+ CK_BYTE_PTR pData, -+ CK_ULONG ulDataLen, -+ CK_BYTE_PTR pSignature, -+ CK_ULONG ulSignatureLen); - #endif - - CK_PKCS11_FUNCTION_INFO(C_MessageVerifyFinal) - #ifdef CK_NEED_ARG_LIST - ( -- CK_SESSION_HANDLE hSession /* the session's handle */ --); -+ CK_SESSION_HANDLE hSession); - #endif - --#endif /* CK_PKCS11_2_0_ONLY */ -- -+#endif ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11n.h -@@ -0,0 +1,672 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#ifndef _PKCS11N_H_ -+#define _PKCS11N_H_ -+ -+/* -+ * pkcs11n.h -+ * -+ * This file contains the NSS-specific type definitions for Cryptoki -+ * (PKCS#11). -+ */ -+ -+/* -+ * NSSCK_VENDOR_NSS -+ * -+ * Cryptoki reserves the high half of all the number spaces for -+ * vendor-defined use. I'd like to keep all of our NSS- -+ * specific values together, but not in the oh-so-obvious -+ * 0x80000001, 0x80000002, etc. area. So I've picked an offset, -+ * and constructed values for the beginnings of our spaces. -+ * -+ * Note that some "historical" Netscape values don't fall within -+ * this range. -+ */ -+#define NSSCK_VENDOR_NSS 0x4E534350 /* NSCP */ -+ -+/* -+ * NSS-defined object classes -+ * -+ */ -+#define CKO_NSS (CKO_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+#define CKO_NSS_CRL (CKO_NSS + 1) -+#define CKO_NSS_SMIME (CKO_NSS + 2) -+#define CKO_NSS_TRUST (CKO_NSS + 3) -+#define CKO_NSS_BUILTIN_ROOT_LIST (CKO_NSS + 4) -+#define CKO_NSS_NEWSLOT (CKO_NSS + 5) -+#define CKO_NSS_DELSLOT (CKO_NSS + 6) -+ -+/* -+ * NSS-defined key types -+ * -+ */ -+#define CKK_NSS (CKK_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+#define CKK_NSS_PKCS8 (CKK_NSS + 1) -+ -+#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2) -+#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3) -+ -+#define CKK_NSS_CHACHA20 (CKK_NSS + 4) -+ -+/* -+ * NSS-defined certificate types -+ * -+ */ -+#define CKC_NSS (CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+/* FAKE PKCS #11 defines */ -+#define CKA_DIGEST 0x81000000L -+#define CKA_NSS_MESSAGE 0x82000000L -+#define CKA_NSS_MESSAGE_MASK 0xff000000L -+#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */ -+ -+/* -+ * NSS-defined object attributes -+ * -+ */ -+#define CKA_NSS (CKA_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+#define CKA_NSS_URL (CKA_NSS + 1) -+#define CKA_NSS_EMAIL (CKA_NSS + 2) -+#define CKA_NSS_SMIME_INFO (CKA_NSS + 3) -+#define CKA_NSS_SMIME_TIMESTAMP (CKA_NSS + 4) -+#define CKA_NSS_PKCS8_SALT (CKA_NSS + 5) -+#define CKA_NSS_PASSWORD_CHECK (CKA_NSS + 6) -+#define CKA_NSS_EXPIRES (CKA_NSS + 7) -+#define CKA_NSS_KRL (CKA_NSS + 8) -+ -+#define CKA_NSS_PQG_COUNTER (CKA_NSS + 20) -+#define CKA_NSS_PQG_SEED (CKA_NSS + 21) -+#define CKA_NSS_PQG_H (CKA_NSS + 22) -+#define CKA_NSS_PQG_SEED_BITS (CKA_NSS + 23) -+#define CKA_NSS_MODULE_SPEC (CKA_NSS + 24) -+#define CKA_NSS_OVERRIDE_EXTENSIONS (CKA_NSS + 25) -+ -+#define CKA_NSS_JPAKE_SIGNERID (CKA_NSS + 26) -+#define CKA_NSS_JPAKE_PEERID (CKA_NSS + 27) -+#define CKA_NSS_JPAKE_GX1 (CKA_NSS + 28) -+#define CKA_NSS_JPAKE_GX2 (CKA_NSS + 29) -+#define CKA_NSS_JPAKE_GX3 (CKA_NSS + 30) -+#define CKA_NSS_JPAKE_GX4 (CKA_NSS + 31) -+#define CKA_NSS_JPAKE_X2 (CKA_NSS + 32) -+#define CKA_NSS_JPAKE_X2S (CKA_NSS + 33) -+ -+#define CKA_NSS_MOZILLA_CA_POLICY (CKA_NSS + 34) -+#define CKA_NSS_SERVER_DISTRUST_AFTER (CKA_NSS + 35) -+#define CKA_NSS_EMAIL_DISTRUST_AFTER (CKA_NSS + 36) -+ -+/* -+ * Trust attributes: -+ * -+ * If trust goes standard, these probably will too. So I'll -+ * put them all in one place. -+ */ -+ -+#define CKA_TRUST (CKA_NSS + 0x2000) -+ -+/* "Usage" key information */ -+#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1) -+#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2) -+#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3) -+#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4) -+#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5) -+#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6) -+#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7) -+ -+/* "Purpose" trust information */ -+#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8) -+#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9) -+#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10) -+#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11) -+#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12) -+#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13) -+#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14) -+#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15) -+#define CKA_TRUST_STEP_UP_APPROVED (CKA_TRUST + 16) -+ -+#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100) -+#define CKA_CERT_MD5_HASH (CKA_TRUST + 101) -+ -+/* NSS trust stuff */ -+ -+/* HISTORICAL: define used to pass in the database key for DSA private keys */ -+#define CKA_NSS_DB 0xD5A0DB00L -+#define CKA_NSS_TRUST 0x80000001L -+ -+/* FAKE PKCS #11 defines */ -+#define CKM_FAKE_RANDOM 0x80000efeUL -+#define CKM_INVALID_MECHANISM 0xffffffffUL -+#define CKT_INVALID_TYPE 0xffffffffUL -+ -+/* -+ * NSS-defined crypto mechanisms -+ * -+ */ -+#define CKM_NSS (CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+#define CKM_NSS_AES_KEY_WRAP (CKM_NSS + 1) -+#define CKM_NSS_AES_KEY_WRAP_PAD (CKM_NSS + 2) -+ -+/* HKDF key derivation mechanisms. See CK_NSS_HKDFParams for documentation. */ -+#define CKM_NSS_HKDF_SHA1 (CKM_NSS + 3) -+#define CKM_NSS_HKDF_SHA256 (CKM_NSS + 4) -+#define CKM_NSS_HKDF_SHA384 (CKM_NSS + 5) -+#define CKM_NSS_HKDF_SHA512 (CKM_NSS + 6) -+ -+/* J-PAKE round 1 key generation mechanisms. -+ * -+ * Required template attributes: CKA_PRIME, CKA_SUBPRIME, CKA_BASE, -+ * CKA_NSS_JPAKE_SIGNERID -+ * Output key type: CKK_NSS_JPAKE_ROUND1 -+ * Output key class: CKO_PRIVATE_KEY -+ * Parameter type: CK_NSS_JPAKERound1Params -+ * -+ */ -+#define CKM_NSS_JPAKE_ROUND1_SHA1 (CKM_NSS + 7) -+#define CKM_NSS_JPAKE_ROUND1_SHA256 (CKM_NSS + 8) -+#define CKM_NSS_JPAKE_ROUND1_SHA384 (CKM_NSS + 9) -+#define CKM_NSS_JPAKE_ROUND1_SHA512 (CKM_NSS + 10) -+ -+/* J-PAKE round 2 key derivation mechanisms. -+ * -+ * Required template attributes: CKA_NSS_JPAKE_PEERID -+ * Input key type: CKK_NSS_JPAKE_ROUND1 -+ * Output key type: CKK_NSS_JPAKE_ROUND2 -+ * Output key class: CKO_PRIVATE_KEY -+ * Parameter type: CK_NSS_JPAKERound2Params -+ */ -+#define CKM_NSS_JPAKE_ROUND2_SHA1 (CKM_NSS + 11) -+#define CKM_NSS_JPAKE_ROUND2_SHA256 (CKM_NSS + 12) -+#define CKM_NSS_JPAKE_ROUND2_SHA384 (CKM_NSS + 13) -+#define CKM_NSS_JPAKE_ROUND2_SHA512 (CKM_NSS + 14) -+ -+/* J-PAKE final key material derivation mechanisms -+ * -+ * Input key type: CKK_NSS_JPAKE_ROUND2 -+ * Output key type: CKK_GENERIC_SECRET -+ * Output key class: CKO_SECRET_KEY -+ * Parameter type: CK_NSS_JPAKEFinalParams -+ * -+ * You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material -+ * to get a key with uniformly distributed bits. -+ */ -+#define CKM_NSS_JPAKE_FINAL_SHA1 (CKM_NSS + 15) -+#define CKM_NSS_JPAKE_FINAL_SHA256 (CKM_NSS + 16) -+#define CKM_NSS_JPAKE_FINAL_SHA384 (CKM_NSS + 17) -+#define CKM_NSS_JPAKE_FINAL_SHA512 (CKM_NSS + 18) -+ -+/* Constant-time MAC mechanisms: -+ * -+ * These operations verify a padded, MAC-then-encrypt block of data in -+ * constant-time. Because of the order of operations, the padding bytes are not -+ * protected by the MAC. However, disclosing the value of the padding bytes -+ * gives an attacker the ability to decrypt ciphertexts. Such disclosure can be -+ * as subtle as taking slightly less time to perform the MAC when the padding -+ * is one byte longer. See https://www.isg.rhul.ac.uk/tls/ -+ * -+ * CKM_NSS_HMAC_CONSTANT_TIME: performs an HMAC authentication. -+ * CKM_NSS_SSL3_MAC_CONSTANT_TIME: performs an authentication with SSLv3 MAC. -+ * -+ * Parameter type: CK_NSS_MAC_CONSTANT_TIME_PARAMS -+ */ -+#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19) -+#define CKM_NSS_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20) -+ -+/* TLS 1.2 mechanisms */ -+#define CKM_NSS_TLS_PRF_GENERAL_SHA256 (CKM_NSS + 21) -+#define CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 (CKM_NSS + 22) -+#define CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 (CKM_NSS + 23) -+#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24) -+ -+/* TLS extended master secret derivation */ -+#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25) -+#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26) -+ -+#define CKM_NSS_CHACHA20_KEY_GEN (CKM_NSS + 27) -+#define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 28) -+ -+/* Additional PKCS #12 PBE algorithms defined in v1.1 */ -+#define CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN (CKM_NSS + 29) -+#define CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN (CKM_NSS + 30) -+#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKM_NSS + 31) -+#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKM_NSS + 32) -+ -+#define CKM_NSS_CHACHA20_CTR (CKM_NSS + 33) -+ -+/* IKE mechanism (to be proposed to PKCS #11 */ -+#define CKM_NSS_IKE_PRF_PLUS_DERIVE (CKM_NSS + 34) -+#define CKM_NSS_IKE_PRF_DERIVE (CKM_NSS + 35) -+#define CKM_NSS_IKE1_PRF_DERIVE (CKM_NSS + 36) -+#define CKM_NSS_IKE1_APP_B_PRF_DERIVE (CKM_NSS + 37) -+ -+#define CKM_NSS_PUB_FROM_PRIV (CKM_NSS + 40) -+ -+/* SP800-108 NSS mechanism with support for data object derivation */ -+#define CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA (CKM_NSS + 42) -+#define CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA (CKM_NSS + 43) -+#define CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA (CKM_NSS + 44) -+ -+/* -+ * HISTORICAL: -+ * Do not attempt to use these. They are only used by NSS's internal -+ * PKCS #11 interface. Most of these are place holders for other mechanism -+ * and will change in the future. -+ */ -+#define CKM_NSS_PBE_SHA1_DES_CBC 0x80000002UL -+#define CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC 0x80000003UL -+#define CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC 0x80000004UL -+#define CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC 0x80000005UL -+#define CKM_NSS_PBE_SHA1_40_BIT_RC4 0x80000006UL -+#define CKM_NSS_PBE_SHA1_128_BIT_RC4 0x80000007UL -+#define CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC 0x80000008UL -+#define CKM_NSS_PBE_SHA1_HMAC_KEY_GEN 0x80000009UL -+#define CKM_NSS_PBE_MD5_HMAC_KEY_GEN 0x8000000aUL -+#define CKM_NSS_PBE_MD2_HMAC_KEY_GEN 0x8000000bUL -+ -+#define CKM_TLS_PRF_GENERAL 0x80000373UL -+ -+typedef struct CK_NSS_JPAKEPublicValue { -+ CK_BYTE *pGX; -+ CK_ULONG ulGXLen; -+ CK_BYTE *pGV; -+ CK_ULONG ulGVLen; -+ CK_BYTE *pR; -+ CK_ULONG ulRLen; -+} CK_NSS_JPAKEPublicValue; -+ -+typedef struct CK_NSS_JPAKERound1Params { -+ CK_NSS_JPAKEPublicValue gx1; /* out */ -+ CK_NSS_JPAKEPublicValue gx2; /* out */ -+} CK_NSS_JPAKERound1Params; -+ -+typedef struct CK_NSS_JPAKERound2Params { -+ CK_BYTE *pSharedKey; /* in */ -+ CK_ULONG ulSharedKeyLen; /* in */ -+ CK_NSS_JPAKEPublicValue gx3; /* in */ -+ CK_NSS_JPAKEPublicValue gx4; /* in */ -+ CK_NSS_JPAKEPublicValue A; /* out */ -+} CK_NSS_JPAKERound2Params; -+ -+typedef struct CK_NSS_JPAKEFinalParams { -+ CK_NSS_JPAKEPublicValue B; /* in */ -+} CK_NSS_JPAKEFinalParams; -+ -+/* macAlg: the MAC algorithm to use. This determines the hash function used in -+ * the HMAC/SSLv3 MAC calculations. -+ * ulBodyTotalLen: the total length of the data, including padding bytes and -+ * padding length. -+ * pHeader: points to a block of data that contains additional data to -+ * authenticate. For TLS this includes the sequence number etc. For SSLv3, -+ * this also includes the initial padding bytes. -+ * -+ * NOTE: the softoken's implementation of CKM_NSS_HMAC_CONSTANT_TIME and -+ * CKM_NSS_SSL3_MAC_CONSTANT_TIME requires that the sum of ulBodyTotalLen -+ * and ulHeaderLen be much smaller than 2^32 / 8 bytes because it uses an -+ * unsigned int variable to represent the length in bits. This should not -+ * be a problem because the SSL/TLS protocol limits the size of an SSL -+ * record to something considerably less than 2^32 bytes. -+ */ -+typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS { -+ CK_MECHANISM_TYPE macAlg; /* in */ -+ CK_ULONG ulBodyTotalLen; /* in */ -+ CK_BYTE *pHeader; /* in */ -+ CK_ULONG ulHeaderLen; /* in */ -+} CK_NSS_MAC_CONSTANT_TIME_PARAMS; -+ -+typedef struct CK_NSS_AEAD_PARAMS { -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceLen; -+ CK_BYTE_PTR pAAD; -+ CK_ULONG ulAADLen; -+ CK_ULONG ulTagLen; -+} CK_NSS_AEAD_PARAMS; -+ -+/* -+ * NSS-defined return values -+ * -+ */ -+#define CKR_NSS (CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+#define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1) -+#define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2) -+ -+/* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms. -+ See RFC 5869. -+ -+ bExtract: If set, HKDF-Extract will be applied to the input key. If -+ the optional salt is given, it is used; otherwise, the salt is -+ set to a sequence of zeros equal in length to the HMAC output. -+ If bExpand is not set, then the key template given to -+ C_DeriveKey must indicate an output key size less than or equal -+ to the output size of the HMAC. -+ -+ bExpand: If set, HKDF-Expand will be applied to the input key (if -+ bExtract is not set) or to the result of HKDF-Extract (if -+ bExtract is set). Any info given in the optional pInfo field will -+ be included in the calculation. -+ -+ The size of the output key must be specified in the template passed to -+ C_DeriveKey. -+*/ -+typedef struct CK_NSS_HKDFParams { -+ CK_BBOOL bExtract; -+ CK_BYTE_PTR pSalt; -+ CK_ULONG ulSaltLen; -+ CK_BBOOL bExpand; -+ CK_BYTE_PTR pInfo; -+ CK_ULONG ulInfoLen; -+} CK_NSS_HKDFParams; -+ -+/* -+ * CK_NSS_IKE_PRF_PLUS_PARAMS is a structure that provides the parameters to -+ * the CKM_NSS_IKE_PRF_PLUS_DERIVE mechanism. -+ * The fields of the structure have the following meanings: -+ * prfMechanism underlying MAC mechanism used to generate the prf. -+ * bHasSeedKey hSeed key is present. -+ * hSeedKey optional seed from key -+ * pSeedData optional seed from data. -+ * ulSeedDataLen length of optional seed data. -+ * If no seed data is present this value is NULL. -+ */ -+typedef struct CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS { -+ CK_MECHANISM_TYPE prfMechanism; -+ CK_BBOOL bHasSeedKey; -+ CK_OBJECT_HANDLE hSeedKey; -+ CK_BYTE_PTR pSeedData; -+ CK_ULONG ulSeedDataLen; -+} CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS; -+ -+/* CK_NSS_IKE_PRF_DERIVE_PARAMS is a structure that provides the parameters to -+ * the CKM_NSS_IKE_PRF_DERIVE mechanism. -+ * -+ * The fields of the structure have the following meanings: -+ * prfMechanism underlying MAC mechanism used to generate the prf. -+ * bRekey hNewKey is present. -+ * pNi Ni value -+ * ulNiLen length of Ni -+ * pNr Nr value -+ * ulNrLen length of Nr -+ * hNewKey New key value to drive the rekey. -+ */ -+typedef struct CK_NSS_IKE_PRF_DERIVE_PARAMS { -+ CK_MECHANISM_TYPE prfMechanism; -+ CK_BBOOL bDataAsKey; -+ CK_BBOOL bRekey; -+ CK_BYTE_PTR pNi; -+ CK_ULONG ulNiLen; -+ CK_BYTE_PTR pNr; -+ CK_ULONG ulNrLen; -+ CK_OBJECT_HANDLE hNewKey; -+} CK_NSS_IKE_PRF_DERIVE_PARAMS; -+ -+/* CK_NSS_IKE1_PRF_DERIVE_PARAMS is a structure that provides the parameters -+ * to the CKM_NSS_IKE_PRF_DERIVE mechanism. -+ * -+ * The fields of the structure have the following meanings: -+ * prfMechanism underlying MAC mechanism used to generate the prf. -+ * bRekey hNewKey is present. -+ * pCKYi CKYi value -+ * ulCKYiLen length of CKYi -+ * pCKYr CKYr value -+ * ulCKYrLen length of CKYr -+ * hNewKey New key value to drive the rekey. -+ */ -+typedef struct CK_NSS_IKE1_PRF_DERIVE_PARAMS { -+ CK_MECHANISM_TYPE prfMechanism; -+ CK_BBOOL bHasPrevKey; -+ CK_OBJECT_HANDLE hKeygxy; -+ CK_OBJECT_HANDLE hPrevKey; -+ CK_BYTE_PTR pCKYi; -+ CK_ULONG ulCKYiLen; -+ CK_BYTE_PTR pCKYr; -+ CK_ULONG ulCKYrLen; -+ CK_BYTE keyNumber; -+} CK_NSS_IKE1_PRF_DERIVE_PARAMS; -+ -+/* CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS is a structure that provides the -+ * parameters to the CKM_NSS_IKE_APP_B_PRF_DERIVE mechanism. -+ * -+ * The fields of the structure have the following meanings: -+ * prfMechanism underlying MAC mechanism used to generate the prf. -+ * bHasKeygxy hKeygxy exists -+ * hKeygxy optional key to hash in the prf -+ * pExtraData optional extra data to hash in the prf -+ * ulExtraData length of the optional extra data. -+ * -+ * CK_NSS_IKE_APP_B_PRF_DERIVE can take wither CK_NSS_IKE1_APP_B_PRF_DRIVE_PARAMS -+ * or a single CK_MECHANISM_TYPE. In the latter cases bHashKeygx is assumed to -+ * be false and ulExtraDataLen is assumed to be '0'. -+ */ -+typedef struct CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS { -+ CK_MECHANISM_TYPE prfMechanism; -+ CK_BBOOL bHasKeygxy; -+ CK_OBJECT_HANDLE hKeygxy; -+ CK_BYTE_PTR pExtraData; -+ CK_ULONG ulExtraDataLen; -+} CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS; -+ -+/* -+ * Parameter for the TLS extended master secret key derivation mechanisms: -+ * -+ * * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE -+ * * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH -+ * -+ * For the TLS 1.2 PRF, the prfHashMechanism parameter determines the hash -+ * function used. For earlier versions of the PRF, set the prfHashMechanism -+ * value to CKM_TLS_PRF. -+ * -+ * The session hash input is expected to be the output of the same hash -+ * function as the PRF uses (as required by draft-ietf-tls-session-hash). So -+ * the ulSessionHashLen member must be equal the output length of the hash -+ * function specified by the prfHashMechanism member (or, for pre-TLS 1.2 PRF, -+ * the length of concatenated MD5 and SHA-1 digests). -+ * -+ */ -+typedef struct CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS { -+ CK_MECHANISM_TYPE prfHashMechanism; -+ CK_BYTE_PTR pSessionHash; -+ CK_ULONG ulSessionHashLen; -+ CK_VERSION_PTR pVersion; -+} CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS; -+ -+/* -+ * Trust info -+ * -+ * This isn't part of the Cryptoki standard (yet), so I'm putting -+ * all the definitions here. Some of this would move to nssckt.h -+ * if trust info were made part of the standard. In view of this -+ * possibility, I'm putting my (NSS) values in the NSS -+ * vendor space, like everything else. -+ */ -+ -+typedef CK_ULONG CK_TRUST; -+ -+/* The following trust types are defined: */ -+#define CKT_VENDOR_DEFINED 0x80000000 -+ -+#define CKT_NSS (CKT_VENDOR_DEFINED | NSSCK_VENDOR_NSS) -+ -+/* If trust goes standard, these'll probably drop out of vendor space. */ -+#define CKT_NSS_TRUSTED (CKT_NSS + 1) -+#define CKT_NSS_TRUSTED_DELEGATOR (CKT_NSS + 2) -+#define CKT_NSS_MUST_VERIFY_TRUST (CKT_NSS + 3) -+#define CKT_NSS_NOT_TRUSTED (CKT_NSS + 10) -+#define CKT_NSS_TRUST_UNKNOWN (CKT_NSS + 5) /* default */ -+ -+/* -+ * These may well remain NSS-specific; I'm only using them -+ * to cache resolution data. -+ */ -+#define CKT_NSS_VALID_DELEGATOR (CKT_NSS + 11) -+ -+/* -+ * old definitions. They still exist, but the plain meaning of the -+ * labels have never been accurate to what was really implemented. -+ * The new labels correctly reflect what the values effectively mean. -+ */ -+#if defined(__GNUC__) && (__GNUC__ > 3) -+/* make GCC warn when we use these #defines */ -+/* -+ * This is really painful because GCC doesn't allow us to mark random -+ * #defines as deprecated. We can only mark the following: -+ * functions, variables, and types. -+ * const variables will create extra storage for everyone including this -+ * header file, so it's undesirable. -+ * functions could be inlined to prevent storage creation, but will fail -+ * when constant values are expected (like switch statements). -+ * enum types do not seem to pay attention to the deprecated attribute. -+ * -+ * That leaves typedefs. We declare new types that we then deprecate, then -+ * cast the resulting value to the deprecated type in the #define, thus -+ * producting the warning when the #define is used. -+ */ -+#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) -+/* The mac doesn't like the friendlier deprecate messages. I'm assuming this -+ * is a gcc version issue rather than mac or ppc specific */ -+typedef CK_TRUST __CKT_NSS_UNTRUSTED __attribute__((deprecated)); -+typedef CK_TRUST __CKT_NSS_VALID __attribute__((deprecated)); -+typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated)); -+#else -+/* when possible, get a full deprecation warning. This works on gcc 4.5 -+ * it may work on earlier versions of gcc */ -+typedef CK_TRUST __CKT_NSS_UNTRUSTED __attribute__((deprecated("CKT_NSS_UNTRUSTED really means CKT_NSS_MUST_VERIFY_TRUST"))); -+typedef CK_TRUST __CKT_NSS_VALID __attribute__((deprecated("CKT_NSS_VALID really means CKT_NSS_NOT_TRUSTED"))); -+typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated("CKT_NSS_MUST_VERIFY really functions as CKT_NSS_TRUST_UNKNOWN"))); -+#endif -+#define CKT_NSS_UNTRUSTED ((__CKT_NSS_UNTRUSTED)CKT_NSS_MUST_VERIFY_TRUST) -+#define CKT_NSS_VALID ((__CKT_NSS_VALID)CKT_NSS_NOT_TRUSTED) -+/* keep the old value for compatibility reasons*/ -+#define CKT_NSS_MUST_VERIFY ((__CKT_NSS_MUST_VERIFY)(CKT_NSS + 4)) -+#else -+#ifdef _WIN32 -+/* This magic gets the windows compiler to give us a deprecation -+ * warning */ -+#pragma deprecated(CKT_NSS_UNTRUSTED, CKT_NSS_MUST_VERIFY, CKT_NSS_VALID) -+#endif -+/* CKT_NSS_UNTRUSTED really means CKT_NSS_MUST_VERIFY_TRUST */ -+#define CKT_NSS_UNTRUSTED CKT_NSS_MUST_VERIFY_TRUST -+/* CKT_NSS_VALID really means CKT_NSS_NOT_TRUSTED */ -+#define CKT_NSS_VALID CKT_NSS_NOT_TRUSTED -+/* CKT_NSS_MUST_VERIFY was always treated as CKT_NSS_TRUST_UNKNOWN */ -+#define CKT_NSS_MUST_VERIFY (CKT_NSS + 4) /*really means trust unknown*/ -+#endif -+ -+/* -+ * These are not really PKCS #11 values specifically. They are the 'loadable' -+ * module spec NSS uses. They are available for others to use as well, but not -+ * part of the formal PKCS #11 spec. -+ * -+ * The function 'FIND' returns an array of PKCS #11 initialization strings -+ * The function 'ADD' takes a PKCS #11 initialization string and stores it. -+ * The function 'DEL' takes a 'name= library=' value and deletes the associated -+ * string. -+ * The function 'RELEASE' frees the array returned by 'FIND' -+ */ -+#define SECMOD_MODULE_DB_FUNCTION_FIND 0 -+#define SECMOD_MODULE_DB_FUNCTION_ADD 1 -+#define SECMOD_MODULE_DB_FUNCTION_DEL 2 -+#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3 -+typedef char **(PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function, -+ char *parameters, void *moduleSpec); -+ -+/* softoken slot ID's */ -+#define SFTK_MIN_USER_SLOT_ID 4 -+#define SFTK_MAX_USER_SLOT_ID 100 -+#define SFTK_MIN_FIPS_USER_SLOT_ID 101 -+#define SFTK_MAX_FIPS_USER_SLOT_ID 127 -+ -+/* Module Interface. This is the old NSS private module interface, now exported -+ * as a PKCS #11 v3 interface. It's interface name is -+ * "Vendor NSS Module Interface" */ -+typedef char **(*CK_NSS_ModuleDBFunc)(unsigned long function, -+ char *parameters, void *args); -+typedef struct CK_NSS_MODULE_FUNCTIONS { -+ CK_VERSION version; -+ CK_NSS_ModuleDBFunc NSC_ModuleDBFunc; -+} CK_NSS_MODULE_FUNCTIONS; -+ -+/* There was an inconsistency between the spec and the header file in defining -+ * the CK_GCM_PARAMS structure. The authoritative reference is the header file, -+ * but NSS used the spec when adding it to its own header. In V3 we've -+ * corrected it, but we need to handle the old case for devices that followed -+ * us in using the incorrect specification. */ -+typedef struct CK_NSS_GCM_PARAMS { -+ CK_BYTE_PTR pIv; -+ CK_ULONG ulIvLen; -+ CK_BYTE_PTR pAAD; -+ CK_ULONG ulAADLen; -+ CK_ULONG ulTagBits; -+} CK_NSS_GCM_PARAMS; -+ -+typedef CK_NSS_GCM_PARAMS CK_PTR CK_NSS_GCM_PARAMS_PTR; -+ -+/* deprecated #defines. Drop in future NSS releases */ -+#ifdef NSS_PKCS11_2_0_COMPAT -+ -+/* defines that were changed between NSS's PKCS #11 and the Oasis headers */ -+#define CKF_EC_FP CKF_EC_F_P -+#define CKO_KG_PARAMETERS CKO_DOMAIN_PARAMETERS -+#define CK_INVALID_SESSION CK_INVALID_HANDLE -+#define CKR_KEY_PARAMS_INVALID 0x0000006B -+ -+/* use the old wrong CK_GCM_PARAMS is NSS_PCKS11_2_0_COMPAT is defined */ -+typedef struct CK_NSS_GCM_PARAMS CK_GCM_PARAMS; -+typedef CK_NSS_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; -+ -+/* don't leave old programs in a lurch just yet, give them the old NETSCAPE -+ * synonym if NSS_PKCS11_2_0_COMPAT is defined*/ -+#define CKO_NETSCAPE_CRL CKO_NSS_CRL -+#define CKO_NETSCAPE_SMIME CKO_NSS_SMIME -+#define CKO_NETSCAPE_TRUST CKO_NSS_TRUST -+#define CKO_NETSCAPE_BUILTIN_ROOT_LIST CKO_NSS_BUILTIN_ROOT_LIST -+#define CKO_NETSCAPE_NEWSLOT CKO_NSS_NEWSLOT -+#define CKO_NETSCAPE_DELSLOT CKO_NSS_DELSLOT -+#define CKK_NETSCAPE_PKCS8 CKK_NSS_PKCS8 -+#define CKA_NETSCAPE_URL CKA_NSS_URL -+#define CKA_NETSCAPE_EMAIL CKA_NSS_EMAIL -+#define CKA_NETSCAPE_SMIME_INFO CKA_NSS_SMIME_INFO -+#define CKA_NETSCAPE_SMIME_TIMESTAMP CKA_NSS_SMIME_TIMESTAMP -+#define CKA_NETSCAPE_PKCS8_SALT CKA_NSS_PKCS8_SALT -+#define CKA_NETSCAPE_PASSWORD_CHECK CKA_NSS_PASSWORD_CHECK -+#define CKA_NETSCAPE_EXPIRES CKA_NSS_EXPIRES -+#define CKA_NETSCAPE_KRL CKA_NSS_KRL -+#define CKA_NETSCAPE_PQG_COUNTER CKA_NSS_PQG_COUNTER -+#define CKA_NETSCAPE_PQG_SEED CKA_NSS_PQG_SEED -+#define CKA_NETSCAPE_PQG_H CKA_NSS_PQG_H -+#define CKA_NETSCAPE_PQG_SEED_BITS CKA_NSS_PQG_SEED_BITS -+#define CKA_NETSCAPE_MODULE_SPEC CKA_NSS_MODULE_SPEC -+#define CKA_NETSCAPE_DB CKA_NSS_DB -+#define CKA_NETSCAPE_TRUST CKA_NSS_TRUST -+#define CKM_NETSCAPE_AES_KEY_WRAP CKM_NSS_AES_KEY_WRAP -+#define CKM_NETSCAPE_AES_KEY_WRAP_PAD CKM_NSS_AES_KEY_WRAP_PAD -+#define CKM_NETSCAPE_PBE_SHA1_DES_CBC CKM_NSS_PBE_SHA1_DES_CBC -+#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC -+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC -+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC -+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 CKM_NSS_PBE_SHA1_40_BIT_RC4 -+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 CKM_NSS_PBE_SHA1_128_BIT_RC4 -+#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC -+#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN CKM_NSS_PBE_SHA1_HMAC_KEY_GEN -+#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN CKM_NSS_PBE_MD5_HMAC_KEY_GEN -+#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN CKM_NSS_PBE_MD2_HMAC_KEY_GEN -+#define CKR_NETSCAPE_CERTDB_FAILED CKR_NSS_CERTDB_FAILED -+#define CKR_NETSCAPE_KEYDB_FAILED CKR_NSS_KEYDB_FAILED -+ -+#define CKT_NETSCAPE_TRUSTED CKT_NSS_TRUSTED -+#define CKT_NETSCAPE_TRUSTED_DELEGATOR CKT_NSS_TRUSTED_DELEGATOR -+#define CKT_NETSCAPE_UNTRUSTED CKT_NSS_UNTRUSTED -+#define CKT_NETSCAPE_MUST_VERIFY CKT_NSS_MUST_VERIFY -+#define CKT_NETSCAPE_TRUST_UNKNOWN CKT_NSS_TRUST_UNKNOWN -+#define CKT_NETSCAPE_VALID CKT_NSS_VALID -+#define CKT_NETSCAPE_VALID_DELEGATOR CKT_NSS_VALID_DELEGATOR -+#else -+/* use the new CK_GCM_PARAMS if NSS_PKCS11_2_0_COMPAT is not defined */ -+typedef struct CK_GCM_PARAMS_V3 CK_GCM_PARAMS; -+typedef CK_GCM_PARAMS_V3 CK_PTR CK_GCM_PARAMS_PTR; -+#endif -+ -+#endif /* _PKCS11N_H_ */ ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h -@@ -1,1150 +1,1265 @@ --/* Copyright (c) OASIS Open 2016, 2019. All Rights Reserved./ -- * /Distributed under the terms of the OASIS IPR Policy, -- * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY -- * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A -- * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. -- */ -- --/* Latest version of the specification: -- * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html -- */ -- --/* See top of pkcs11.h for information about the macros that -- * must be defined and the structure-packing conventions that -- * must be set before including this file. -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+/* License to copy and use this software is granted provided that it is -+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface -+ * (Cryptoki)" in all material mentioning or referencing this software. -+ -+ * License is also granted to make and use derivative works provided that -+ * such works are identified as "derived from the RSA Security Inc. PKCS #11 -+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or -+ * referencing the derived work. -+ -+ * RSA Security Inc. makes no representations concerning either the -+ * merchantability of this software or the suitability of this software for -+ * any particular purpose. It is provided "as is" without express or implied -+ * warranty of any kind. - */ - - #ifndef _PKCS11T_H_ - #define _PKCS11T_H_ 1 - --#define CRYPTOKI_VERSION_MAJOR 3 --#define CRYPTOKI_VERSION_MINOR 0 --#define CRYPTOKI_VERSION_AMENDMENT 0 -- --#define CK_TRUE 1 --#define CK_FALSE 0 -- --#ifndef CK_DISABLE_TRUE_FALSE --#ifndef FALSE --#define FALSE CK_FALSE --#endif --#ifndef TRUE --#define TRUE CK_TRUE --#endif -+#define CK_TRUE 1 -+#define CK_FALSE 0 -+ -+#include "prtypes.h" -+ -+#define CK_PTR * -+#define CK_NULL_PTR 0 -+#define CK_CALLBACK_FUNCTION(rtype, func) rtype(PR_CALLBACK *func) -+#define CK_DECLARE_FUNCTION(rtype, func) extern rtype func -+#define CK_DECLARE_FUNCTION_POINTER(rtype, func) rtype(PR_CALLBACK *func) -+ -+#ifdef NSS_PCKS11_2_0_COMPAT -+#define prfHashMechanism prfMechanism - #endif - -+#define CRYPTOKI_VERSION_MAJOR 3 -+#define CRYPTOKI_VERSION_MINOR 0 -+#define CRYPTOKI_VERSION_AMENDMENT 0 -+ - /* an unsigned 8-bit value */ --typedef unsigned char CK_BYTE; -+typedef unsigned char CK_BYTE; - - /* an unsigned 8-bit character */ --typedef CK_BYTE CK_CHAR; -+typedef CK_BYTE CK_CHAR; - - /* an 8-bit UTF-8 character */ --typedef CK_BYTE CK_UTF8CHAR; -+typedef CK_BYTE CK_UTF8CHAR; - - /* a BYTE-sized Boolean flag */ --typedef CK_BYTE CK_BBOOL; -+typedef CK_BYTE CK_BBOOL; - - /* an unsigned value, at least 32 bits long */ - typedef unsigned long int CK_ULONG; - - /* a signed value, the same size as a CK_ULONG */ --typedef long int CK_LONG; -+/* CK_LONG is new for v2.0 */ -+typedef long int CK_LONG; - - /* at least 32 bits; each bit is a Boolean flag */ --typedef CK_ULONG CK_FLAGS; -- -+typedef CK_ULONG CK_FLAGS; - - /* some special values for certain CK_ULONG variables */ --#define CK_UNAVAILABLE_INFORMATION (~0UL) --#define CK_EFFECTIVELY_INFINITE 0UL -- -+#define CK_UNAVAILABLE_INFORMATION (~0UL) -+#define CK_EFFECTIVELY_INFINITE 0 - --typedef CK_BYTE CK_PTR CK_BYTE_PTR; --typedef CK_CHAR CK_PTR CK_CHAR_PTR; --typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; --typedef CK_ULONG CK_PTR CK_ULONG_PTR; --typedef void CK_PTR CK_VOID_PTR; -+typedef CK_BYTE CK_PTR CK_BYTE_PTR; -+typedef CK_CHAR CK_PTR CK_CHAR_PTR; -+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; -+typedef CK_ULONG CK_PTR CK_ULONG_PTR; -+typedef void CK_PTR CK_VOID_PTR; - - /* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ - typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; - -+/* The following value is always invalid if used as a session */ -+/* handle or object handle */ -+#define CK_INVALID_HANDLE 0 - --/* The following value is always invalid if used as a session -- * handle or object handle -- */ --#define CK_INVALID_HANDLE 0UL -- -+/* pack */ -+// #include "pkcs11p.h" - - typedef struct CK_VERSION { -- CK_BYTE major; /* integer portion of version number */ -- CK_BYTE minor; /* 1/100ths portion of version number */ -+ CK_BYTE major; /* integer portion of version number */ -+ CK_BYTE minor; /* 1/100ths portion of version number */ - } CK_VERSION; - - typedef CK_VERSION CK_PTR CK_VERSION_PTR; - -- - typedef struct CK_INFO { -- CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ -- CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -- CK_FLAGS flags; /* must be zero */ -+ /* manufacturerID and libraryDecription have been changed from -+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ -+ CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */ -+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -+ CK_FLAGS flags; /* must be zero */ -+ -+ /* libraryDescription and libraryVersion are new for v2.0 */ - CK_UTF8CHAR libraryDescription[32]; /* blank padded */ -- CK_VERSION libraryVersion; /* version of library */ -+ CK_VERSION libraryVersion; /* version of library */ - } CK_INFO; - --typedef CK_INFO CK_PTR CK_INFO_PTR; -- -+typedef CK_INFO CK_PTR CK_INFO_PTR; - - /* CK_NOTIFICATION enumerates the types of notifications that -- * Cryptoki provides to an application -- */ -+ * PKCS #11 provides to an application */ -+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG -+ * for v2.0 */ - typedef CK_ULONG CK_NOTIFICATION; --#define CKN_SURRENDER 0UL --#define CKN_OTP_CHANGED 1UL -+#define CKN_SURRENDER 0 - --typedef CK_ULONG CK_SLOT_ID; -+typedef CK_ULONG CK_SLOT_ID; - - typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; - -- - /* CK_SLOT_INFO provides information about a slot */ - typedef struct CK_SLOT_INFO { -- CK_UTF8CHAR slotDescription[64]; /* blank padded */ -- CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -- CK_FLAGS flags; -+ /* slotDescription and manufacturerID have been changed from -+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ -+ CK_UTF8CHAR slotDescription[64]; /* blank padded */ -+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -+ CK_FLAGS flags; - -- CK_VERSION hardwareVersion; /* version of hardware */ -- CK_VERSION firmwareVersion; /* version of firmware */ -+ /* hardwareVersion and firmwareVersion are new for v2.0 */ -+ CK_VERSION hardwareVersion; /* version of hardware */ -+ CK_VERSION firmwareVersion; /* version of firmware */ - } CK_SLOT_INFO; - - /* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ --#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */ --#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/ --#define CKF_HW_SLOT 0x00000004UL /* hardware slot */ -+#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */ -+#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/ -+#define CKF_HW_SLOT 0x00000004UL /* hardware slot */ - - typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; - -- - /* CK_TOKEN_INFO provides information about a token */ - typedef struct CK_TOKEN_INFO { -- CK_UTF8CHAR label[32]; /* blank padded */ -- CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -- CK_UTF8CHAR model[16]; /* blank padded */ -- CK_CHAR serialNumber[16]; /* blank padded */ -- CK_FLAGS flags; /* see below */ -- -- CK_ULONG ulMaxSessionCount; /* max open sessions */ -- CK_ULONG ulSessionCount; /* sess. now open */ -- CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ -- CK_ULONG ulRwSessionCount; /* R/W sess. now open */ -- CK_ULONG ulMaxPinLen; /* in bytes */ -- CK_ULONG ulMinPinLen; /* in bytes */ -- CK_ULONG ulTotalPublicMemory; /* in bytes */ -- CK_ULONG ulFreePublicMemory; /* in bytes */ -- CK_ULONG ulTotalPrivateMemory; /* in bytes */ -- CK_ULONG ulFreePrivateMemory; /* in bytes */ -- CK_VERSION hardwareVersion; /* version of hardware */ -- CK_VERSION firmwareVersion; /* version of firmware */ -- CK_CHAR utcTime[16]; /* time */ -+ /* label, manufacturerID, and model have been changed from -+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ -+ CK_UTF8CHAR label[32]; /* blank padded */ -+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ -+ CK_UTF8CHAR model[16]; /* blank padded */ -+ CK_CHAR serialNumber[16]; /* blank padded */ -+ CK_FLAGS flags; /* see below */ -+ -+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, -+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been -+ * changed from CK_USHORT to CK_ULONG for v2.0 */ -+ CK_ULONG ulMaxSessionCount; /* max open sessions */ -+ CK_ULONG ulSessionCount; /* sess. now open */ -+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ -+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */ -+ CK_ULONG ulMaxPinLen; /* in bytes */ -+ CK_ULONG ulMinPinLen; /* in bytes */ -+ CK_ULONG ulTotalPublicMemory; /* in bytes */ -+ CK_ULONG ulFreePublicMemory; /* in bytes */ -+ CK_ULONG ulTotalPrivateMemory; /* in bytes */ -+ CK_ULONG ulFreePrivateMemory; /* in bytes */ -+ -+ /* hardwareVersion, firmwareVersion, and time are new for -+ * v2.0 */ -+ CK_VERSION hardwareVersion; /* version of hardware */ -+ CK_VERSION firmwareVersion; /* version of firmware */ -+ CK_CHAR utcTime[16]; /* time */ - } CK_TOKEN_INFO; - - /* The flags parameter is defined as follows: - * Bit Flag Mask Meaning - */ --#define CKF_RNG 0x00000001UL /* has random # generator */ --#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */ --#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */ --#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */ -+#define CKF_RNG 0x00000001UL /* has random # \ -+ * generator */ -+#define CKF_WRITE_PROTECTED 0x00000002UL /* token is \ -+ * write- \ -+ * protected */ -+#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must \ -+ * login */ -+#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's \ -+ * PIN is set */ - --/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set, -+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, - * that means that *every* time the state of cryptographic - * operations of a session is successfully saved, all keys -- * needed to continue those operations are stored in the state -- */ --#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL -+ * needed to continue those operations are stored in the state */ -+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL - --/* CKF_CLOCK_ON_TOKEN. If it is set, that means -+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means - * that the token has some sort of clock. The time on that -- * clock is returned in the token info structure -- */ --#define CKF_CLOCK_ON_TOKEN 0x00000040UL -+ * clock is returned in the token info structure */ -+#define CKF_CLOCK_ON_TOKEN 0x00000040UL - --/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is -+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is - * set, that means that there is some way for the user to login -- * without sending a PIN through the Cryptoki library itself -- */ -+ * without sending a PIN through the PKCS #11 library itself */ - #define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL - --/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true, -+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, - * that means that a single session with the token can perform - * dual simultaneous cryptographic operations (digest and - * encrypt; decrypt and digest; sign and encrypt; and decrypt -- * and sign) -- */ --#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL -+ * and sign) */ -+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL - --/* CKF_TOKEN_INITIALIZED. If it is true, the -+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the - * token has been initialized using C_InitializeToken or an - * equivalent mechanism outside the scope of PKCS #11. - * Calling C_InitializeToken when this flag is set will cause -- * the token to be reinitialized. -- */ --#define CKF_TOKEN_INITIALIZED 0x00000400UL -+ * the token to be reinitialized. */ -+#define CKF_TOKEN_INITIALIZED 0x00000400UL - --/* CKF_SECONDARY_AUTHENTICATION. If it is -+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is - * true, the token supports secondary authentication for -- * private key objects. -- */ --#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL -+ * private key objects. This flag is deprecated in v2.11 and -+ onwards. */ -+#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL - --/* CKF_USER_PIN_COUNT_LOW. If it is true, an -+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an - * incorrect user login PIN has been entered at least once -- * since the last successful authentication. -- */ --#define CKF_USER_PIN_COUNT_LOW 0x00010000UL -+ * since the last successful authentication. */ -+#define CKF_USER_PIN_COUNT_LOW 0x00010000UL - --/* CKF_USER_PIN_FINAL_TRY. If it is true, -- * supplying an incorrect user PIN will it to become locked. -- */ --#define CKF_USER_PIN_FINAL_TRY 0x00020000UL -+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true, -+ * supplying an incorrect user PIN will it to become locked. */ -+#define CKF_USER_PIN_FINAL_TRY 0x00020000UL - --/* CKF_USER_PIN_LOCKED. If it is true, the -+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the - * user PIN has been locked. User login to the token is not -- * possible. -- */ --#define CKF_USER_PIN_LOCKED 0x00040000UL -+ * possible. */ -+#define CKF_USER_PIN_LOCKED 0x00040000UL - --/* CKF_USER_PIN_TO_BE_CHANGED. If it is true, -+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true, - * the user PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been -- * expired by the card. -- */ --#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL -+ * expired by the card. */ -+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL - --/* CKF_SO_PIN_COUNT_LOW. If it is true, an -+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an - * incorrect SO login PIN has been entered at least once since -- * the last successful authentication. -- */ --#define CKF_SO_PIN_COUNT_LOW 0x00100000UL -+ * the last successful authentication. */ -+#define CKF_SO_PIN_COUNT_LOW 0x00100000UL - --/* CKF_SO_PIN_FINAL_TRY. If it is true, -- * supplying an incorrect SO PIN will it to become locked. -- */ --#define CKF_SO_PIN_FINAL_TRY 0x00200000UL -+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true, -+ * supplying an incorrect SO PIN will it to become locked. */ -+#define CKF_SO_PIN_FINAL_TRY 0x00200000UL - --/* CKF_SO_PIN_LOCKED. If it is true, the SO -+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO - * PIN has been locked. SO login to the token is not possible. - */ --#define CKF_SO_PIN_LOCKED 0x00400000UL -+#define CKF_SO_PIN_LOCKED 0x00400000UL - --/* CKF_SO_PIN_TO_BE_CHANGED. If it is true, -+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true, - * the SO PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been -- * expired by the card. -- */ --#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL -+ * expired by the card. */ -+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL - --#define CKF_ERROR_STATE 0x01000000UL -+#define CKF_ERROR_STATE 0x01000000UL - - typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; - -- --/* CK_SESSION_HANDLE is a Cryptoki-assigned value that -- * identifies a session -- */ --typedef CK_ULONG CK_SESSION_HANDLE; -+/* CK_SESSION_HANDLE is a PKCS #11-assigned value that -+ * identifies a session */ -+typedef CK_ULONG CK_SESSION_HANDLE; - - typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; - -- --/* CK_USER_TYPE enumerates the types of Cryptoki users */ --typedef CK_ULONG CK_USER_TYPE; -+/* CK_USER_TYPE enumerates the types of PKCS #11 users */ -+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for -+ * v2.0 */ -+typedef CK_ULONG CK_USER_TYPE; - /* Security Officer */ --#define CKU_SO 0UL -+#define CKU_SO 0 - /* Normal user */ --#define CKU_USER 1UL --/* Context specific */ --#define CKU_CONTEXT_SPECIFIC 2UL -+#define CKU_USER 1 -+/* Context specific (added in v2.20) */ -+#define CKU_CONTEXT_SPECIFIC 2 - - /* CK_STATE enumerates the session states */ --typedef CK_ULONG CK_STATE; --#define CKS_RO_PUBLIC_SESSION 0UL --#define CKS_RO_USER_FUNCTIONS 1UL --#define CKS_RW_PUBLIC_SESSION 2UL --#define CKS_RW_USER_FUNCTIONS 3UL --#define CKS_RW_SO_FUNCTIONS 4UL -+/* CK_STATE has been changed from an enum to a CK_ULONG for -+ * v2.0 */ -+typedef CK_ULONG CK_STATE; -+#define CKS_RO_PUBLIC_SESSION 0 -+#define CKS_RO_USER_FUNCTIONS 1 -+#define CKS_RW_PUBLIC_SESSION 2 -+#define CKS_RW_USER_FUNCTIONS 3 -+#define CKS_RW_SO_FUNCTIONS 4 - - /* CK_SESSION_INFO provides information about a session */ - typedef struct CK_SESSION_INFO { - CK_SLOT_ID slotID; -- CK_STATE state; -- CK_FLAGS flags; /* see below */ -- CK_ULONG ulDeviceError; /* device-dependent error code */ -+ CK_STATE state; -+ CK_FLAGS flags; /* see below */ -+ -+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+ CK_ULONG ulDeviceError; /* device-dependent error code */ - } CK_SESSION_INFO; - - /* The flags are defined in the following table: - * Bit Flag Mask Meaning - */ --#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ --#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ -+#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ -+#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ - - typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; - -- - /* CK_OBJECT_HANDLE is a token-specific identifier for an -- * object -- */ --typedef CK_ULONG CK_OBJECT_HANDLE; -+ * object */ -+typedef CK_ULONG CK_OBJECT_HANDLE; - - typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; - -- - /* CK_OBJECT_CLASS is a value that identifies the classes (or -- * types) of objects that Cryptoki recognizes. It is defined -- * as follows: -- */ --typedef CK_ULONG CK_OBJECT_CLASS; -+ * types) of objects that PKCS #11 recognizes. It is defined -+ * as follows: */ -+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+typedef CK_ULONG CK_OBJECT_CLASS; - - /* The following classes of objects are defined: */ --#define CKO_DATA 0x00000000UL --#define CKO_CERTIFICATE 0x00000001UL --#define CKO_PUBLIC_KEY 0x00000002UL --#define CKO_PRIVATE_KEY 0x00000003UL --#define CKO_SECRET_KEY 0x00000004UL --#define CKO_HW_FEATURE 0x00000005UL -+/* CKO_HW_FEATURE is new for v2.10 */ -+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */ -+/* CKO_MECHANISM is new for v2.20 */ -+/* CKO_PROFILE is new for v3.00 */ -+#define CKO_DATA 0x00000000UL -+#define CKO_CERTIFICATE 0x00000001UL -+#define CKO_PUBLIC_KEY 0x00000002UL -+#define CKO_PRIVATE_KEY 0x00000003UL -+#define CKO_SECRET_KEY 0x00000004UL -+#define CKO_HW_FEATURE 0x00000005UL - #define CKO_DOMAIN_PARAMETERS 0x00000006UL --#define CKO_MECHANISM 0x00000007UL --#define CKO_OTP_KEY 0x00000008UL --#define CKO_PROFILE 0x00000009UL -- --#define CKO_VENDOR_DEFINED 0x80000000UL -+#define CKO_MECHANISM 0x00000007UL -+#define CKO_PROFILE 0x00000009UL -+#define CKO_VENDOR_DEFINED 0x80000000UL - - typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; - -+/* CK_PROFILE_ID is new for v3.00. CK_PROFILE_ID is a value that -+ * identifies the profile that the token supports. */ -+typedef CK_ULONG CK_PROFILE_ID; -+ - /* Profile ID's */ --#define CKP_INVALID_ID 0x00000000UL --#define CKP_BASELINE_PROVIDER 0x00000001UL --#define CKP_EXTENDED_PROVIDER 0x00000002UL --#define CKP_AUTHENTICATION_TOKEN 0x00000003UL -+#define CKP_INVALID_ID 0x00000000UL -+#define CKP_BASELINE_PROVIDER 0x00000001UL -+#define CKP_EXTENDED_PROVIDER 0x00000002UL -+#define CKP_AUTHENTICATION_TOKEN 0x00000003UL - #define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL --#define CKP_VENDOR_DEFINED 0x80000000UL -+#define CKP_VENDOR_DEFINED 0x80000000UL - --/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type -- * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. -- */ --typedef CK_ULONG CK_HW_FEATURE_TYPE; -+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a -+ * value that identifies the hardware feature type of an object -+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */ -+typedef CK_ULONG CK_HW_FEATURE_TYPE; - - /* The following hardware feature types are defined */ --#define CKH_MONOTONIC_COUNTER 0x00000001UL --#define CKH_CLOCK 0x00000002UL --#define CKH_USER_INTERFACE 0x00000003UL --#define CKH_VENDOR_DEFINED 0x80000000UL -+/* CKH_USER_INTERFACE is new for v2.20 */ -+#define CKH_MONOTONIC_COUNTER 0x00000001UL -+#define CKH_CLOCK 0x00000002UL -+#define CKH_USER_INTERFACE 0x00000003UL -+#define CKH_VENDOR_DEFINED 0x80000000UL - - /* CK_KEY_TYPE is a value that identifies a key type */ --typedef CK_ULONG CK_KEY_TYPE; -+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ -+typedef CK_ULONG CK_KEY_TYPE; - - /* the following key types are defined: */ --#define CKK_RSA 0x00000000UL --#define CKK_DSA 0x00000001UL --#define CKK_DH 0x00000002UL --#define CKK_ECDSA 0x00000003UL /* Deprecated */ --#define CKK_EC 0x00000003UL --#define CKK_X9_42_DH 0x00000004UL --#define CKK_KEA 0x00000005UL --#define CKK_GENERIC_SECRET 0x00000010UL --#define CKK_RC2 0x00000011UL --#define CKK_RC4 0x00000012UL --#define CKK_DES 0x00000013UL --#define CKK_DES2 0x00000014UL --#define CKK_DES3 0x00000015UL --#define CKK_CAST 0x00000016UL --#define CKK_CAST3 0x00000017UL --#define CKK_CAST5 0x00000018UL /* Deprecated */ --#define CKK_CAST128 0x00000018UL --#define CKK_RC5 0x00000019UL --#define CKK_IDEA 0x0000001AUL --#define CKK_SKIPJACK 0x0000001BUL --#define CKK_BATON 0x0000001CUL --#define CKK_JUNIPER 0x0000001DUL --#define CKK_CDMF 0x0000001EUL --#define CKK_AES 0x0000001FUL --#define CKK_BLOWFISH 0x00000020UL --#define CKK_TWOFISH 0x00000021UL --#define CKK_SECURID 0x00000022UL --#define CKK_HOTP 0x00000023UL --#define CKK_ACTI 0x00000024UL --#define CKK_CAMELLIA 0x00000025UL --#define CKK_ARIA 0x00000026UL -- --/* the following definitions were added in the 2.30 header file, -- * but never defined in the spec. */ --#define CKK_MD5_HMAC 0x00000027UL --#define CKK_SHA_1_HMAC 0x00000028UL --#define CKK_RIPEMD128_HMAC 0x00000029UL --#define CKK_RIPEMD160_HMAC 0x0000002AUL --#define CKK_SHA256_HMAC 0x0000002BUL --#define CKK_SHA384_HMAC 0x0000002CUL --#define CKK_SHA512_HMAC 0x0000002DUL --#define CKK_SHA224_HMAC 0x0000002EUL -- --#define CKK_SEED 0x0000002FUL --#define CKK_GOSTR3410 0x00000030UL --#define CKK_GOSTR3411 0x00000031UL --#define CKK_GOST28147 0x00000032UL --#define CKK_CHACHA20 0x00000033UL --#define CKK_POLY1305 0x00000034UL --#define CKK_AES_XTS 0x00000035UL --#define CKK_SHA3_224_HMAC 0x00000036UL --#define CKK_SHA3_256_HMAC 0x00000037UL --#define CKK_SHA3_384_HMAC 0x00000038UL --#define CKK_SHA3_512_HMAC 0x00000039UL --#define CKK_BLAKE2B_160_HMAC 0x0000003aUL --#define CKK_BLAKE2B_256_HMAC 0x0000003bUL --#define CKK_BLAKE2B_384_HMAC 0x0000003cUL --#define CKK_BLAKE2B_512_HMAC 0x0000003dUL --#define CKK_SALSA20 0x0000003eUL --#define CKK_X2RATCHET 0x0000003fUL --#define CKK_EC_EDWARDS 0x00000040UL --#define CKK_EC_MONTGOMERY 0x00000041UL --#define CKK_HKDF 0x00000042UL --#define CKK_SHA512_224_HMAC 0x00000043UL --#define CKK_SHA512_256_HMAC 0x00000044UL --#define CKK_SHA512_T_HMAC 0x00000045UL -- --#define CKK_VENDOR_DEFINED 0x80000000UL -+#define CKK_RSA 0x00000000UL -+#define CKK_DSA 0x00000001UL -+#define CKK_DH 0x00000002UL -+ -+/* CKK_ECDSA and CKK_KEA are new for v2.0 */ -+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */ -+#define CKK_ECDSA 0x00000003UL -+#define CKK_EC 0x00000003UL -+#define CKK_X9_42_DH 0x00000004UL -+#define CKK_KEA 0x00000005UL -+ -+#define CKK_GENERIC_SECRET 0x00000010UL -+#define CKK_RC2 0x00000011UL -+#define CKK_RC4 0x00000012UL -+#define CKK_DES 0x00000013UL -+#define CKK_DES2 0x00000014UL -+#define CKK_DES3 0x00000015UL -+ -+/* all these key types are new for v2.0 */ -+#define CKK_CAST 0x00000016UL -+#define CKK_CAST3 0x00000017UL -+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */ -+#define CKK_CAST5 0x00000018UL -+#define CKK_CAST128 0x00000018UL -+#define CKK_RC5 0x00000019UL -+#define CKK_IDEA 0x0000001AUL -+#define CKK_SKIPJACK 0x0000001BUL -+#define CKK_BATON 0x0000001CUL -+#define CKK_JUNIPER 0x0000001DUL -+#define CKK_CDMF 0x0000001EUL -+#define CKK_AES 0x0000001FUL -+ -+/* BlowFish and TwoFish are new for v2.20 */ -+#define CKK_BLOWFISH 0x00000020UL -+#define CKK_TWOFISH 0x00000021UL -+ -+/* Camellia is proposed for v2.20 Amendment 3 */ -+#define CKK_CAMELLIA 0x00000025UL -+ -+#define CKK_SEED 0x0000002FUL /* was 2A */ -+ -+/* added in v2.30 */ -+#define CKK_ARIA 0x00000026UL -+ -+/* added in 2.40 */ -+#define CKK_MD5_HMAC 0x00000027UL -+#define CKK_SHA_1_HMAC 0x00000028UL -+#define CKK_RIPEMD128_HMAC 0x00000029UL -+#define CKK_RIPEMD160_HMAC 0x0000002AUL -+#define CKK_SHA256_HMAC 0x0000002BUL -+#define CKK_SHA384_HMAC 0x0000002CUL -+#define CKK_SHA512_HMAC 0x0000002DUL -+#define CKK_SHA224_HMAC 0x0000002EUL -+#define CKK_GOSTR3410 0x00000030UL -+#define CKK_GOSTR3411 0x00000031UL -+#define CKK_GOST28147 0x00000032UL -+#define CKK_CHACHA20 0x00000033UL -+#define CKK_POLY1305 0x00000034UL -+#define CKK_AES_XTS 0x00000035UL -+#define CKK_SHA3_224_HMAC 0x00000036UL -+#define CKK_SHA3_256_HMAC 0x00000037UL -+#define CKK_SHA3_384_HMAC 0x00000038UL -+#define CKK_SHA3_512_HMAC 0x00000039UL -+ -+/* added in 3.0 */ -+#define CKK_BLAKE2B_160_HMAC 0x0000003aUL -+#define CKK_BLAKE2B_256_HMAC 0x0000003bUL -+#define CKK_BLAKE2B_384_HMAC 0x0000003cUL -+#define CKK_BLAKE2B_512_HMAC 0x0000003dUL -+#define CKK_SALSA20 0x0000003eUL -+#define CKK_X2RATCHET 0x0000003fUL -+#define CKK_EC_EDWARDS 0x00000040UL -+#define CKK_EC_MONTGOMERY 0x00000041UL -+#define CKK_HKDF 0x00000042UL -+#define CKK_SHA512_224_HMAC 0x00000043UL -+#define CKK_SHA512_256_HMAC 0x00000044UL -+#define CKK_SHA512_T_HMAC 0x00000045UL - -+#define CKK_VENDOR_DEFINED 0x80000000UL - - /* CK_CERTIFICATE_TYPE is a value that identifies a certificate -- * type -- */ --typedef CK_ULONG CK_CERTIFICATE_TYPE; -- --#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL --#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL --#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL --#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL -- --#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL --#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL --#define CK_SECURITY_DOMAIN_OPERATOR 2UL --#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL -- -+ * type */ -+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG -+ * for v2.0 */ -+typedef CK_ULONG CK_CERTIFICATE_TYPE; - - /* The following certificate types are defined: */ --#define CKC_X_509 0x00000000UL --#define CKC_X_509_ATTR_CERT 0x00000001UL --#define CKC_WTLS 0x00000002UL --#define CKC_VENDOR_DEFINED 0x80000000UL -- -+/* CKC_X_509_ATTR_CERT is new for v2.10 */ -+/* CKC_WTLS is new for v2.20 */ -+#define CKC_X_509 0x00000000UL -+#define CKC_X_509_ATTR_CERT 0x00000001UL -+#define CKC_WTLS 0x00000002UL -+#define CKC_VENDOR_DEFINED 0x80000000UL - - /* CK_ATTRIBUTE_TYPE is a value that identifies an attribute -- * type -- */ --typedef CK_ULONG CK_ATTRIBUTE_TYPE; -+ * type */ -+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+typedef CK_ULONG CK_ATTRIBUTE_TYPE; - --/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which -- * consists of an array of values. -- */ --#define CKF_ARRAY_ATTRIBUTE 0x40000000UL -+/* values for CKA_CERTIFICATE_CATEGORY v2.20 */ -+typedef CK_ULONG CK_CERTIFICATE_CATEGORY; -+#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL -+#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL -+#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL -+#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL - --/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */ --#define CK_OTP_FORMAT_DECIMAL 0UL --#define CK_OTP_FORMAT_HEXADECIMAL 1UL --#define CK_OTP_FORMAT_ALPHANUMERIC 2UL --#define CK_OTP_FORMAT_BINARY 3UL -+/* values for CKA_JAVA_MIDP_SECURITY_DOMAIN v2.20 */ -+typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; -+#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL -+#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL -+#define CK_SECURITY_DOMAIN_OPERATOR 2UL -+#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL -+ -+/* values for CKA_OTP_FORMAT */ -+#define CK_OTP_FORMAT_DECIMAL 0UL -+#define CK_OTP_FORMAT_HEXADECIMAL 1UL -+#define CK_OTP_FORMAT_ALPHANUMERIC 2UL -+#define CK_OTP_FORMAT_BINARY 3UL -+ -+/* values for CKA_OTP_CHALLENGE_REQUIREMENT, CKA_OTP_TIME_REQUIREMENT, -+ * CKA_OTP_COUNTER_REQUIREMENT, CKA_OTP_PIN_REQUIREMENT */ -+#define CK_OTP_PARAM_IGNORED 0UL -+#define CK_OTP_PARAM_OPTIONAL 1UL -+#define CK_OTP_PARAM_MANDATORY 2UL - --/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT -- * attributes -- */ --#define CK_OTP_PARAM_IGNORED 0UL --#define CK_OTP_PARAM_OPTIONAL 1UL --#define CK_OTP_PARAM_MANDATORY 2UL -+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which -+ consists of an array of values. */ -+#define CKF_ARRAY_ATTRIBUTE 0x40000000UL - - /* The following attribute types are defined: */ --#define CKA_CLASS 0x00000000UL --#define CKA_TOKEN 0x00000001UL --#define CKA_PRIVATE 0x00000002UL --#define CKA_LABEL 0x00000003UL --#define CKA_UNIQUE_ID 0x00000004UL --#define CKA_APPLICATION 0x00000010UL --#define CKA_VALUE 0x00000011UL --#define CKA_OBJECT_ID 0x00000012UL --#define CKA_CERTIFICATE_TYPE 0x00000080UL --#define CKA_ISSUER 0x00000081UL --#define CKA_SERIAL_NUMBER 0x00000082UL --#define CKA_AC_ISSUER 0x00000083UL --#define CKA_OWNER 0x00000084UL --#define CKA_ATTR_TYPES 0x00000085UL --#define CKA_TRUSTED 0x00000086UL --#define CKA_CERTIFICATE_CATEGORY 0x00000087UL --#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL --#define CKA_URL 0x00000089UL --#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL --#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL --#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL --#define CKA_CHECK_VALUE 0x00000090UL -- --#define CKA_KEY_TYPE 0x00000100UL --#define CKA_SUBJECT 0x00000101UL --#define CKA_ID 0x00000102UL --#define CKA_SENSITIVE 0x00000103UL --#define CKA_ENCRYPT 0x00000104UL --#define CKA_DECRYPT 0x00000105UL --#define CKA_WRAP 0x00000106UL --#define CKA_UNWRAP 0x00000107UL --#define CKA_SIGN 0x00000108UL --#define CKA_SIGN_RECOVER 0x00000109UL --#define CKA_VERIFY 0x0000010AUL --#define CKA_VERIFY_RECOVER 0x0000010BUL --#define CKA_DERIVE 0x0000010CUL --#define CKA_START_DATE 0x00000110UL --#define CKA_END_DATE 0x00000111UL --#define CKA_MODULUS 0x00000120UL --#define CKA_MODULUS_BITS 0x00000121UL --#define CKA_PUBLIC_EXPONENT 0x00000122UL --#define CKA_PRIVATE_EXPONENT 0x00000123UL --#define CKA_PRIME_1 0x00000124UL --#define CKA_PRIME_2 0x00000125UL --#define CKA_EXPONENT_1 0x00000126UL --#define CKA_EXPONENT_2 0x00000127UL --#define CKA_COEFFICIENT 0x00000128UL --#define CKA_PUBLIC_KEY_INFO 0x00000129UL --#define CKA_PRIME 0x00000130UL --#define CKA_SUBPRIME 0x00000131UL --#define CKA_BASE 0x00000132UL -- --#define CKA_PRIME_BITS 0x00000133UL --#define CKA_SUBPRIME_BITS 0x00000134UL --#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS -- --#define CKA_VALUE_BITS 0x00000160UL --#define CKA_VALUE_LEN 0x00000161UL --#define CKA_EXTRACTABLE 0x00000162UL --#define CKA_LOCAL 0x00000163UL --#define CKA_NEVER_EXTRACTABLE 0x00000164UL --#define CKA_ALWAYS_SENSITIVE 0x00000165UL --#define CKA_KEY_GEN_MECHANISM 0x00000166UL -- --#define CKA_MODIFIABLE 0x00000170UL --#define CKA_COPYABLE 0x00000171UL -- --#define CKA_DESTROYABLE 0x00000172UL -- --#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */ --#define CKA_EC_PARAMS 0x00000180UL -- --#define CKA_EC_POINT 0x00000181UL -- --#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */ --#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */ -- --#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL -- --#define CKA_WRAP_WITH_TRUSTED 0x00000210UL --#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL) --#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL) --#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL) -- --#define CKA_OTP_FORMAT 0x00000220UL --#define CKA_OTP_LENGTH 0x00000221UL --#define CKA_OTP_TIME_INTERVAL 0x00000222UL --#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL -+#define CKA_CLASS 0x00000000UL -+#define CKA_TOKEN 0x00000001UL -+#define CKA_PRIVATE 0x00000002UL -+#define CKA_LABEL 0x00000003UL -+#define CKA_APPLICATION 0x00000010UL -+#define CKA_VALUE 0x00000011UL -+ -+/* CKA_OBJECT_ID is new for v2.10 */ -+#define CKA_OBJECT_ID 0x00000012UL -+ -+#define CKA_CERTIFICATE_TYPE 0x00000080UL -+#define CKA_ISSUER 0x00000081UL -+#define CKA_SERIAL_NUMBER 0x00000082UL -+ -+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new -+ * for v2.10 */ -+#define CKA_AC_ISSUER 0x00000083UL -+#define CKA_OWNER 0x00000084UL -+#define CKA_ATTR_TYPES 0x00000085UL -+ -+/* CKA_TRUSTED is new for v2.11 */ -+#define CKA_TRUSTED 0x00000086UL -+ -+/* CKA_CERTIFICATE_CATEGORY ... -+ * CKA_CHECK_VALUE are new for v2.20 */ -+#define CKA_CERTIFICATE_CATEGORY 0x00000087UL -+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL -+#define CKA_URL 0x00000089UL -+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL -+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL -+#define CKA_CHECK_VALUE 0x00000090UL -+ -+#define CKA_KEY_TYPE 0x00000100UL -+#define CKA_SUBJECT 0x00000101UL -+#define CKA_ID 0x00000102UL -+#define CKA_SENSITIVE 0x00000103UL -+#define CKA_ENCRYPT 0x00000104UL -+#define CKA_DECRYPT 0x00000105UL -+#define CKA_WRAP 0x00000106UL -+#define CKA_UNWRAP 0x00000107UL -+#define CKA_SIGN 0x00000108UL -+#define CKA_SIGN_RECOVER 0x00000109UL -+#define CKA_VERIFY 0x0000010AUL -+#define CKA_VERIFY_RECOVER 0x0000010BUL -+#define CKA_DERIVE 0x0000010CUL -+#define CKA_START_DATE 0x00000110UL -+#define CKA_END_DATE 0x00000111UL -+#define CKA_MODULUS 0x00000120UL -+#define CKA_MODULUS_BITS 0x00000121UL -+#define CKA_PUBLIC_EXPONENT 0x00000122UL -+#define CKA_PRIVATE_EXPONENT 0x00000123UL -+#define CKA_PRIME_1 0x00000124UL -+#define CKA_PRIME_2 0x00000125UL -+#define CKA_EXPONENT_1 0x00000126UL -+#define CKA_EXPONENT_2 0x00000127UL -+#define CKA_COEFFICIENT 0x00000128UL -+/* CKA_PUBLIC_KEY_INFO is new for v2.40 */ -+#define CKA_PUBLIC_KEY_INFO 0x00000129UL -+#define CKA_PRIME 0x00000130UL -+#define CKA_SUBPRIME 0x00000131UL -+#define CKA_BASE 0x00000132UL -+ -+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */ -+#define CKA_PRIME_BITS 0x00000133UL -+#define CKA_SUBPRIME_BITS 0x00000134UL -+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS -+/* (To retain backwards-compatibility) */ -+ -+#define CKA_VALUE_BITS 0x00000160UL -+#define CKA_VALUE_LEN 0x00000161UL -+ -+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, -+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS, -+ * and CKA_EC_POINT are new for v2.0 */ -+#define CKA_EXTRACTABLE 0x00000162UL -+#define CKA_LOCAL 0x00000163UL -+#define CKA_NEVER_EXTRACTABLE 0x00000164UL -+#define CKA_ALWAYS_SENSITIVE 0x00000165UL -+ -+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */ -+#define CKA_KEY_GEN_MECHANISM 0x00000166UL -+ -+#define CKA_MODIFIABLE 0x00000170UL -+ -+/* New for 2.40 */ -+#define CKA_COPYABLE 0x00000171UL -+#define CKA_DESTROYABLE 0x00000172UL -+ -+/* CKA_ECDSA_PARAMS is deprecated in v2.11, -+ * CKA_EC_PARAMS is preferred. */ -+#define CKA_ECDSA_PARAMS 0x00000180UL -+#define CKA_EC_PARAMS 0x00000180UL -+ -+#define CKA_EC_POINT 0x00000181UL -+ -+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, -+ * are new for v2.10. Deprecated in v2.11 and onwards. */ -+#define CKA_SECONDARY_AUTH 0x00000200UL -+#define CKA_AUTH_PIN_FLAGS 0x00000201UL -+ -+/* CKA_ALWAYS_AUTHENTICATE ... -+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */ -+#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL -+ -+#define CKA_WRAP_WITH_TRUSTED 0x00000210UL -+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x00000211UL) -+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x00000212UL) -+ -+/* new for 2.40 */ -+#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x00000213UL) -+#define CKA_OTP_FORMAT 0x00000220UL -+#define CKA_OTP_LENGTH 0x00000221UL -+#define CKA_OTP_TIME_INTERVAL 0x00000222UL -+#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL - #define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL --#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL --#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL --#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL --#define CKA_OTP_COUNTER 0x0000022EUL --#define CKA_OTP_TIME 0x0000022FUL --#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL --#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL --#define CKA_OTP_SERVICE_LOGO 0x0000022CUL --#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL -- --#define CKA_GOSTR3410_PARAMS 0x00000250UL --#define CKA_GOSTR3411_PARAMS 0x00000251UL --#define CKA_GOST28147_PARAMS 0x00000252UL -- --#define CKA_HW_FEATURE_TYPE 0x00000300UL --#define CKA_RESET_ON_INIT 0x00000301UL --#define CKA_HAS_RESET 0x00000302UL -- --#define CKA_PIXEL_X 0x00000400UL --#define CKA_PIXEL_Y 0x00000401UL --#define CKA_RESOLUTION 0x00000402UL --#define CKA_CHAR_ROWS 0x00000403UL --#define CKA_CHAR_COLUMNS 0x00000404UL --#define CKA_COLOR 0x00000405UL --#define CKA_BITS_PER_PIXEL 0x00000406UL --#define CKA_CHAR_SETS 0x00000480UL --#define CKA_ENCODING_METHODS 0x00000481UL --#define CKA_MIME_TYPES 0x00000482UL --#define CKA_MECHANISM_TYPE 0x00000500UL --#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL --#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL --#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL --#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL) --#define CKA_PROFILE_ID 0x00000601UL --#define CKA_X2RATCHET_BAG 0x00000602UL --#define CKA_X2RATCHET_BAGSIZE 0x00000603UL --#define CKA_X2RATCHET_BOBS1STMSG 0x00000604UL --#define CKA_X2RATCHET_CKR 0x00000605UL --#define CKA_X2RATCHET_CKS 0x00000606UL --#define CKA_X2RATCHET_DHP 0x00000607UL --#define CKA_X2RATCHET_DHR 0x00000608UL --#define CKA_X2RATCHET_DHS 0x00000609UL --#define CKA_X2RATCHET_HKR 0x0000060aUL --#define CKA_X2RATCHET_HKS 0x0000060bUL --#define CKA_X2RATCHET_ISALICE 0x0000060cUL --#define CKA_X2RATCHET_NHKR 0x0000060dUL --#define CKA_X2RATCHET_NHKS 0x0000060eUL --#define CKA_X2RATCHET_NR 0x0000060fUL --#define CKA_X2RATCHET_NS 0x00000610UL --#define CKA_X2RATCHET_PNS 0x00000611UL --#define CKA_X2RATCHET_RK 0x00000612UL -+#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL -+#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL -+#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL -+#define CKA_OTP_COUNTER 0x0000022EUL -+#define CKA_OTP_TIME 0x0000022FUL -+#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL -+#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL -+#define CKA_OTP_SERVICE_LOGO 0x0000022CUL -+#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL -+#define CKA_GOSTR3410_PARAMS 0x00000250UL -+#define CKA_GOSTR3411_PARAMS 0x00000251UL -+#define CKA_GOST28147_PARAMS 0x00000252UL -+ -+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET -+ * are new for v2.10 */ -+#define CKA_HW_FEATURE_TYPE 0x00000300UL -+#define CKA_RESET_ON_INIT 0x00000301UL -+#define CKA_HAS_RESET 0x00000302UL -+ -+/* The following attributes are new for v2.20 */ -+#define CKA_PIXEL_X 0x00000400UL -+#define CKA_PIXEL_Y 0x00000401UL -+#define CKA_RESOLUTION 0x00000402UL -+#define CKA_CHAR_ROWS 0x00000403UL -+#define CKA_CHAR_COLUMNS 0x00000404UL -+#define CKA_COLOR 0x00000405UL -+#define CKA_BITS_PER_PIXEL 0x00000406UL -+#define CKA_CHAR_SETS 0x00000480UL -+#define CKA_ENCODING_METHODS 0x00000481UL -+#define CKA_MIME_TYPES 0x00000482UL -+#define CKA_MECHANISM_TYPE 0x00000500UL -+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL -+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL -+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL -+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x00000600UL) -+ -+/* new for v3.0 */ -+#define CKA_PROFILE_ID 0x00000601UL -+#define CKA_X2RATCHET_BAG 0x00000602UL -+#define CKA_X2RATCHET_BAGSIZE 0x00000603UL -+#define CKA_X2RATCHET_BOBS1STMSG 0x00000604UL -+#define CKA_X2RATCHET_CKR 0x00000605UL -+#define CKA_X2RATCHET_CKS 0x00000606UL -+#define CKA_X2RATCHET_DHP 0x00000607UL -+#define CKA_X2RATCHET_DHR 0x00000608UL -+#define CKA_X2RATCHET_DHS 0x00000609UL -+#define CKA_X2RATCHET_HKR 0x0000060aUL -+#define CKA_X2RATCHET_HKS 0x0000060bUL -+#define CKA_X2RATCHET_ISALICE 0x0000060cUL -+#define CKA_X2RATCHET_NHKR 0x0000060dUL -+#define CKA_X2RATCHET_NHKS 0x0000060eUL -+#define CKA_X2RATCHET_NR 0x0000060fUL -+#define CKA_X2RATCHET_NS 0x00000610UL -+#define CKA_X2RATCHET_PNS 0x00000611UL -+#define CKA_X2RATCHET_RK 0x00000612UL - --#define CKA_VENDOR_DEFINED 0x80000000UL -+#define CKA_VENDOR_DEFINED 0x80000000UL - - /* CK_ATTRIBUTE is a structure that includes the type, length -- * and value of an attribute -- */ -+ * and value of an attribute */ - typedef struct CK_ATTRIBUTE { - CK_ATTRIBUTE_TYPE type; -- CK_VOID_PTR pValue; -- CK_ULONG ulValueLen; /* in bytes */ -+ CK_VOID_PTR pValue; -+ -+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ -+ CK_ULONG ulValueLen; /* in bytes */ - } CK_ATTRIBUTE; - - typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; - - /* CK_DATE is a structure that defines a date */ --typedef struct CK_DATE{ -- CK_CHAR year[4]; /* the year ("1900" - "9999") */ -- CK_CHAR month[2]; /* the month ("01" - "12") */ -- CK_CHAR day[2]; /* the day ("01" - "31") */ -+typedef struct CK_DATE { -+ CK_CHAR year[4]; /* the year ("1900" - "9999") */ -+ CK_CHAR month[2]; /* the month ("01" - "12") */ -+ CK_CHAR day[2]; /* the day ("01" - "31") */ - } CK_DATE; - -- - /* CK_MECHANISM_TYPE is a value that identifies a mechanism -- * type -- */ --typedef CK_ULONG CK_MECHANISM_TYPE; -+ * type */ -+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+typedef CK_ULONG CK_MECHANISM_TYPE; - - /* the following mechanism types are defined: */ --#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL --#define CKM_RSA_PKCS 0x00000001UL --#define CKM_RSA_9796 0x00000002UL --#define CKM_RSA_X_509 0x00000003UL -- --#define CKM_MD2_RSA_PKCS 0x00000004UL --#define CKM_MD5_RSA_PKCS 0x00000005UL --#define CKM_SHA1_RSA_PKCS 0x00000006UL -- --#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL --#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL --#define CKM_RSA_PKCS_OAEP 0x00000009UL -- --#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL --#define CKM_RSA_X9_31 0x0000000BUL --#define CKM_SHA1_RSA_X9_31 0x0000000CUL --#define CKM_RSA_PKCS_PSS 0x0000000DUL --#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL -- --#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL --#define CKM_DSA 0x00000011UL --#define CKM_DSA_SHA1 0x00000012UL --#define CKM_DSA_SHA224 0x00000013UL --#define CKM_DSA_SHA256 0x00000014UL --#define CKM_DSA_SHA384 0x00000015UL --#define CKM_DSA_SHA512 0x00000016UL --#define CKM_DSA_SHA3_224 0x00000018UL --#define CKM_DSA_SHA3_256 0x00000019UL --#define CKM_DSA_SHA3_384 0x0000001AUL --#define CKM_DSA_SHA3_512 0x0000001BUL -- --#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL --#define CKM_DH_PKCS_DERIVE 0x00000021UL -- --#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL --#define CKM_X9_42_DH_DERIVE 0x00000031UL --#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL --#define CKM_X9_42_MQV_DERIVE 0x00000033UL -- --#define CKM_SHA256_RSA_PKCS 0x00000040UL --#define CKM_SHA384_RSA_PKCS 0x00000041UL --#define CKM_SHA512_RSA_PKCS 0x00000042UL --#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL --#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL --#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL -- --#define CKM_SHA224_RSA_PKCS 0x00000046UL --#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL -- --#define CKM_SHA512_224 0x00000048UL --#define CKM_SHA512_224_HMAC 0x00000049UL --#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL --#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL --#define CKM_SHA512_256 0x0000004CUL --#define CKM_SHA512_256_HMAC 0x0000004DUL --#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL --#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL -- --#define CKM_SHA512_T 0x00000050UL --#define CKM_SHA512_T_HMAC 0x00000051UL --#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL --#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL -- --#define CKM_SHA3_256_RSA_PKCS 0x00000060UL --#define CKM_SHA3_384_RSA_PKCS 0x00000061UL --#define CKM_SHA3_512_RSA_PKCS 0x00000062UL --#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL --#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL --#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL --#define CKM_SHA3_224_RSA_PKCS 0x00000066UL --#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL -- --#define CKM_RC2_KEY_GEN 0x00000100UL --#define CKM_RC2_ECB 0x00000101UL --#define CKM_RC2_CBC 0x00000102UL --#define CKM_RC2_MAC 0x00000103UL -- --#define CKM_RC2_MAC_GENERAL 0x00000104UL --#define CKM_RC2_CBC_PAD 0x00000105UL -- --#define CKM_RC4_KEY_GEN 0x00000110UL --#define CKM_RC4 0x00000111UL --#define CKM_DES_KEY_GEN 0x00000120UL --#define CKM_DES_ECB 0x00000121UL --#define CKM_DES_CBC 0x00000122UL --#define CKM_DES_MAC 0x00000123UL -- --#define CKM_DES_MAC_GENERAL 0x00000124UL --#define CKM_DES_CBC_PAD 0x00000125UL -- --#define CKM_DES2_KEY_GEN 0x00000130UL --#define CKM_DES3_KEY_GEN 0x00000131UL --#define CKM_DES3_ECB 0x00000132UL --#define CKM_DES3_CBC 0x00000133UL --#define CKM_DES3_MAC 0x00000134UL -- --#define CKM_DES3_MAC_GENERAL 0x00000135UL --#define CKM_DES3_CBC_PAD 0x00000136UL --#define CKM_DES3_CMAC_GENERAL 0x00000137UL --#define CKM_DES3_CMAC 0x00000138UL --#define CKM_CDMF_KEY_GEN 0x00000140UL --#define CKM_CDMF_ECB 0x00000141UL --#define CKM_CDMF_CBC 0x00000142UL --#define CKM_CDMF_MAC 0x00000143UL --#define CKM_CDMF_MAC_GENERAL 0x00000144UL --#define CKM_CDMF_CBC_PAD 0x00000145UL -- --#define CKM_DES_OFB64 0x00000150UL --#define CKM_DES_OFB8 0x00000151UL --#define CKM_DES_CFB64 0x00000152UL --#define CKM_DES_CFB8 0x00000153UL -- --#define CKM_MD2 0x00000200UL -- --#define CKM_MD2_HMAC 0x00000201UL --#define CKM_MD2_HMAC_GENERAL 0x00000202UL -- --#define CKM_MD5 0x00000210UL -- --#define CKM_MD5_HMAC 0x00000211UL --#define CKM_MD5_HMAC_GENERAL 0x00000212UL -- --#define CKM_SHA_1 0x00000220UL -- --#define CKM_SHA_1_HMAC 0x00000221UL --#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL -- --#define CKM_RIPEMD128 0x00000230UL --#define CKM_RIPEMD128_HMAC 0x00000231UL --#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL --#define CKM_RIPEMD160 0x00000240UL --#define CKM_RIPEMD160_HMAC 0x00000241UL --#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL -- --#define CKM_SHA256 0x00000250UL --#define CKM_SHA256_HMAC 0x00000251UL --#define CKM_SHA256_HMAC_GENERAL 0x00000252UL --#define CKM_SHA224 0x00000255UL --#define CKM_SHA224_HMAC 0x00000256UL --#define CKM_SHA224_HMAC_GENERAL 0x00000257UL --#define CKM_SHA384 0x00000260UL --#define CKM_SHA384_HMAC 0x00000261UL --#define CKM_SHA384_HMAC_GENERAL 0x00000262UL --#define CKM_SHA512 0x00000270UL --#define CKM_SHA512_HMAC 0x00000271UL --#define CKM_SHA512_HMAC_GENERAL 0x00000272UL --#define CKM_SECURID_KEY_GEN 0x00000280UL --#define CKM_SECURID 0x00000282UL --#define CKM_HOTP_KEY_GEN 0x00000290UL --#define CKM_HOTP 0x00000291UL --#define CKM_ACTI 0x000002A0UL --#define CKM_ACTI_KEY_GEN 0x000002A1UL -- --#define CKM_SHA3_256 0x000002B0UL --#define CKM_SHA3_256_HMAC 0x000002B1UL --#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL --#define CKM_SHA3_256_KEY_GEN 0x000002B3UL --#define CKM_SHA3_224 0x000002B5UL --#define CKM_SHA3_224_HMAC 0x000002B6UL --#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL --#define CKM_SHA3_224_KEY_GEN 0x000002B8UL --#define CKM_SHA3_384 0x000002C0UL --#define CKM_SHA3_384_HMAC 0x000002C1UL --#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL --#define CKM_SHA3_384_KEY_GEN 0x000002C3UL --#define CKM_SHA3_512 0x000002D0UL --#define CKM_SHA3_512_HMAC 0x000002D1UL --#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL --#define CKM_SHA3_512_KEY_GEN 0x000002D3UL -- -- --#define CKM_CAST_KEY_GEN 0x00000300UL --#define CKM_CAST_ECB 0x00000301UL --#define CKM_CAST_CBC 0x00000302UL --#define CKM_CAST_MAC 0x00000303UL --#define CKM_CAST_MAC_GENERAL 0x00000304UL --#define CKM_CAST_CBC_PAD 0x00000305UL --#define CKM_CAST3_KEY_GEN 0x00000310UL --#define CKM_CAST3_ECB 0x00000311UL --#define CKM_CAST3_CBC 0x00000312UL --#define CKM_CAST3_MAC 0x00000313UL --#define CKM_CAST3_MAC_GENERAL 0x00000314UL --#define CKM_CAST3_CBC_PAD 0x00000315UL -+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL -+#define CKM_RSA_PKCS 0x00000001UL -+#define CKM_RSA_9796 0x00000002UL -+#define CKM_RSA_X_509 0x00000003UL -+ -+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS -+ * are new for v2.0. They are mechanisms which hash and sign */ -+#define CKM_MD2_RSA_PKCS 0x00000004UL -+#define CKM_MD5_RSA_PKCS 0x00000005UL -+#define CKM_SHA1_RSA_PKCS 0x00000006UL -+ -+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and -+ * CKM_RSA_PKCS_OAEP are new for v2.10 */ -+#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL -+#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL -+#define CKM_RSA_PKCS_OAEP 0x00000009UL -+ -+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31, -+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */ -+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL -+#define CKM_RSA_X9_31 0x0000000BUL -+#define CKM_SHA1_RSA_X9_31 0x0000000CUL -+#define CKM_RSA_PKCS_PSS 0x0000000DUL -+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL -+ -+#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL -+#define CKM_DSA 0x00000011UL -+#define CKM_DSA_SHA1 0x00000012UL -+ -+/* new for v2.40 */ -+#define CKM_DSA_SHA224 0x00000013UL -+#define CKM_DSA_SHA256 0x00000014UL -+#define CKM_DSA_SHA384 0x00000015UL -+#define CKM_DSA_SHA512 0x00000016UL -+#define CKM_DSA_SHA3_224 0x00000018UL -+#define CKM_DSA_SHA3_256 0x00000019UL -+#define CKM_DSA_SHA3_384 0x0000001AUL -+#define CKM_DSA_SHA3_512 0x0000001BUL -+ -+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL -+#define CKM_DH_PKCS_DERIVE 0x00000021UL -+ -+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE, -+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for -+ * v2.11 */ -+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL -+#define CKM_X9_42_DH_DERIVE 0x00000031UL -+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL -+#define CKM_X9_42_MQV_DERIVE 0x00000033UL -+ -+/* CKM_SHA256/384/512 are new for v2.20 */ -+#define CKM_SHA256_RSA_PKCS 0x00000040UL -+#define CKM_SHA384_RSA_PKCS 0x00000041UL -+#define CKM_SHA512_RSA_PKCS 0x00000042UL -+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL -+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL -+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL -+ -+/* CKM_SHA224 new for v2.20 amendment 3 */ -+#define CKM_SHA224_RSA_PKCS 0x00000046UL -+#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL -+ -+/* new for v2.40 */ -+#define CKM_SHA512_224 0x00000048UL -+#define CKM_SHA512_224_HMAC 0x00000049UL -+#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL -+#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL -+#define CKM_SHA512_256 0x0000004CUL -+#define CKM_SHA512_256_HMAC 0x0000004DUL -+#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL -+#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL -+#define CKM_SHA512_T 0x00000050UL -+#define CKM_SHA512_T_HMAC 0x00000051UL -+#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL -+#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL -+#define CKM_SHA3_256_RSA_PKCS 0x00000060UL -+#define CKM_SHA3_384_RSA_PKCS 0x00000061UL -+#define CKM_SHA3_512_RSA_PKCS 0x00000062UL -+#define CKM_SHA3_256_RSA_PKCS_PSS 0x00000063UL -+#define CKM_SHA3_384_RSA_PKCS_PSS 0x00000064UL -+#define CKM_SHA3_512_RSA_PKCS_PSS 0x00000065UL -+#define CKM_SHA3_224_RSA_PKCS 0x00000066UL -+#define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL -+ -+#define CKM_RC2_KEY_GEN 0x00000100UL -+#define CKM_RC2_ECB 0x00000101UL -+#define CKM_RC2_CBC 0x00000102UL -+#define CKM_RC2_MAC 0x00000103UL -+ -+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ -+#define CKM_RC2_MAC_GENERAL 0x00000104UL -+#define CKM_RC2_CBC_PAD 0x00000105UL -+ -+#define CKM_RC4_KEY_GEN 0x00000110UL -+#define CKM_RC4 0x00000111UL -+#define CKM_DES_KEY_GEN 0x00000120UL -+#define CKM_DES_ECB 0x00000121UL -+#define CKM_DES_CBC 0x00000122UL -+#define CKM_DES_MAC 0x00000123UL -+ -+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ -+#define CKM_DES_MAC_GENERAL 0x00000124UL -+#define CKM_DES_CBC_PAD 0x00000125UL -+ -+#define CKM_DES2_KEY_GEN 0x00000130UL -+#define CKM_DES3_KEY_GEN 0x00000131UL -+#define CKM_DES3_ECB 0x00000132UL -+#define CKM_DES3_CBC 0x00000133UL -+#define CKM_DES3_MAC 0x00000134UL -+ -+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, -+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, -+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */ -+#define CKM_DES3_MAC_GENERAL 0x00000135UL -+#define CKM_DES3_CBC_PAD 0x00000136UL -+#define CKM_CDMF_KEY_GEN 0x00000140UL -+#define CKM_CDMF_ECB 0x00000141UL -+#define CKM_CDMF_CBC 0x00000142UL -+#define CKM_CDMF_MAC 0x00000143UL -+#define CKM_CDMF_MAC_GENERAL 0x00000144UL -+#define CKM_CDMF_CBC_PAD 0x00000145UL -+ -+/* the following four DES mechanisms are new for v2.20 */ -+#define CKM_DES_OFB64 0x00000150UL -+#define CKM_DES_OFB8 0x00000151UL -+#define CKM_DES_CFB64 0x00000152UL -+#define CKM_DES_CFB8 0x00000153UL -+ -+#define CKM_MD2 0x00000200UL -+ -+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ -+#define CKM_MD2_HMAC 0x00000201UL -+#define CKM_MD2_HMAC_GENERAL 0x00000202UL -+ -+#define CKM_MD5 0x00000210UL -+ -+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ -+#define CKM_MD5_HMAC 0x00000211UL -+#define CKM_MD5_HMAC_GENERAL 0x00000212UL -+ -+#define CKM_SHA_1 0x00000220UL -+ -+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ -+#define CKM_SHA_1_HMAC 0x00000221UL -+#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL -+ -+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC, -+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC, -+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */ -+#define CKM_RIPEMD128 0x00000230UL -+#define CKM_RIPEMD128_HMAC 0x00000231UL -+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL -+#define CKM_RIPEMD160 0x00000240UL -+#define CKM_RIPEMD160_HMAC 0x00000241UL -+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL -+ -+/* CKM_SHA256/384/512 are new for v2.20 */ -+#define CKM_SHA256 0x00000250UL -+#define CKM_SHA256_HMAC 0x00000251UL -+#define CKM_SHA256_HMAC_GENERAL 0x00000252UL -+#define CKM_SHA384 0x00000260UL -+#define CKM_SHA384_HMAC 0x00000261UL -+#define CKM_SHA384_HMAC_GENERAL 0x00000262UL -+#define CKM_SHA512 0x00000270UL -+#define CKM_SHA512_HMAC 0x00000271UL -+#define CKM_SHA512_HMAC_GENERAL 0x00000272UL -+ -+/* CKM_SHA224 new for v2.20 amendment 3 */ -+#define CKM_SHA224 0x00000255UL -+#define CKM_SHA224_HMAC 0x00000256UL -+#define CKM_SHA224_HMAC_GENERAL 0x00000257UL -+ -+/* new for v2.40 */ -+#define CKM_SECURID_KEY_GEN 0x00000280UL -+#define CKM_SECURID 0x00000282UL -+#define CKM_HOTP_KEY_GEN 0x00000290UL -+#define CKM_HOTP 0x00000291UL -+#define CKM_ACTI 0x000002A0UL -+#define CKM_ACTI_KEY_GEN 0x000002A1UL -+#define CKM_SHA3_256 0x000002B0UL -+#define CKM_SHA3_256_HMAC 0x000002B1UL -+#define CKM_SHA3_256_HMAC_GENERAL 0x000002B2UL -+#define CKM_SHA3_256_KEY_GEN 0x000002B3UL -+#define CKM_SHA3_224 0x000002B5UL -+#define CKM_SHA3_224_HMAC 0x000002B6UL -+#define CKM_SHA3_224_HMAC_GENERAL 0x000002B7UL -+#define CKM_SHA3_224_KEY_GEN 0x000002B8UL -+#define CKM_SHA3_384 0x000002C0UL -+#define CKM_SHA3_384_HMAC 0x000002C1UL -+#define CKM_SHA3_384_HMAC_GENERAL 0x000002C2UL -+#define CKM_SHA3_384_KEY_GEN 0x000002C3UL -+#define CKM_SHA3_512 0x000002D0UL -+#define CKM_SHA3_512_HMAC 0x000002D1UL -+#define CKM_SHA3_512_HMAC_GENERAL 0x000002D2UL -+#define CKM_SHA3_512_KEY_GEN 0x000002D3UL -+ -+/* All of the following mechanisms are new for v2.0 */ - /* Note that CAST128 and CAST5 are the same algorithm */ --#define CKM_CAST5_KEY_GEN 0x00000320UL --#define CKM_CAST128_KEY_GEN 0x00000320UL --#define CKM_CAST5_ECB 0x00000321UL --#define CKM_CAST128_ECB 0x00000321UL --#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */ --#define CKM_CAST128_CBC 0x00000322UL --#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */ --#define CKM_CAST128_MAC 0x00000323UL --#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */ --#define CKM_CAST128_MAC_GENERAL 0x00000324UL --#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */ --#define CKM_CAST128_CBC_PAD 0x00000325UL --#define CKM_RC5_KEY_GEN 0x00000330UL --#define CKM_RC5_ECB 0x00000331UL --#define CKM_RC5_CBC 0x00000332UL --#define CKM_RC5_MAC 0x00000333UL --#define CKM_RC5_MAC_GENERAL 0x00000334UL --#define CKM_RC5_CBC_PAD 0x00000335UL --#define CKM_IDEA_KEY_GEN 0x00000340UL --#define CKM_IDEA_ECB 0x00000341UL --#define CKM_IDEA_CBC 0x00000342UL --#define CKM_IDEA_MAC 0x00000343UL --#define CKM_IDEA_MAC_GENERAL 0x00000344UL --#define CKM_IDEA_CBC_PAD 0x00000345UL --#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL --#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL --#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL --#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL --#define CKM_XOR_BASE_AND_DATA 0x00000364UL --#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL --#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL --#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL --#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL -- --#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL --#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL --#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL --#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL --#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL -- --#define CKM_TLS_PRF 0x00000378UL -- --#define CKM_SSL3_MD5_MAC 0x00000380UL --#define CKM_SSL3_SHA1_MAC 0x00000381UL --#define CKM_MD5_KEY_DERIVATION 0x00000390UL --#define CKM_MD2_KEY_DERIVATION 0x00000391UL --#define CKM_SHA1_KEY_DERIVATION 0x00000392UL -- --#define CKM_SHA256_KEY_DERIVATION 0x00000393UL --#define CKM_SHA384_KEY_DERIVATION 0x00000394UL --#define CKM_SHA512_KEY_DERIVATION 0x00000395UL --#define CKM_SHA224_KEY_DERIVATION 0x00000396UL --#define CKM_SHA3_256_KEY_DERIVATION 0x00000397UL --#define CKM_SHA3_224_KEY_DERIVATION 0x00000398UL --#define CKM_SHA3_384_KEY_DERIVATION 0x00000399UL --#define CKM_SHA3_512_KEY_DERIVATION 0x0000039AUL --#define CKM_SHAKE_128_KEY_DERIVATION 0x0000039BUL --#define CKM_SHAKE_256_KEY_DERIVATION 0x0000039CUL --#define CKM_SHA3_256_KEY_DERIVE CKM_SHA3_256_KEY_DERIVATION --#define CKM_SHA3_224_KEY_DERIVE CKM_SHA3_224_KEY_DERIVATION --#define CKM_SHA3_384_KEY_DERIVE CKM_SHA3_384_KEY_DERIVATION --#define CKM_SHA3_512_KEY_DERIVE CKM_SHA3_512_KEY_DERIVATION --#define CKM_SHAKE_128_KEY_DERIVE CKM_SHAKE_128_KEY_DERIVATION --#define CKM_SHAKE_256_KEY_DERIVE CKM_SHAKE_256_KEY_DERIVATION -- --#define CKM_PBE_MD2_DES_CBC 0x000003A0UL --#define CKM_PBE_MD5_DES_CBC 0x000003A1UL --#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL --#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL --#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */ --#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL --#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */ --#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL --#define CKM_PBE_SHA1_RC4_128 0x000003A6UL --#define CKM_PBE_SHA1_RC4_40 0x000003A7UL --#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL --#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL --#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL --#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL -- --#define CKM_PKCS5_PBKD2 0x000003B0UL -- --#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL -- --#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL --#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL --#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL --#define CKM_WTLS_PRF 0x000003D3UL --#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL --#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL -- --#define CKM_TLS12_MAC 0x000003D8UL --#define CKM_TLS12_KDF 0x000003D9UL --#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL --#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL --#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL --#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL --#define CKM_TLS_MAC 0x000003E4UL --#define CKM_TLS_KDF 0x000003E5UL -- --#define CKM_KEY_WRAP_LYNKS 0x00000400UL --#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL -- --#define CKM_CMS_SIG 0x00000500UL --#define CKM_KIP_DERIVE 0x00000510UL --#define CKM_KIP_WRAP 0x00000511UL --#define CKM_KIP_MAC 0x00000512UL -- --#define CKM_CAMELLIA_KEY_GEN 0x00000550UL --#define CKM_CAMELLIA_ECB 0x00000551UL --#define CKM_CAMELLIA_CBC 0x00000552UL --#define CKM_CAMELLIA_MAC 0x00000553UL --#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL --#define CKM_CAMELLIA_CBC_PAD 0x00000555UL --#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL --#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL --#define CKM_CAMELLIA_CTR 0x00000558UL -- --#define CKM_ARIA_KEY_GEN 0x00000560UL --#define CKM_ARIA_ECB 0x00000561UL --#define CKM_ARIA_CBC 0x00000562UL --#define CKM_ARIA_MAC 0x00000563UL --#define CKM_ARIA_MAC_GENERAL 0x00000564UL --#define CKM_ARIA_CBC_PAD 0x00000565UL --#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL --#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL -- --#define CKM_SEED_KEY_GEN 0x00000650UL --#define CKM_SEED_ECB 0x00000651UL --#define CKM_SEED_CBC 0x00000652UL --#define CKM_SEED_MAC 0x00000653UL --#define CKM_SEED_MAC_GENERAL 0x00000654UL --#define CKM_SEED_CBC_PAD 0x00000655UL --#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL --#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL -- --#define CKM_SKIPJACK_KEY_GEN 0x00001000UL --#define CKM_SKIPJACK_ECB64 0x00001001UL --#define CKM_SKIPJACK_CBC64 0x00001002UL --#define CKM_SKIPJACK_OFB64 0x00001003UL --#define CKM_SKIPJACK_CFB64 0x00001004UL --#define CKM_SKIPJACK_CFB32 0x00001005UL --#define CKM_SKIPJACK_CFB16 0x00001006UL --#define CKM_SKIPJACK_CFB8 0x00001007UL --#define CKM_SKIPJACK_WRAP 0x00001008UL --#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL --#define CKM_SKIPJACK_RELAYX 0x0000100aUL --#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL --#define CKM_KEA_KEY_DERIVE 0x00001011UL --#define CKM_KEA_DERIVE 0x00001012UL --#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL --#define CKM_BATON_KEY_GEN 0x00001030UL --#define CKM_BATON_ECB128 0x00001031UL --#define CKM_BATON_ECB96 0x00001032UL --#define CKM_BATON_CBC128 0x00001033UL --#define CKM_BATON_COUNTER 0x00001034UL --#define CKM_BATON_SHUFFLE 0x00001035UL --#define CKM_BATON_WRAP 0x00001036UL -- --#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */ --#define CKM_EC_KEY_PAIR_GEN 0x00001040UL -- --#define CKM_ECDSA 0x00001041UL --#define CKM_ECDSA_SHA1 0x00001042UL --#define CKM_ECDSA_SHA224 0x00001043UL --#define CKM_ECDSA_SHA256 0x00001044UL --#define CKM_ECDSA_SHA384 0x00001045UL --#define CKM_ECDSA_SHA512 0x00001046UL -+#define CKM_CAST_KEY_GEN 0x00000300UL -+#define CKM_CAST_ECB 0x00000301UL -+#define CKM_CAST_CBC 0x00000302UL -+#define CKM_CAST_MAC 0x00000303UL -+#define CKM_CAST_MAC_GENERAL 0x00000304UL -+#define CKM_CAST_CBC_PAD 0x00000305UL -+#define CKM_CAST3_KEY_GEN 0x00000310UL -+#define CKM_CAST3_ECB 0x00000311UL -+#define CKM_CAST3_CBC 0x00000312UL -+#define CKM_CAST3_MAC 0x00000313UL -+#define CKM_CAST3_MAC_GENERAL 0x00000314UL -+#define CKM_CAST3_CBC_PAD 0x00000315UL -+#define CKM_CAST5_KEY_GEN 0x00000320UL -+#define CKM_CAST128_KEY_GEN 0x00000320UL -+#define CKM_CAST5_ECB 0x00000321UL -+#define CKM_CAST128_ECB 0x00000321UL -+#define CKM_CAST5_CBC 0x00000322UL -+#define CKM_CAST128_CBC 0x00000322UL -+#define CKM_CAST5_MAC 0x00000323UL -+#define CKM_CAST128_MAC 0x00000323UL -+#define CKM_CAST5_MAC_GENERAL 0x00000324UL -+#define CKM_CAST128_MAC_GENERAL 0x00000324UL -+#define CKM_CAST5_CBC_PAD 0x00000325UL -+#define CKM_CAST128_CBC_PAD 0x00000325UL -+#define CKM_RC5_KEY_GEN 0x00000330UL -+#define CKM_RC5_ECB 0x00000331UL -+#define CKM_RC5_CBC 0x00000332UL -+#define CKM_RC5_MAC 0x00000333UL -+#define CKM_RC5_MAC_GENERAL 0x00000334UL -+#define CKM_RC5_CBC_PAD 0x00000335UL -+#define CKM_IDEA_KEY_GEN 0x00000340UL -+#define CKM_IDEA_ECB 0x00000341UL -+#define CKM_IDEA_CBC 0x00000342UL -+#define CKM_IDEA_MAC 0x00000343UL -+#define CKM_IDEA_MAC_GENERAL 0x00000344UL -+#define CKM_IDEA_CBC_PAD 0x00000345UL -+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL -+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL -+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL -+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL -+#define CKM_XOR_BASE_AND_DATA 0x00000364UL -+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL -+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL -+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL -+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL -+ -+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN, -+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and -+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */ -+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL -+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL -+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL -+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL -+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL -+ -+/* CKM_TLS_PRF is new for v2.20 */ -+#define CKM_TLS_PRF 0x00000378UL -+ -+#define CKM_SSL3_MD5_MAC 0x00000380UL -+#define CKM_SSL3_SHA1_MAC 0x00000381UL -+#define CKM_MD5_KEY_DERIVATION 0x00000390UL -+#define CKM_MD2_KEY_DERIVATION 0x00000391UL -+#define CKM_SHA1_KEY_DERIVATION 0x00000392UL -+ -+/* CKM_SHA256/384/512 are new for v2.20 */ -+#define CKM_SHA256_KEY_DERIVATION 0x00000393UL -+#define CKM_SHA384_KEY_DERIVATION 0x00000394UL -+#define CKM_SHA512_KEY_DERIVATION 0x00000395UL -+ -+/* CKM_SHA224 new for v2.20 amendment 3 */ -+#define CKM_SHA224_KEY_DERIVATION 0x00000396UL -+ -+/* new for v2.40 */ -+#define CKM_SHA3_256_KEY_DERIVATION 0x00000397UL -+#define CKM_SHA3_224_KEY_DERIVATION 0x00000398UL -+#define CKM_SHA3_384_KEY_DERIVATION 0x00000399UL -+#define CKM_SHA3_512_KEY_DERIVATION 0x0000039AUL -+#define CKM_SHAKE_128_KEY_DERIVATION 0x0000039BUL -+#define CKM_SHAKE_256_KEY_DERIVATION 0x0000039CUL -+ -+#define CKM_PBE_MD2_DES_CBC 0x000003A0UL -+#define CKM_PBE_MD5_DES_CBC 0x000003A1UL -+#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL -+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL -+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL -+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL -+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL -+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL -+#define CKM_PBE_SHA1_RC4_128 0x000003A6UL -+#define CKM_PBE_SHA1_RC4_40 0x000003A7UL -+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL -+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL -+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL -+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL -+ -+/* CKM_PKCS5_PBKD2 is new for v2.10 */ -+#define CKM_PKCS5_PBKD2 0x000003B0UL -+ -+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL -+ -+/* WTLS mechanisms are new for v2.20 */ -+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL -+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL -+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL -+#define CKM_WTLS_PRF 0x000003D3UL -+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL -+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL -+ -+/* TLS 1.2 mechanisms are new for v2.40 */ -+#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL -+#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL -+#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL -+#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL -+#define CKM_TLS12_MAC 0x000003D8UL -+#define CKM_TLS12_KDF 0x000003D9UL -+#define CKM_TLS_MAC 0x000003E4UL -+#define CKM_TLS_KDF 0x000003E5UL -+ -+#define CKM_KEY_WRAP_LYNKS 0x00000400UL -+#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL -+ -+/* CKM_CMS_SIG is new for v2.20 */ -+#define CKM_CMS_SIG 0x00000500UL -+ -+/* new for 2.40 */ -+#define CKM_KIP_DERIVE 0x00000510UL -+#define CKM_KIP_WRAP 0x00000511UL -+#define CKM_KIP_MAC 0x00000512UL -+ -+/* Fortezza mechanisms */ -+#define CKM_SKIPJACK_KEY_GEN 0x00001000UL -+#define CKM_SKIPJACK_ECB64 0x00001001UL -+#define CKM_SKIPJACK_CBC64 0x00001002UL -+#define CKM_SKIPJACK_OFB64 0x00001003UL -+#define CKM_SKIPJACK_CFB64 0x00001004UL -+#define CKM_SKIPJACK_CFB32 0x00001005UL -+#define CKM_SKIPJACK_CFB16 0x00001006UL -+#define CKM_SKIPJACK_CFB8 0x00001007UL -+#define CKM_SKIPJACK_WRAP 0x00001008UL -+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL -+#define CKM_SKIPJACK_RELAYX 0x0000100aUL -+#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL -+#define CKM_KEA_KEY_DERIVE 0x00001011UL -+#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL -+#define CKM_BATON_KEY_GEN 0x00001030UL -+#define CKM_BATON_ECB128 0x00001031UL -+#define CKM_BATON_ECB96 0x00001032UL -+#define CKM_BATON_CBC128 0x00001033UL -+#define CKM_BATON_COUNTER 0x00001034UL -+#define CKM_BATON_SHUFFLE 0x00001035UL -+#define CKM_BATON_WRAP 0x00001036UL -+ -+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, -+ * CKM_EC_KEY_PAIR_GEN is preferred */ -+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL -+#define CKM_EC_KEY_PAIR_GEN 0x00001040UL -+ -+#define CKM_ECDSA 0x00001041UL -+#define CKM_ECDSA_SHA1 0x00001042UL -+ -+/* new for v2.40 */ -+#define CKM_ECDSA_SHA224 0x00001043UL -+#define CKM_ECDSA_SHA256 0x00001044UL -+#define CKM_ECDSA_SHA384 0x00001045UL -+#define CKM_ECDSA_SHA512 0x00001046UL - #define CKM_EC_KEY_PAIR_GEN_W_EXTRA_BITS 0x0000140BUL - --#define CKM_ECDH1_DERIVE 0x00001050UL --#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL --#define CKM_ECMQV_DERIVE 0x00001052UL -- --#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL --#define CKM_RSA_AES_KEY_WRAP 0x00001054UL -- --#define CKM_JUNIPER_KEY_GEN 0x00001060UL --#define CKM_JUNIPER_ECB128 0x00001061UL --#define CKM_JUNIPER_CBC128 0x00001062UL --#define CKM_JUNIPER_COUNTER 0x00001063UL --#define CKM_JUNIPER_SHUFFLE 0x00001064UL --#define CKM_JUNIPER_WRAP 0x00001065UL --#define CKM_FASTHASH 0x00001070UL -- --#define CKM_AES_XTS 0x00001071UL --#define CKM_AES_XTS_KEY_GEN 0x00001072UL --#define CKM_AES_KEY_GEN 0x00001080UL --#define CKM_AES_ECB 0x00001081UL --#define CKM_AES_CBC 0x00001082UL --#define CKM_AES_MAC 0x00001083UL --#define CKM_AES_MAC_GENERAL 0x00001084UL --#define CKM_AES_CBC_PAD 0x00001085UL --#define CKM_AES_CTR 0x00001086UL --#define CKM_AES_GCM 0x00001087UL --#define CKM_AES_CCM 0x00001088UL --#define CKM_AES_CTS 0x00001089UL --#define CKM_AES_CMAC 0x0000108AUL --#define CKM_AES_CMAC_GENERAL 0x0000108BUL -- --#define CKM_AES_XCBC_MAC 0x0000108CUL --#define CKM_AES_XCBC_MAC_96 0x0000108DUL --#define CKM_AES_GMAC 0x0000108EUL -- --#define CKM_BLOWFISH_KEY_GEN 0x00001090UL --#define CKM_BLOWFISH_CBC 0x00001091UL --#define CKM_TWOFISH_KEY_GEN 0x00001092UL --#define CKM_TWOFISH_CBC 0x00001093UL --#define CKM_BLOWFISH_CBC_PAD 0x00001094UL --#define CKM_TWOFISH_CBC_PAD 0x00001095UL -- --#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL --#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL --#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL --#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL --#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL --#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL -- --#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL --#define CKM_GOSTR3410 0x00001201UL --#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL --#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL --#define CKM_GOSTR3410_DERIVE 0x00001204UL --#define CKM_GOSTR3411 0x00001210UL --#define CKM_GOSTR3411_HMAC 0x00001211UL --#define CKM_GOST28147_KEY_GEN 0x00001220UL --#define CKM_GOST28147_ECB 0x00001221UL --#define CKM_GOST28147 0x00001222UL --#define CKM_GOST28147_MAC 0x00001223UL --#define CKM_GOST28147_KEY_WRAP 0x00001224UL --#define CKM_CHACHA20_KEY_GEN 0x00001225UL --#define CKM_CHACHA20 0x00001226UL --#define CKM_POLY1305_KEY_GEN 0x00001227UL --#define CKM_POLY1305 0x00001228UL --#define CKM_DSA_PARAMETER_GEN 0x00002000UL --#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL --#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL --#define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL --#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN CKM_DSA_PROBABILISTIC_PARAMETER_GEN --#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL --#define CKM_DSA_FIPS_G_GEN 0x00002005UL -- --#define CKM_AES_OFB 0x00002104UL --#define CKM_AES_CFB64 0x00002105UL --#define CKM_AES_CFB8 0x00002106UL --#define CKM_AES_CFB128 0x00002107UL -- --#define CKM_AES_CFB1 0x00002108UL --#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */ --#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */ --#define CKM_AES_KEY_WRAP_KWP 0x0000210BUL -- --#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL --#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL -- --#define CKM_SHA_1_KEY_GEN 0x00004003UL --#define CKM_SHA224_KEY_GEN 0x00004004UL --#define CKM_SHA256_KEY_GEN 0x00004005UL --#define CKM_SHA384_KEY_GEN 0x00004006UL --#define CKM_SHA512_KEY_GEN 0x00004007UL --#define CKM_SHA512_224_KEY_GEN 0x00004008UL --#define CKM_SHA512_256_KEY_GEN 0x00004009UL --#define CKM_SHA512_T_KEY_GEN 0x0000400aUL --#define CKM_NULL 0x0000400bUL --#define CKM_BLAKE2B_160 0x0000400cUL --#define CKM_BLAKE2B_160_HMAC 0x0000400dUL --#define CKM_BLAKE2B_160_HMAC_GENERAL 0x0000400eUL --#define CKM_BLAKE2B_160_KEY_DERIVE 0x0000400fUL --#define CKM_BLAKE2B_160_KEY_GEN 0x00004010UL --#define CKM_BLAKE2B_256 0x00004011UL --#define CKM_BLAKE2B_256_HMAC 0x00004012UL --#define CKM_BLAKE2B_256_HMAC_GENERAL 0x00004013UL --#define CKM_BLAKE2B_256_KEY_DERIVE 0x00004014UL --#define CKM_BLAKE2B_256_KEY_GEN 0x00004015UL --#define CKM_BLAKE2B_384 0x00004016UL --#define CKM_BLAKE2B_384_HMAC 0x00004017UL --#define CKM_BLAKE2B_384_HMAC_GENERAL 0x00004018UL --#define CKM_BLAKE2B_384_KEY_DERIVE 0x00004019UL --#define CKM_BLAKE2B_384_KEY_GEN 0x0000401aUL --#define CKM_BLAKE2B_512 0x0000401bUL --#define CKM_BLAKE2B_512_HMAC 0x0000401cUL --#define CKM_BLAKE2B_512_HMAC_GENERAL 0x0000401dUL --#define CKM_BLAKE2B_512_KEY_DERIVE 0x0000401eUL --#define CKM_BLAKE2B_512_KEY_GEN 0x0000401fUL --#define CKM_SALSA20 0x00004020UL --#define CKM_CHACHA20_POLY1305 0x00004021UL --#define CKM_SALSA20_POLY1305 0x00004022UL --#define CKM_X3DH_INITIALIZE 0x00004023UL --#define CKM_X3DH_RESPOND 0x00004024UL --#define CKM_X2RATCHET_INITIALIZE 0x00004025UL --#define CKM_X2RATCHET_RESPOND 0x00004026UL --#define CKM_X2RATCHET_ENCRYPT 0x00004027UL --#define CKM_X2RATCHET_DECRYPT 0x00004028UL --#define CKM_XEDDSA 0x00004029UL --#define CKM_HKDF_DERIVE 0x0000402aUL --#define CKM_HKDF_DATA 0x0000402bUL --#define CKM_HKDF_KEY_GEN 0x0000402cUL --#define CKM_SALSA20_KEY_GEN 0x0000402dUL -- --#define CKM_ECDSA_SHA3_224 0x00001047UL --#define CKM_ECDSA_SHA3_256 0x00001048UL --#define CKM_ECDSA_SHA3_384 0x00001049UL --#define CKM_ECDSA_SHA3_512 0x0000104aUL --#define CKM_EC_EDWARDS_KEY_PAIR_GEN 0x00001055UL -+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE -+ * are new for v2.11 */ -+#define CKM_ECDH1_DERIVE 0x00001050UL -+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL -+#define CKM_ECMQV_DERIVE 0x00001052UL -+ -+/* new for v2.40 */ -+#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL -+#define CKM_RSA_AES_KEY_WRAP 0x00001054UL -+ -+#define CKM_JUNIPER_KEY_GEN 0x00001060UL -+#define CKM_JUNIPER_ECB128 0x00001061UL -+#define CKM_JUNIPER_CBC128 0x00001062UL -+#define CKM_JUNIPER_COUNTER 0x00001063UL -+#define CKM_JUNIPER_SHUFFLE 0x00001064UL -+#define CKM_JUNIPER_WRAP 0x00001065UL -+#define CKM_FASTHASH 0x00001070UL -+ -+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC, -+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN, -+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are -+ * new for v2.11 */ -+#define CKM_AES_KEY_GEN 0x00001080UL -+#define CKM_AES_ECB 0x00001081UL -+#define CKM_AES_CBC 0x00001082UL -+#define CKM_AES_MAC 0x00001083UL -+#define CKM_AES_MAC_GENERAL 0x00001084UL -+#define CKM_AES_CBC_PAD 0x00001085UL -+/* new for v2.20 amendment 3 */ -+#define CKM_AES_CTR 0x00001086UL -+/* new for v2.30 */ -+#define CKM_AES_GCM 0x00001087UL -+#define CKM_AES_CCM 0x00001088UL -+#define CKM_AES_CTS 0x00001089UL -+/* AES-CMAC values copied from v2.40 errata 1 header file */ -+#define CKM_AES_CMAC 0x0000108AUL -+#define CKM_AES_CMAC_GENERAL 0x0000108BUL -+#define CKM_AES_XCBC_MAC 0x0000108CUL -+#define CKM_AES_XCBC_MAC_96 0x0000108DUL -+ -+/* BlowFish and TwoFish are new for v2.20 */ -+#define CKM_BLOWFISH_KEY_GEN 0x00001090UL -+#define CKM_BLOWFISH_CBC 0x00001091UL -+#define CKM_TWOFISH_KEY_GEN 0x00001092UL -+#define CKM_TWOFISH_CBC 0x00001093UL -+ -+/* new for v2.40 */ -+#define CKM_BLOWFISH_CBC_PAD 0x00001094UL -+#define CKM_TWOFISH_CBC_PAD 0x00001095UL -+ -+/* Camellia is proposed for v2.20 Amendment 3 */ -+#define CKM_CAMELLIA_KEY_GEN 0x00000550UL -+#define CKM_CAMELLIA_ECB 0x00000551UL -+#define CKM_CAMELLIA_CBC 0x00000552UL -+#define CKM_CAMELLIA_MAC 0x00000553UL -+#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL -+#define CKM_CAMELLIA_CBC_PAD 0x00000555UL -+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL -+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL -+ -+/* new for v2.40 */ -+#define CKM_ARIA_KEY_GEN 0x00000560UL -+#define CKM_ARIA_ECB 0x00000561UL -+#define CKM_ARIA_CBC 0x00000562UL -+#define CKM_ARIA_MAC 0x00000563UL -+#define CKM_ARIA_MAC_GENERAL 0x00000564UL -+#define CKM_ARIA_CBC_PAD 0x00000565UL -+#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL -+#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL -+ -+#define CKM_SEED_KEY_GEN 0x00000650UL -+#define CKM_SEED_ECB 0x00000651UL -+#define CKM_SEED_CBC 0x00000652UL -+#define CKM_SEED_MAC 0x00000653UL -+#define CKM_SEED_MAC_GENERAL 0x00000654UL -+#define CKM_SEED_CBC_PAD 0x00000655UL -+#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL -+#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL -+ -+/* new for v2.40 */ -+#define CKM_ECDSA_SHA3_224 0x00001047UL -+#define CKM_ECDSA_SHA3_256 0x00001048UL -+#define CKM_ECDSA_SHA3_384 0x00001049UL -+#define CKM_ECDSA_SHA3_512 0x0000104aUL -+#define CKM_EC_EDWARDS_KEY_PAIR_GEN 0x00001055UL - #define CKM_EC_MONTGOMERY_KEY_PAIR_GEN 0x00001056UL --#define CKM_EDDSA 0x00001057UL --#define CKM_SP800_108_COUNTER_KDF 0x000003acUL --#define CKM_SP800_108_FEEDBACK_KDF 0x000003adUL -+#define CKM_EDDSA 0x00001057UL -+ -+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */ -+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL -+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL -+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL -+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL -+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL -+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL -+ -+#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL -+#define CKM_GOSTR3410 0x00001201UL -+#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL -+#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL -+#define CKM_GOSTR3410_DERIVE 0x00001204UL -+#define CKM_GOSTR3411 0x00001210UL -+#define CKM_GOSTR3411_HMAC 0x00001211UL -+#define CKM_GOST28147_KEY_GEN 0x00001220UL -+#define CKM_GOST28147_ECB 0x00001221UL -+#define CKM_GOST28147 0x00001222UL -+#define CKM_GOST28147_MAC 0x00001223UL -+#define CKM_GOST28147_KEY_WRAP 0x00001224UL -+ -+/* new for v2.40 */ -+#define CKM_CHACHA20_KEY_GEN 0x00001225UL -+#define CKM_CHACHA20 0x00001226UL -+#define CKM_POLY1305_KEY_GEN 0x00001227UL -+#define CKM_POLY1305 0x00001228UL -+ -+#define CKM_DSA_PARAMETER_GEN 0x00002000UL -+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL -+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL -+ -+/* new for v2.40 */ -+#define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL -+#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL -+#define CKM_DSA_FIPS_G_GEN 0x00002005UL -+#define CKM_AES_CFB1 0x00002108UL -+#define CKM_AES_KEY_WRAP 0x00002109UL -+#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL -+#define CKM_AES_KEY_WRAP_KWP 0x0000210BUL -+ -+/* CKM_SP800_108_xxx_KDF are new for v3.0 */ -+#define CKM_SP800_108_COUNTER_KDF 0x000003acUL -+#define CKM_SP800_108_FEEDBACK_KDF 0x000003adUL - #define CKM_SP800_108_DOUBLE_PIPELINE_KDF 0x000003aeUL - --#define CKM_VENDOR_DEFINED 0x80000000UL -+/* new for v2.4 */ -+#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL -+#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL -+#define CKM_SHA_1_KEY_GEN 0x00004003UL -+#define CKM_SHA224_KEY_GEN 0x00004004UL -+#define CKM_SHA256_KEY_GEN 0x00004005UL -+#define CKM_SHA384_KEY_GEN 0x00004006UL -+#define CKM_SHA512_KEY_GEN 0x00004007UL -+#define CKM_SHA512_224_KEY_GEN 0x00004008UL -+#define CKM_SHA512_256_KEY_GEN 0x00004009UL -+#define CKM_SHA512_T_KEY_GEN 0x0000400aUL -+ -+/* new for v3.0 */ -+#define CKM_NULL 0x0000400bUL -+#define CKM_BLAKE2B_160 0x0000400cUL -+#define CKM_BLAKE2B_160_HMAC 0x0000400dUL -+#define CKM_BLAKE2B_160_HMAC_GENERAL 0x0000400eUL -+#define CKM_BLAKE2B_160_KEY_DERIVE 0x0000400fUL -+#define CKM_BLAKE2B_160_KEY_GEN 0x00004010UL -+#define CKM_BLAKE2B_256 0x00004011UL -+#define CKM_BLAKE2B_256_HMAC 0x00004012UL -+#define CKM_BLAKE2B_256_HMAC_GENERAL 0x00004013UL -+#define CKM_BLAKE2B_256_KEY_DERIVE 0x00004014UL -+#define CKM_BLAKE2B_256_KEY_GEN 0x00004015UL -+#define CKM_BLAKE2B_384 0x00004016UL -+#define CKM_BLAKE2B_384_HMAC 0x00004017UL -+#define CKM_BLAKE2B_384_HMAC_GENERAL 0x00004018UL -+#define CKM_BLAKE2B_384_KEY_DERIVE 0x00004019UL -+#define CKM_BLAKE2B_384_KEY_GEN 0x0000401aUL -+#define CKM_BLAKE2B_512 0x0000401bUL -+#define CKM_BLAKE2B_512_HMAC 0x0000401cUL -+#define CKM_BLAKE2B_512_HMAC_GENERAL 0x0000401dUL -+#define CKM_BLAKE2B_512_KEY_DERIVE 0x0000401eUL -+#define CKM_BLAKE2B_512_KEY_GEN 0x0000401fUL -+#define CKM_SALSA20 0x00004020UL -+#define CKM_CHACHA20_POLY1305 0x00004021UL -+#define CKM_SALSA20_POLY1305 0x00004022UL -+#define CKM_X3DH_INITIALIZE 0x00004023UL -+#define CKM_X3DH_RESPOND 0x00004024UL -+#define CKM_X2RATCHET_INITIALIZE 0x00004025UL -+#define CKM_X2RATCHET_RESPOND 0x00004026UL -+#define CKM_X2RATCHET_ENCRYPT 0x00004027UL -+#define CKM_X2RATCHET_DECRYPT 0x00004028UL -+#define CKM_XEDDSA 0x00004029UL -+#define CKM_HKDF_DERIVE 0x0000402aUL -+#define CKM_HKDF_DATA 0x0000402bUL -+#define CKM_HKDF_KEY_GEN 0x0000402cUL -+#define CKM_SALSA20_KEY_GEN 0x0000402dUL - --typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; -+#define CKM_VENDOR_DEFINED 0x80000000UL - -+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; - - /* CK_MECHANISM is a structure that specifies a particular -- * mechanism -- */ -+ * mechanism */ - typedef struct CK_MECHANISM { - CK_MECHANISM_TYPE mechanism; -- CK_VOID_PTR pParameter; -- CK_ULONG ulParameterLen; /* in bytes */ -+ CK_VOID_PTR pParameter; -+ -+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+ CK_ULONG ulParameterLen; /* in bytes */ - } CK_MECHANISM; - - typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; - -- - /* CK_MECHANISM_INFO provides information about a particular -- * mechanism -- */ -+ * mechanism */ - typedef struct CK_MECHANISM_INFO { - CK_ULONG ulMinKeySize; - CK_ULONG ulMaxKeySize; -@@ -1152,711 +1267,947 @@ typedef struct CK_MECHANISM_INFO { - } CK_MECHANISM_INFO; - - /* The flags are defined as follows: -- * Bit Flag Mask Meaning */ --#define CKF_HW 0x00000001UL /* performed by HW */ -- --/* Specify whether or not a mechanism can be used for a particular task */ --#define CKF_MESSAGE_ENCRYPT 0x00000002UL --#define CKF_MESSAGE_DECRYPT 0x00000004UL --#define CKF_MESSAGE_SIGN 0x00000008UL --#define CKF_MESSAGE_VERIFY 0x00000010UL --#define CKF_MULTI_MESSAGE 0x00000020UL --#define CKF_MULTI_MESSGE CKF_MULTI_MESSAGE --#define CKF_FIND_OBJECTS 0x00000040UL -- --#define CKF_ENCRYPT 0x00000100UL --#define CKF_DECRYPT 0x00000200UL --#define CKF_DIGEST 0x00000400UL --#define CKF_SIGN 0x00000800UL --#define CKF_SIGN_RECOVER 0x00001000UL --#define CKF_VERIFY 0x00002000UL --#define CKF_VERIFY_RECOVER 0x00004000UL --#define CKF_GENERATE 0x00008000UL --#define CKF_GENERATE_KEY_PAIR 0x00010000UL --#define CKF_WRAP 0x00020000UL --#define CKF_UNWRAP 0x00040000UL --#define CKF_DERIVE 0x00080000UL -+ * Bit Flag Mask Meaning */ -+#define CKF_HW 0x00000001UL /* performed by HW */ - --/* Describe a token's EC capabilities not available in mechanism -- * information. -- */ --#define CKF_EC_F_P 0x00100000UL --#define CKF_EC_F_2M 0x00200000UL --#define CKF_EC_ECPARAMETERS 0x00400000UL --#define CKF_EC_OID 0x00800000UL --#define CKF_EC_NAMEDCURVE CKF_EC_OID /* deprecated since PKCS#11 3.00 */ --#define CKF_EC_UNCOMPRESS 0x01000000UL --#define CKF_EC_COMPRESS 0x02000000UL --#define CKF_EC_CURVENAME 0x04000000UL -+/* Message interface Flags, new for v3.0 */ -+#define CKF_MESSAGE_ENCRYPT 0x00000002UL -+#define CKF_MESSAGE_DECRYPT 0x00000004UL -+#define CKF_MESSAGE_SIGN 0x00000008UL -+#define CKF_MESSAGE_VERIFY 0x00000010UL -+#define CKF_MULTI_MESSAGE 0x00000020UL -+ -+/* FindObjects (not for CK_MECHANISM_INFO, but for C_CancelSession) v3.0 */ -+#define CKF_FIND_OBJECTS 0x00000040UL -+ -+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, -+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, -+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, -+ * and CKF_DERIVE are new for v2.0. They specify whether or not -+ * a mechanism can be used for a particular task */ -+#define CKF_ENCRYPT 0x00000100UL -+#define CKF_DECRYPT 0x00000200UL -+#define CKF_DIGEST 0x00000400UL -+#define CKF_SIGN 0x00000800UL -+#define CKF_SIGN_RECOVER 0x00001000UL -+#define CKF_VERIFY 0x00002000 -+#define CKF_VERIFY_RECOVER 0x00004000UL -+#define CKF_GENERATE 0x00008000UL -+#define CKF_GENERATE_KEY_PAIR 0x00010000UL -+#define CKF_WRAP 0x00020000UL -+#define CKF_UNWRAP 0x00040000UL -+#define CKF_DERIVE 0x00080000UL -+ -+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE, -+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They -+ * describe a token's EC capabilities not available in mechanism -+ * information. */ -+#define CKF_EC_F_P 0x00100000UL -+#define CKF_EC_F_2M 0x00200000UL -+#define CKF_EC_ECPARAMETERS 0x00400000UL -+#define CKF_EC_OID 0x00800000UL -+#define CKF_EC_NAMEDCURVE CKF_EC_OID /* renamed in v3.0 */ -+#define CKF_EC_UNCOMPRESS 0x01000000UL -+#define CKF_EC_COMPRESS 0x02000000UL - --#define CKF_EXTENSION 0x80000000UL -+#define CKF_EXTENSION 0x80000000UL /* FALSE for this version */ - - typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; - - /* CK_RV is a value that identifies the return value of a -- * Cryptoki function -- */ --typedef CK_ULONG CK_RV; -- --#define CKR_OK 0x00000000UL --#define CKR_CANCEL 0x00000001UL --#define CKR_HOST_MEMORY 0x00000002UL --#define CKR_SLOT_ID_INVALID 0x00000003UL -- --#define CKR_GENERAL_ERROR 0x00000005UL --#define CKR_FUNCTION_FAILED 0x00000006UL -- --#define CKR_ARGUMENTS_BAD 0x00000007UL --#define CKR_NO_EVENT 0x00000008UL --#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL --#define CKR_CANT_LOCK 0x0000000AUL -- --#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL --#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL --#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL --#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL -- --#define CKR_ACTION_PROHIBITED 0x0000001BUL -- --#define CKR_DATA_INVALID 0x00000020UL --#define CKR_DATA_LEN_RANGE 0x00000021UL --#define CKR_DEVICE_ERROR 0x00000030UL --#define CKR_DEVICE_MEMORY 0x00000031UL --#define CKR_DEVICE_REMOVED 0x00000032UL --#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL --#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL --#define CKR_AEAD_DECRYPT_FAILED 0x00000042UL --#define CKR_FUNCTION_CANCELED 0x00000050UL --#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL -- --#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL -- --#define CKR_KEY_HANDLE_INVALID 0x00000060UL -- --#define CKR_KEY_SIZE_RANGE 0x00000062UL --#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL -- --#define CKR_KEY_NOT_NEEDED 0x00000064UL --#define CKR_KEY_CHANGED 0x00000065UL --#define CKR_KEY_NEEDED 0x00000066UL --#define CKR_KEY_INDIGESTIBLE 0x00000067UL --#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL --#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL --#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL -- --#define CKR_MECHANISM_INVALID 0x00000070UL --#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL -- --#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL --#define CKR_OPERATION_ACTIVE 0x00000090UL --#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL --#define CKR_PIN_INCORRECT 0x000000A0UL --#define CKR_PIN_INVALID 0x000000A1UL --#define CKR_PIN_LEN_RANGE 0x000000A2UL -- --#define CKR_PIN_EXPIRED 0x000000A3UL --#define CKR_PIN_LOCKED 0x000000A4UL -- --#define CKR_SESSION_CLOSED 0x000000B0UL --#define CKR_SESSION_COUNT 0x000000B1UL --#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL --#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL --#define CKR_SESSION_READ_ONLY 0x000000B5UL --#define CKR_SESSION_EXISTS 0x000000B6UL -- --#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL --#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL -- --#define CKR_SIGNATURE_INVALID 0x000000C0UL --#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL --#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL --#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL --#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL --#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL --#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL --#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL --#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL --#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL --#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL --#define CKR_USER_NOT_LOGGED_IN 0x00000101UL --#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL --#define CKR_USER_TYPE_INVALID 0x00000103UL -- --#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL --#define CKR_USER_TOO_MANY_TYPES 0x00000105UL -- --#define CKR_WRAPPED_KEY_INVALID 0x00000110UL --#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL --#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL --#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL --#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL --#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL -- --#define CKR_RANDOM_NO_RNG 0x00000121UL -- --#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL -- --#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL -- --#define CKR_BUFFER_TOO_SMALL 0x00000150UL --#define CKR_SAVED_STATE_INVALID 0x00000160UL --#define CKR_INFORMATION_SENSITIVE 0x00000170UL --#define CKR_STATE_UNSAVEABLE 0x00000180UL -- --#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL --#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL --#define CKR_MUTEX_BAD 0x000001A0UL --#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL -- --#define CKR_NEW_PIN_MODE 0x000001B0UL --#define CKR_NEXT_OTP 0x000001B1UL -- --#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL --#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL --#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL --#define CKR_PIN_TOO_WEAK 0x000001B8UL --#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL -- --#define CKR_FUNCTION_REJECTED 0x00000200UL --#define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL --#define CKR_OPERATION_CANCEL_FAILED 0x00000202UL -- --#define CKR_VENDOR_DEFINED 0x80000000UL -+ * PKCS #11 function */ -+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ -+typedef CK_ULONG CK_RV; -+ -+#define CKR_OK 0x00000000UL -+#define CKR_CANCEL 0x00000001UL -+#define CKR_HOST_MEMORY 0x00000002UL -+#define CKR_SLOT_ID_INVALID 0x00000003UL -+ -+/* CKR_FLAGS_INVALID was removed for v2.0 */ -+ -+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ -+#define CKR_GENERAL_ERROR 0x00000005UL -+#define CKR_FUNCTION_FAILED 0x00000006UL -+ -+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, -+ * and CKR_CANT_LOCK are new for v2.01 */ -+#define CKR_ARGUMENTS_BAD 0x00000007UL -+#define CKR_NO_EVENT 0x00000008UL -+#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL -+#define CKR_CANT_LOCK 0x0000000AUL -+ -+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL -+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL -+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL -+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL -+ -+/* new for v3.0 */ -+#define CKR_ACTION_PROHIBITED 0x0000001BUL -+ -+#define CKR_DATA_INVALID 0x00000020UL -+#define CKR_DATA_LEN_RANGE 0x00000021UL -+#define CKR_DEVICE_ERROR 0x00000030UL -+#define CKR_DEVICE_MEMORY 0x00000031UL -+#define CKR_DEVICE_REMOVED 0x00000032UL -+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL -+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL -+#define CKR_FUNCTION_CANCELED 0x00000050UL -+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL -+ -+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ -+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL -+ -+#define CKR_KEY_HANDLE_INVALID 0x00000060UL -+ -+/* CKR_KEY_SENSITIVE was removed for v2.0 */ -+ -+#define CKR_KEY_SIZE_RANGE 0x00000062UL -+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL -+ -+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, -+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, -+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for -+ * v2.0 */ -+#define CKR_KEY_NOT_NEEDED 0x00000064UL -+#define CKR_KEY_CHANGED 0x00000065UL -+#define CKR_KEY_NEEDED 0x00000066UL -+#define CKR_KEY_INDIGESTIBLE 0x00000067UL -+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL -+#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL -+#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL -+ -+#define CKR_MECHANISM_INVALID 0x00000070UL -+#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL -+ -+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID -+ * were removed for v2.0 */ -+#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL -+#define CKR_OPERATION_ACTIVE 0x00000090UL -+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL -+#define CKR_PIN_INCORRECT 0x000000A0UL -+#define CKR_PIN_INVALID 0x000000A1UL -+#define CKR_PIN_LEN_RANGE 0x000000A2UL -+ -+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ -+#define CKR_PIN_EXPIRED 0x000000A3UL -+#define CKR_PIN_LOCKED 0x000000A4UL -+ -+#define CKR_SESSION_CLOSED 0x000000B0UL -+#define CKR_SESSION_COUNT 0x000000B1UL -+#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL -+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL -+#define CKR_SESSION_READ_ONLY 0x000000B5UL -+#define CKR_SESSION_EXISTS 0x000000B6UL -+ -+/* CKR_SESSION_READ_ONLY_EXISTS and -+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */ -+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL -+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL -+ -+#define CKR_SIGNATURE_INVALID 0x000000C0UL -+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL -+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL -+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL -+#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL -+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL -+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL -+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL -+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL -+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL -+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL -+#define CKR_USER_NOT_LOGGED_IN 0x00000101UL -+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL -+#define CKR_USER_TYPE_INVALID 0x00000103UL -+ -+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES -+ * are new to v2.01 */ -+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL -+#define CKR_USER_TOO_MANY_TYPES 0x00000105UL -+ -+#define CKR_WRAPPED_KEY_INVALID 0x00000110UL -+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL -+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL -+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL -+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL -+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL -+ -+/* This is new to v2.0 */ -+#define CKR_RANDOM_NO_RNG 0x00000121UL -+ -+/* This is new to v2.11 */ -+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL -+ -+/* This is new to v2.40 */ -+#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL -+ -+/* These are new to v2.0 */ -+#define CKR_BUFFER_TOO_SMALL 0x00000150UL -+#define CKR_SAVED_STATE_INVALID 0x00000160UL -+#define CKR_INFORMATION_SENSITIVE 0x00000170UL -+#define CKR_STATE_UNSAVEABLE 0x00000180UL -+ -+/* These are new to v2.01 */ -+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL -+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL -+#define CKR_MUTEX_BAD 0x000001A0UL -+#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL -+ -+/* These are new to v2.40 */ -+#define CKR_NEW_PIN_MODE 0x000001B0UL -+#define CKR_NEXT_OTP 0x000001B1UL -+#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL -+#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL -+#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL -+#define CKR_PIN_TOO_WEAK 0x000001B8UL -+#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL -+ -+/* This is new to v2.20 */ -+#define CKR_FUNCTION_REJECTED 0x00000200UL -+ -+/* This is new to v3.0 */ -+#define CKR_TOKEN_RESOURCE_EXCEEDED 0x00000201UL -+#define CKR_OPERATION_CANCEL_FAILED 0x00000202UL - -+#define CKR_VENDOR_DEFINED 0x80000000UL - - /* CK_NOTIFY is an application callback that processes events */ - typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( -- CK_SESSION_HANDLE hSession, /* the session's handle */ -- CK_NOTIFICATION event, -- CK_VOID_PTR pApplication /* passed to C_OpenSession */ --); -+ CK_SESSION_HANDLE hSession, /* the session's handle */ -+ CK_NOTIFICATION event, -+ CK_VOID_PTR pApplication /* passed to C_OpenSession */ -+ ); - -- --/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec -+/* CK_FUNCTION_LIST is a structure holding a PKCS #11 spec - * version and pointers of appropriate types to all the -- * Cryptoki functions -- */ -+ * PKCS #11 functions */ -+/* CK_FUNCTION_LIST is new for v2.0 */ - typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; --typedef struct CK_FUNCTION_LIST_3_0 CK_FUNCTION_LIST_3_0; - - typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; --typedef CK_FUNCTION_LIST_3_0 CK_PTR CK_FUNCTION_LIST_3_0_PTR; - - typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; -+ -+/* These are new for v3.0 */ -+typedef struct CK_FUNCTION_LIST_3_0 CK_FUNCTION_LIST_3_0; -+typedef CK_FUNCTION_LIST_3_0 CK_PTR CK_FUNCTION_LIST_3_0_PTR; - typedef CK_FUNCTION_LIST_3_0_PTR CK_PTR CK_FUNCTION_LIST_3_0_PTR_PTR; - -+/* Interfaces are new in v3.0 */ - typedef struct CK_INTERFACE { -- CK_CHAR *pInterfaceName; -+ CK_CHAR *pInterfaceName; - CK_VOID_PTR pFunctionList; -- CK_FLAGS flags; -+ CK_FLAGS flags; - } CK_INTERFACE; - - typedef CK_INTERFACE CK_PTR CK_INTERFACE_PTR; - typedef CK_INTERFACE_PTR CK_PTR CK_INTERFACE_PTR_PTR; - --#define CKF_END_OF_MESSAGE 0x00000001UL -- -+#define CKF_END_OF_MESSAGE 0x00000001UL -+#define CKF_INTERFACE_FORK_SAFE 0x00000001UL - - /* CK_CREATEMUTEX is an application callback for creating a -- * mutex object -- */ -+ * mutex object */ - typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( -- CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ --); -- -+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ -+ ); - - /* CK_DESTROYMUTEX is an application callback for destroying a -- * mutex object -- */ -+ * mutex object */ - typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( -- CK_VOID_PTR pMutex /* pointer to mutex */ --); -- -+ CK_VOID_PTR pMutex /* pointer to mutex */ -+ ); - - /* CK_LOCKMUTEX is an application callback for locking a mutex */ - typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( -- CK_VOID_PTR pMutex /* pointer to mutex */ --); -- -+ CK_VOID_PTR pMutex /* pointer to mutex */ -+ ); - - /* CK_UNLOCKMUTEX is an application callback for unlocking a -- * mutex -- */ -+ * mutex */ - typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( -- CK_VOID_PTR pMutex /* pointer to mutex */ --); -- --/* Get functionlist flags */ --#define CKF_INTERFACE_FORK_SAFE 0x00000001UL -+ CK_VOID_PTR pMutex /* pointer to mutex */ -+ ); - - /* CK_C_INITIALIZE_ARGS provides the optional arguments to -- * C_Initialize -- */ -+ * C_Initialize */ - typedef struct CK_C_INITIALIZE_ARGS { -- CK_CREATEMUTEX CreateMutex; -+ CK_CREATEMUTEX CreateMutex; - CK_DESTROYMUTEX DestroyMutex; -- CK_LOCKMUTEX LockMutex; -- CK_UNLOCKMUTEX UnlockMutex; -- CK_FLAGS flags; -- CK_VOID_PTR pReserved; -+ CK_LOCKMUTEX LockMutex; -+ CK_UNLOCKMUTEX UnlockMutex; -+ CK_FLAGS flags; -+ /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but -+ * a reserved field. NSS needs a way to pass instance-specific information -+ * to the library (like where to find its config files, etc). This -+ * information is usually provided by the installer and passed uninterpreted -+ * by NSS to the library, though NSS does know the specifics of the softoken -+ * version of this parameter. Most compliant PKCS#11 modules expect this -+ * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from -+ * C_Initialize if Library parameters is supplied. */ -+ CK_CHAR_PTR *LibraryParameters; -+ /* This field is only present if the LibraryParameters is not NULL. It must -+ * be NULL in all cases */ -+ CK_VOID_PTR pReserved; - } CK_C_INITIALIZE_ARGS; - - /* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ - #define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL --#define CKF_OS_LOCKING_OK 0x00000002UL -+#define CKF_OS_LOCKING_OK 0x00000002UL - - typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; - -- -- - /* additional flags for parameters to functions */ - - /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ --#define CKF_DONT_BLOCK 1 -+#define CKF_DONT_BLOCK 1 - --/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message -+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10. -+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message - * Generation Function (MGF) applied to a message block when - * formatting a message block for the PKCS #1 OAEP encryption -- * scheme. -- */ -+ * scheme. */ - typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; - - typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; - - /* The following MGFs are defined */ --#define CKG_MGF1_SHA1 0x00000001UL --#define CKG_MGF1_SHA256 0x00000002UL --#define CKG_MGF1_SHA384 0x00000003UL --#define CKG_MGF1_SHA512 0x00000004UL --#define CKG_MGF1_SHA224 0x00000005UL --#define CKG_MGF1_SHA3_224 0x00000006UL --#define CKG_MGF1_SHA3_256 0x00000007UL --#define CKG_MGF1_SHA3_384 0x00000008UL --#define CKG_MGF1_SHA3_512 0x00000009UL -+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512 -+ * are new for v2.20 */ -+#define CKG_MGF1_SHA1 0x00000001UL -+#define CKG_MGF1_SHA256 0x00000002UL -+#define CKG_MGF1_SHA384 0x00000003UL -+#define CKG_MGF1_SHA512 0x00000004UL -+ -+/* v2.20 amendment 3 */ -+#define CKG_MGF1_SHA224 0x00000005UL -+ -+/* v2.40 */ -+#define CKG_MGF1_SHA3_224 0x00000006UL -+#define CKG_MGF1_SHA3_256 0x00000007UL -+#define CKG_MGF1_SHA3_384 0x00000008UL -+#define CKG_MGF1_SHA3_512 0x00000009UL - --/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source -+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10. -+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source - * of the encoding parameter when formatting a message block -- * for the PKCS #1 OAEP encryption scheme. -- */ -+ * for the PKCS #1 OAEP encryption scheme. */ - typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; - - typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; - - /* The following encoding parameter sources are defined */ --#define CKZ_DATA_SPECIFIED 0x00000001UL -+#define CKZ_DATA_SPECIFIED 0x00000001UL - --/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the -- * CKM_RSA_PKCS_OAEP mechanism. -- */ -+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10. -+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the -+ * CKM_RSA_PKCS_OAEP mechanism. */ - typedef struct CK_RSA_PKCS_OAEP_PARAMS { -- CK_MECHANISM_TYPE hashAlg; -- CK_RSA_PKCS_MGF_TYPE mgf; -+ CK_MECHANISM_TYPE hashAlg; -+ CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; -- CK_VOID_PTR pSourceData; -- CK_ULONG ulSourceDataLen; -+ CK_VOID_PTR pSourceData; -+ CK_ULONG ulSourceDataLen; - } CK_RSA_PKCS_OAEP_PARAMS; - - typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; - --/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the -- * CKM_RSA_PKCS_PSS mechanism(s). -- */ -+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11. -+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the -+ * CKM_RSA_PKCS_PSS mechanism(s). */ - typedef struct CK_RSA_PKCS_PSS_PARAMS { -- CK_MECHANISM_TYPE hashAlg; -+ CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; -- CK_ULONG sLen; -+ CK_ULONG sLen; - } CK_RSA_PKCS_PSS_PARAMS; - - typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; - -+/* CK_EC_KDF_TYPE is new for v2.11. */ - typedef CK_ULONG CK_EC_KDF_TYPE; --typedef CK_EC_KDF_TYPE CK_PTR CK_EC_KDF_TYPE_PTR; - - /* The following EC Key Derivation Functions are defined */ --#define CKD_NULL 0x00000001UL --#define CKD_SHA1_KDF 0x00000002UL -- --/* The following X9.42 DH key derivation functions are defined */ --#define CKD_SHA1_KDF_ASN1 0x00000003UL --#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL --#define CKD_SHA224_KDF 0x00000005UL --#define CKD_SHA256_KDF 0x00000006UL --#define CKD_SHA384_KDF 0x00000007UL --#define CKD_SHA512_KDF 0x00000008UL --#define CKD_CPDIVERSIFY_KDF 0x00000009UL --#define CKD_SHA3_224_KDF 0x0000000AUL --#define CKD_SHA3_256_KDF 0x0000000BUL --#define CKD_SHA3_384_KDF 0x0000000CUL --#define CKD_SHA3_512_KDF 0x0000000DUL --#define CKD_SHA1_KDF_SP800 0x0000000EUL --#define CKD_SHA224_KDF_SP800 0x0000000FUL --#define CKD_SHA256_KDF_SP800 0x00000010UL --#define CKD_SHA384_KDF_SP800 0x00000011UL --#define CKD_SHA512_KDF_SP800 0x00000012UL --#define CKD_SHA3_224_KDF_SP800 0x00000013UL --#define CKD_SHA3_256_KDF_SP800 0x00000014UL --#define CKD_SHA3_384_KDF_SP800 0x00000015UL --#define CKD_SHA3_512_KDF_SP800 0x00000016UL --#define CKD_BLAKE2B_160_KDF 0x00000017UL --#define CKD_BLAKE2B_256_KDF 0x00000018UL --#define CKD_BLAKE2B_384_KDF 0x00000019UL --#define CKD_BLAKE2B_512_KDF 0x0000001aUL -+#define CKD_NULL 0x00000001UL -+#define CKD_SHA1_KDF 0x00000002UL -+#define CKD_SHA224_KDF 0x00000005UL -+#define CKD_SHA256_KDF 0x00000006UL -+#define CKD_SHA384_KDF 0x00000007UL -+#define CKD_SHA512_KDF 0x00000008UL -+ -+/* new for v2.40 */ -+#define CKD_CPDIVERSIFY_KDF 0x00000009UL -+#define CKD_SHA3_224_KDF 0x0000000AUL -+#define CKD_SHA3_256_KDF 0x0000000BUL -+#define CKD_SHA3_384_KDF 0x0000000CUL -+#define CKD_SHA3_512_KDF 0x0000000DUL -+ -+/* new for v3.0 */ -+#define CKD_SHA1_KDF_SP800 0x0000000EUL -+#define CKD_SHA224_KDF_SP800 0x0000000FUL -+#define CKD_SHA256_KDF_SP800 0x00000010UL -+#define CKD_SHA384_KDF_SP800 0x00000011UL -+#define CKD_SHA512_KDF_SP800 0x00000012UL -+#define CKD_SHA3_224_KDF_SP800 0x00000013UL -+#define CKD_SHA3_256_KDF_SP800 0x00000014UL -+#define CKD_SHA3_384_KDF_SP800 0x00000015UL -+#define CKD_SHA3_512_KDF_SP800 0x00000016UL -+#define CKD_BLAKE2B_160_KDF 0x00000017UL -+#define CKD_BLAKE2B_256_KDF 0x00000018UL -+#define CKD_BLAKE2B_384_KDF 0x00000019UL -+#define CKD_BLAKE2B_512_KDF 0x0000001aUL - --/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the -+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11. -+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the - * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, - * where each party contributes one key pair. - */ - typedef struct CK_ECDH1_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; -- CK_ULONG ulSharedDataLen; -- CK_BYTE_PTR pSharedData; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -+ CK_ULONG ulSharedDataLen; -+ CK_BYTE_PTR pSharedData; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; - } CK_ECDH1_DERIVE_PARAMS; - - typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; - --/* -+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11. - * CK_ECDH2_DERIVE_PARAMS provides the parameters to the -- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. -- */ -+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */ - typedef struct CK_ECDH2_DERIVE_PARAMS { -- CK_EC_KDF_TYPE kdf; -- CK_ULONG ulSharedDataLen; -- CK_BYTE_PTR pSharedData; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -- CK_ULONG ulPrivateDataLen; -+ CK_EC_KDF_TYPE kdf; -+ CK_ULONG ulSharedDataLen; -+ CK_BYTE_PTR pSharedData; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; -+ CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; -- CK_ULONG ulPublicDataLen2; -- CK_BYTE_PTR pPublicData2; -+ CK_ULONG ulPublicDataLen2; -+ CK_BYTE_PTR pPublicData2; - } CK_ECDH2_DERIVE_PARAMS; - - typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; - - typedef struct CK_ECMQV_DERIVE_PARAMS { -- CK_EC_KDF_TYPE kdf; -- CK_ULONG ulSharedDataLen; -- CK_BYTE_PTR pSharedData; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -- CK_ULONG ulPrivateDataLen; -+ CK_EC_KDF_TYPE kdf; -+ CK_ULONG ulSharedDataLen; -+ CK_BYTE_PTR pSharedData; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; -+ CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; -- CK_ULONG ulPublicDataLen2; -- CK_BYTE_PTR pPublicData2; -+ CK_ULONG ulPublicDataLen2; -+ CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; - } CK_ECMQV_DERIVE_PARAMS; - - typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; - - /* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the -- * CKM_X9_42_DH_PARAMETER_GEN mechanisms -- */ -+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */ - typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; - typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; - --/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the -+/* The following X9.42 DH key derivation functions are defined -+ (besides CKD_NULL already defined : */ -+#define CKD_SHA1_KDF_ASN1 0x00000003UL -+#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL -+ -+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11. -+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party -- * contributes one key pair -- */ -+ * contributes one key pair */ - typedef struct CK_X9_42_DH1_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; -- CK_ULONG ulOtherInfoLen; -- CK_BYTE_PTR pOtherInfo; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -+ CK_ULONG ulOtherInfoLen; -+ CK_BYTE_PTR pOtherInfo; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; - } CK_X9_42_DH1_DERIVE_PARAMS; - - typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; - --/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the -+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11. -+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation -- * mechanisms, where each party contributes two key pairs -- */ -+ * mechanisms, where each party contributes two key pairs */ - typedef struct CK_X9_42_DH2_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; -- CK_ULONG ulOtherInfoLen; -- CK_BYTE_PTR pOtherInfo; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -- CK_ULONG ulPrivateDataLen; -- CK_OBJECT_HANDLE hPrivateData; -- CK_ULONG ulPublicDataLen2; -- CK_BYTE_PTR pPublicData2; -+ CK_ULONG ulOtherInfoLen; -+ CK_BYTE_PTR pOtherInfo; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; -+ CK_ULONG ulPrivateDataLen; -+ CK_OBJECT_HANDLE hPrivateData; -+ CK_ULONG ulPublicDataLen2; -+ CK_BYTE_PTR pPublicData2; - } CK_X9_42_DH2_DERIVE_PARAMS; - - typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; - - typedef struct CK_X9_42_MQV_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; -- CK_ULONG ulOtherInfoLen; -- CK_BYTE_PTR pOtherInfo; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pPublicData; -- CK_ULONG ulPrivateDataLen; -- CK_OBJECT_HANDLE hPrivateData; -- CK_ULONG ulPublicDataLen2; -- CK_BYTE_PTR pPublicData2; -- CK_OBJECT_HANDLE publicKey; -+ CK_ULONG ulOtherInfoLen; -+ CK_BYTE_PTR pOtherInfo; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pPublicData; -+ CK_ULONG ulPrivateDataLen; -+ CK_OBJECT_HANDLE hPrivateData; -+ CK_ULONG ulPublicDataLen2; -+ CK_BYTE_PTR pPublicData2; -+ CK_OBJECT_HANDLE publicKey; - } CK_X9_42_MQV_DERIVE_PARAMS; - - typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; - - /* CK_KEA_DERIVE_PARAMS provides the parameters to the -- * CKM_KEA_DERIVE mechanism -- */ -+ * CKM_KEA_DERIVE mechanism */ -+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */ - typedef struct CK_KEA_DERIVE_PARAMS { -- CK_BBOOL isSender; -- CK_ULONG ulRandomLen; -+ CK_BBOOL isSender; -+ CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pRandomB; -- CK_ULONG ulPublicDataLen; -+ CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - } CK_KEA_DERIVE_PARAMS; - - typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; - -- - /* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and - * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just -- * holds the effective keysize -- */ --typedef CK_ULONG CK_RC2_PARAMS; -+ * holds the effective keysize */ -+typedef CK_ULONG CK_RC2_PARAMS; - - typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; - -- - /* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC -- * mechanism -- */ -+ * mechanism */ - typedef struct CK_RC2_CBC_PARAMS { -- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ -- CK_BYTE iv[8]; /* IV for CBC mode */ -+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for -+ * v2.0 */ -+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ -+ -+ CK_BYTE iv[8]; /* IV for CBC mode */ - } CK_RC2_CBC_PARAMS; - - typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; - -- - /* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the -- * CKM_RC2_MAC_GENERAL mechanism -- */ -+ * CKM_RC2_MAC_GENERAL mechanism */ -+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ - typedef struct CK_RC2_MAC_GENERAL_PARAMS { -- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ -- CK_ULONG ulMacLength; /* Length of MAC in bytes */ -+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ -+ CK_ULONG ulMacLength; /* Length of MAC in bytes */ - } CK_RC2_MAC_GENERAL_PARAMS; - --typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ -- CK_RC2_MAC_GENERAL_PARAMS_PTR; -- -+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR -+ CK_RC2_MAC_GENERAL_PARAMS_PTR; - - /* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and -- * CKM_RC5_MAC mechanisms -- */ -+ * CKM_RC5_MAC mechanisms */ -+/* CK_RC5_PARAMS is new for v2.0 */ - typedef struct CK_RC5_PARAMS { -- CK_ULONG ulWordsize; /* wordsize in bits */ -- CK_ULONG ulRounds; /* number of rounds */ -+ CK_ULONG ulWordsize; /* wordsize in bits */ -+ CK_ULONG ulRounds; /* number of rounds */ - } CK_RC5_PARAMS; - - typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; - -- - /* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC -- * mechanism -- */ -+ * mechanism */ -+/* CK_RC5_CBC_PARAMS is new for v2.0 */ - typedef struct CK_RC5_CBC_PARAMS { -- CK_ULONG ulWordsize; /* wordsize in bits */ -- CK_ULONG ulRounds; /* number of rounds */ -- CK_BYTE_PTR pIv; /* pointer to IV */ -- CK_ULONG ulIvLen; /* length of IV in bytes */ -+ CK_ULONG ulWordsize; /* wordsize in bits */ -+ CK_ULONG ulRounds; /* number of rounds */ -+ CK_BYTE_PTR pIv; /* pointer to IV */ -+ CK_ULONG ulIvLen; /* length of IV in bytes */ - } CK_RC5_CBC_PARAMS; - - typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; - -- - /* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the -- * CKM_RC5_MAC_GENERAL mechanism -- */ -+ * CKM_RC5_MAC_GENERAL mechanism */ -+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ - typedef struct CK_RC5_MAC_GENERAL_PARAMS { -- CK_ULONG ulWordsize; /* wordsize in bits */ -- CK_ULONG ulRounds; /* number of rounds */ -- CK_ULONG ulMacLength; /* Length of MAC in bytes */ -+ CK_ULONG ulWordsize; /* wordsize in bits */ -+ CK_ULONG ulRounds; /* number of rounds */ -+ CK_ULONG ulMacLength; /* Length of MAC in bytes */ - } CK_RC5_MAC_GENERAL_PARAMS; - --typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ -- CK_RC5_MAC_GENERAL_PARAMS_PTR; -+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR -+ CK_RC5_MAC_GENERAL_PARAMS_PTR; - - /* CK_MAC_GENERAL_PARAMS provides the parameters to most block - * ciphers' MAC_GENERAL mechanisms. Its value is the length of -- * the MAC -- */ --typedef CK_ULONG CK_MAC_GENERAL_PARAMS; -+ * the MAC */ -+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */ -+typedef CK_ULONG CK_MAC_GENERAL_PARAMS; - - typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; - -+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */ - typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { -- CK_BYTE iv[8]; -+ CK_BYTE iv[8]; - CK_BYTE_PTR pData; -- CK_ULONG length; -+ CK_ULONG length; - } CK_DES_CBC_ENCRYPT_DATA_PARAMS; - --typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ -- CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; -+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; - - typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { -- CK_BYTE iv[16]; -+ CK_BYTE iv[16]; - CK_BYTE_PTR pData; -- CK_ULONG length; -+ CK_ULONG length; - } CK_AES_CBC_ENCRYPT_DATA_PARAMS; - --typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ -- CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; -+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; -+ -+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ -+typedef struct CK_AES_CTR_PARAMS { -+ CK_ULONG ulCounterBits; -+ CK_BYTE cb[16]; -+} CK_AES_CTR_PARAMS; -+ -+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; -+ -+/* CK_GCM_PARAMS is new for version 2.30 */ -+/* There was a discrepency between the doc and the headers -+ * in PKCS #11 v2.40, NSS had the doc version, but the header -+ * was normative. In V3.0 they were reconsiled as the header -+ * version. In NSS the header version is called CK_GCM_PARAMS_V3 -+ * and the v2.40 doc version is called CK_NSS_GCM_PARAMS. -+ * CK_GCM_PARMS is define as CK_NSS_GCM_PARAMS if -+ * NSS_PCKS11_2_0_COMPAT is defined and CK_GCM_PARAMS_V3 if it's not. -+ * Softoken accepts either version and internally uses CK_NSS_GCM_PARAMS */ -+typedef struct CK_GCM_PARAMS_V3 { -+ CK_BYTE_PTR pIv; -+ CK_ULONG ulIvLen; -+ CK_ULONG ulIvBits; -+ CK_BYTE_PTR pAAD; -+ CK_ULONG ulAADLen; -+ CK_ULONG ulTagBits; -+} CK_GCM_PARAMS_V3; -+ -+typedef CK_GCM_PARAMS_V3 CK_PTR CK_GCM_PARAMS_V3_PTR; -+ -+/* CK_CCM_PARAMS is new for version 2.30 */ -+typedef struct CK_CCM_PARAMS { -+ CK_ULONG ulDataLen; -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceLen; -+ CK_BYTE_PTR pAAD; -+ CK_ULONG ulAADLen; -+ CK_ULONG ulMACLen; -+} CK_CCM_PARAMS; -+ -+typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; -+ -+/* SALSA20_POLY1305 and CHACHA20_POLY1305 is AEAD is new in v3.0 */ -+typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceLen; -+ CK_BYTE_PTR pAAD; -+ CK_ULONG ulAADLen; -+} CK_SALSA20_CHACHA20_POLY1305_PARAMS; -+ -+typedef CK_SALSA20_CHACHA20_POLY1305_PARAMS -+ CK_PTR CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR; -+ -+/* MESSAGE params are new for v3.0 */ -+typedef CK_ULONG CK_GENERATOR_FUNCTION; -+#define CKG_NO_GENERATE 0x00000000UL -+#define CKG_GENERATE 0x00000001UL -+#define CKG_GENERATE_COUNTER 0x00000002UL -+#define CKG_GENERATE_RANDOM 0x00000003UL -+#define CKG_GENERATE_COUNTER_XOR 0x00000004UL -+ -+typedef struct CK_GCM_MESSAGE_PARAMS { -+ CK_BYTE_PTR pIv; -+ CK_ULONG ulIvLen; -+ CK_ULONG ulIvFixedBits; -+ CK_GENERATOR_FUNCTION ivGenerator; -+ CK_BYTE_PTR pTag; -+ CK_ULONG ulTagBits; -+} CK_GCM_MESSAGE_PARAMS; -+ -+typedef CK_GCM_MESSAGE_PARAMS CK_GCM_MESSAGE_PARAMS_PTR; -+ -+typedef struct CK_CCM_MESSAGE_PARAMS { -+ CK_ULONG ulDataLen; /*plaintext or ciphertext*/ -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceLen; -+ CK_ULONG ulNonceFixedBits; -+ CK_GENERATOR_FUNCTION nonceGenerator; -+ CK_BYTE_PTR pMAC; -+ CK_ULONG ulMACLen; -+} CK_CCM_MESSAGE_PARAMS; -+ -+typedef CK_CCM_MESSAGE_PARAMS CK_CCM_MESSAGE_PARAMS_PTR; -+ -+/* SALSA20/CHACHA20 doe not define IV generators */ -+typedef struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceLen; -+ CK_BYTE_PTR pTag; -+} CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS; -+ -+typedef CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS -+ CK_PTR CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS_PTR; - - /* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the -- * CKM_SKIPJACK_PRIVATE_WRAP mechanism -- */ -+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ -+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ - typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { -- CK_ULONG ulPasswordLen; -+ CK_ULONG ulPasswordLen; - CK_BYTE_PTR pPassword; -- CK_ULONG ulPublicDataLen; -+ CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -- CK_ULONG ulPAndGLen; -- CK_ULONG ulQLen; -- CK_ULONG ulRandomLen; -+ CK_ULONG ulPAndGLen; -+ CK_ULONG ulQLen; -+ CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pPrimeP; - CK_BYTE_PTR pBaseG; - CK_BYTE_PTR pSubprimeQ; - } CK_SKIPJACK_PRIVATE_WRAP_PARAMS; - --typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ -- CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; -- -+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR -+ CK_SKIPJACK_PRIVATE_WRAP_PTR; - - /* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the -- * CKM_SKIPJACK_RELAYX mechanism -- */ -+ * CKM_SKIPJACK_RELAYX mechanism */ -+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ - typedef struct CK_SKIPJACK_RELAYX_PARAMS { -- CK_ULONG ulOldWrappedXLen; -+ CK_ULONG ulOldWrappedXLen; - CK_BYTE_PTR pOldWrappedX; -- CK_ULONG ulOldPasswordLen; -+ CK_ULONG ulOldPasswordLen; - CK_BYTE_PTR pOldPassword; -- CK_ULONG ulOldPublicDataLen; -+ CK_ULONG ulOldPublicDataLen; - CK_BYTE_PTR pOldPublicData; -- CK_ULONG ulOldRandomLen; -+ CK_ULONG ulOldRandomLen; - CK_BYTE_PTR pOldRandomA; -- CK_ULONG ulNewPasswordLen; -+ CK_ULONG ulNewPasswordLen; - CK_BYTE_PTR pNewPassword; -- CK_ULONG ulNewPublicDataLen; -+ CK_ULONG ulNewPublicDataLen; - CK_BYTE_PTR pNewPublicData; -- CK_ULONG ulNewRandomLen; -+ CK_ULONG ulNewRandomLen; - CK_BYTE_PTR pNewRandomA; - } CK_SKIPJACK_RELAYX_PARAMS; - --typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ -- CK_SKIPJACK_RELAYX_PARAMS_PTR; -+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR -+ CK_SKIPJACK_RELAYX_PARAMS_PTR; -+ -+/* New for v2.40, CAMELLIA, ARIA, SEED */ -+typedef struct CK_CAMELLIA_CTR_PARAMS { -+ CK_ULONG ulCounterBits; -+ CK_BYTE cb[16]; -+} CK_CAMELLIA_CTR_PARAMS; -+ -+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; - -+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { -+ CK_BYTE iv[16]; -+ CK_BYTE_PTR pData; -+ CK_ULONG length; -+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; -+ -+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR -+ CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; -+ -+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { -+ CK_BYTE iv[16]; -+ CK_BYTE_PTR pData; -+ CK_ULONG length; -+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; -+ -+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR -+ CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; -+ -+typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { -+ CK_BYTE iv[16]; -+ CK_BYTE_PTR pData; -+ CK_ULONG length; -+} CK_SEED_CBC_ENCRYPT_DATA_PARAMS; -+ -+typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR -+ CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; -+ -+/* ChaCha20/Salsa20 Counter support is new in v3.0*/ -+typedef struct CK_CHACHA20_PARAMS { -+ CK_BYTE_PTR pBlockCounter; -+ CK_ULONG blockCounterBits; -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceBits; -+} CK_CHACHA20_PARAMS; -+ -+typedef CK_CHACHA20_PARAMS CK_PTR CK_CHACHA20_PARAMS_PTR; -+ -+typedef struct CK_SALSA20_PARAMS { -+ CK_BYTE_PTR pBlockCounter; -+ CK_BYTE_PTR pNonce; -+ CK_ULONG ulNonceBits; -+} CK_SALSA20_PARAMS; -+typedef CK_SALSA20_PARAMS CK_PTR CK_SALSA20_PARAMS_PTR; - - typedef struct CK_PBE_PARAMS { -- CK_BYTE_PTR pInitVector; -+ CK_BYTE_PTR pInitVector; - CK_UTF8CHAR_PTR pPassword; -- CK_ULONG ulPasswordLen; -- CK_BYTE_PTR pSalt; -- CK_ULONG ulSaltLen; -- CK_ULONG ulIteration; -+ CK_ULONG ulPasswordLen; -+ CK_BYTE_PTR pSalt; -+ CK_ULONG ulSaltLen; -+ CK_ULONG ulIteration; - } CK_PBE_PARAMS; - - typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; - -- - /* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the -- * CKM_KEY_WRAP_SET_OAEP mechanism -- */ -+ * CKM_KEY_WRAP_SET_OAEP mechanism */ -+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ - typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { -- CK_BYTE bBC; /* block contents byte */ -- CK_BYTE_PTR pX; /* extra data */ -- CK_ULONG ulXLen; /* length of extra data in bytes */ -+ CK_BYTE bBC; /* block contents byte */ -+ CK_BYTE_PTR pX; /* extra data */ -+ CK_ULONG ulXLen; /* length of extra data in bytes */ - } CK_KEY_WRAP_SET_OAEP_PARAMS; - --typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; -+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR -+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; - - typedef struct CK_SSL3_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; -- CK_ULONG ulClientRandomLen; -+ CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; -- CK_ULONG ulServerRandomLen; -+ CK_ULONG ulServerRandomLen; - } CK_SSL3_RANDOM_DATA; - -- - typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; -- CK_VERSION_PTR pVersion; -+ CK_VERSION_PTR pVersion; - } CK_SSL3_MASTER_KEY_DERIVE_PARAMS; - --typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ -- CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; -+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR -+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; - - typedef struct CK_SSL3_KEY_MAT_OUT { - CK_OBJECT_HANDLE hClientMacSecret; - CK_OBJECT_HANDLE hServerMacSecret; - CK_OBJECT_HANDLE hClientKey; - CK_OBJECT_HANDLE hServerKey; -- CK_BYTE_PTR pIVClient; -- CK_BYTE_PTR pIVServer; -+ CK_BYTE_PTR pIVClient; -+ CK_BYTE_PTR pIVServer; - } CK_SSL3_KEY_MAT_OUT; - - typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; - -- - typedef struct CK_SSL3_KEY_MAT_PARAMS { -- CK_ULONG ulMacSizeInBits; -- CK_ULONG ulKeySizeInBits; -- CK_ULONG ulIVSizeInBits; -- CK_BBOOL bIsExport; -- CK_SSL3_RANDOM_DATA RandomInfo; -+ CK_ULONG ulMacSizeInBits; -+ CK_ULONG ulKeySizeInBits; -+ CK_ULONG ulIVSizeInBits; -+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */ -+ CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; - } CK_SSL3_KEY_MAT_PARAMS; - - typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; - -+/* CK_TLS_PRF_PARAMS is new for version 2.20 */ - typedef struct CK_TLS_PRF_PARAMS { -- CK_BYTE_PTR pSeed; -- CK_ULONG ulSeedLen; -- CK_BYTE_PTR pLabel; -- CK_ULONG ulLabelLen; -- CK_BYTE_PTR pOutput; -+ CK_BYTE_PTR pSeed; -+ CK_ULONG ulSeedLen; -+ CK_BYTE_PTR pLabel; -+ CK_ULONG ulLabelLen; -+ CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; - } CK_TLS_PRF_PARAMS; - - typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; - -+/* TLS 1.2 is new for version 2.40 */ -+typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { -+ CK_SSL3_RANDOM_DATA RandomInfo; -+ CK_VERSION_PTR pVersion; -+ CK_MECHANISM_TYPE prfHashMechanism; -+} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; -+ -+typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR -+ CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; -+ -+typedef struct CK_TLS12_KEY_MAT_PARAMS { -+ CK_ULONG ulMacSizeInBits; -+ CK_ULONG ulKeySizeInBits; -+ CK_ULONG ulIVSizeInBits; -+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */ -+ CK_SSL3_RANDOM_DATA RandomInfo; -+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -+ CK_MECHANISM_TYPE prfHashMechanism; -+} CK_TLS12_KEY_MAT_PARAMS; -+ -+typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; -+ -+typedef struct CK_TLS_KDF_PARAMS { -+ CK_MECHANISM_TYPE prfMechanism; -+ CK_BYTE_PTR pLabel; -+ CK_ULONG ulLabelLength; -+ CK_SSL3_RANDOM_DATA RandomInfo; -+ CK_BYTE_PTR pContextData; -+ CK_ULONG ulContextDataLength; -+} CK_TLS_KDF_PARAMS; -+ -+typedef struct CK_TLS_MAC_PARAMS { -+ CK_MECHANISM_TYPE prfHashMechanism; -+ CK_ULONG ulMacLength; -+ CK_ULONG ulServerOrClient; -+} CK_TLS_MAC_PARAMS; -+ -+typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; -+ -+/* HKDF is new for v3.0 */ -+typedef struct CK_HKDF_PARAMS { -+ CK_BBOOL bExtract; -+ CK_BBOOL bExpand; -+ CK_MECHANISM_TYPE prfHashMechanism; -+ CK_ULONG ulSaltType; -+ CK_BYTE_PTR pSalt; -+ CK_ULONG ulSaltLen; -+ CK_OBJECT_HANDLE hSaltKey; -+ CK_BYTE_PTR pInfo; -+ CK_ULONG ulInfoLen; -+} CK_HKDF_PARAMS; -+typedef CK_HKDF_PARAMS CK_PTR CK_HKDF_PARAMS_PTR; -+ -+#define CKF_HKDF_SALT_NULL 0x00000001UL -+#define CKF_HKDF_SALT_DATA 0x00000002UL -+#define CKF_HKDF_SALT_KEY 0x00000004UL -+ -+/* WTLS is new for version 2.20 */ - typedef struct CK_WTLS_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; -- CK_ULONG ulClientRandomLen; -+ CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; -- CK_ULONG ulServerRandomLen; -+ CK_ULONG ulServerRandomLen; - } CK_WTLS_RANDOM_DATA; - - typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; - - typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { -- CK_MECHANISM_TYPE DigestMechanism; -+ CK_MECHANISM_TYPE DigestMechanism; - CK_WTLS_RANDOM_DATA RandomInfo; -- CK_BYTE_PTR pVersion; -+ CK_BYTE_PTR pVersion; - } CK_WTLS_MASTER_KEY_DERIVE_PARAMS; - --typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ -- CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; -+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR -+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; - - typedef struct CK_WTLS_PRF_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; -- CK_BYTE_PTR pSeed; -- CK_ULONG ulSeedLen; -- CK_BYTE_PTR pLabel; -- CK_ULONG ulLabelLen; -- CK_BYTE_PTR pOutput; -- CK_ULONG_PTR pulOutputLen; -+ CK_BYTE_PTR pSeed; -+ CK_ULONG ulSeedLen; -+ CK_BYTE_PTR pLabel; -+ CK_ULONG ulLabelLen; -+ CK_BYTE_PTR pOutput; -+ CK_ULONG_PTR pulOutputLen; - } CK_WTLS_PRF_PARAMS; - - typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; -@@ -1864,581 +2215,377 @@ typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTL - typedef struct CK_WTLS_KEY_MAT_OUT { - CK_OBJECT_HANDLE hMacSecret; - CK_OBJECT_HANDLE hKey; -- CK_BYTE_PTR pIV; -+ CK_BYTE_PTR pIV; - } CK_WTLS_KEY_MAT_OUT; - - typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; - - typedef struct CK_WTLS_KEY_MAT_PARAMS { -- CK_MECHANISM_TYPE DigestMechanism; -- CK_ULONG ulMacSizeInBits; -- CK_ULONG ulKeySizeInBits; -- CK_ULONG ulIVSizeInBits; -- CK_ULONG ulSequenceNumber; -- CK_BBOOL bIsExport; -- CK_WTLS_RANDOM_DATA RandomInfo; -+ CK_MECHANISM_TYPE DigestMechanism; -+ CK_ULONG ulMacSizeInBits; -+ CK_ULONG ulKeySizeInBits; -+ CK_ULONG ulIVSizeInBits; -+ CK_ULONG ulSequenceNumber; -+ CK_BBOOL bIsExport; /* Unused. Must be set to CK_FALSE. */ -+ CK_WTLS_RANDOM_DATA RandomInfo; - CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; - } CK_WTLS_KEY_MAT_PARAMS; - - typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; - -+/* The following types for NIST 800-108 KBKDF are defined in PKCS#11 v3.0 */ -+typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; -+typedef CK_ULONG CK_PRF_DATA_TYPE; -+ -+#define CK_SP800_108_ITERATION_VARIABLE 0x00000001UL -+#define CK_SP800_108_OPTIONAL_COUNTER 0x00000002UL -+#define CK_SP800_108_DKM_LENGTH 0x00000003UL -+#define CK_SP800_108_BYTE_ARRAY 0x00000004UL -+ -+/* ERRATA: PKCS#11 v3.0 Cryptographic Token Interface Current Mechanisms -+ * specification specifies a CK_SP800_108_COUNTER, while the pkcs11t.h from -+ * PKCS#11 v3.0 Cryptographic Token Interface Base Specification specifies -+ * CK_SP800_108_OPTIONAL_COUNTER. */ -+#define CK_SP800_108_COUNTER CK_SP800_108_OPTIONAL_COUNTER -+ -+typedef struct CK_PRF_DATA_PARAM { -+ CK_PRF_DATA_TYPE type; -+ CK_VOID_PTR pValue; -+ CK_ULONG ulValueLen; -+} CK_PRF_DATA_PARAM; -+ -+typedef CK_PRF_DATA_PARAM CK_PTR CK_PRF_DATA_PARAM_PTR; -+ -+typedef struct CK_SP800_108_COUNTER_FORMAT { -+ CK_BBOOL bLittleEndian; -+ CK_ULONG ulWidthInBits; -+} CK_SP800_108_COUNTER_FORMAT; -+ -+typedef CK_SP800_108_COUNTER_FORMAT CK_PTR CK_SP800_108_COUNTER_FORMAT_PTR; -+ -+typedef CK_ULONG CK_SP800_108_DKM_LENGTH_METHOD; -+ -+/* ERRATA: PKCS#11 v3.0 Cryptographic Token Interface Current Mechanisms -+ * defines that these constants exist, but doesn't specify values. pkcs11t.h -+ * from PKCS#11 v3.0 Cryptographic Token Interface Base Specification doesn't -+ * define these constants either. */ -+#define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL -+#define CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS 0x00000002UL -+ -+typedef struct CK_SP800_108_DKM_LENGTH_FORMAT { -+ CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; -+ CK_BBOOL bLittleEndian; -+ CK_ULONG ulWidthInBits; -+} CK_SP800_108_DKM_LENGTH_FORMAT; -+ -+typedef CK_SP800_108_DKM_LENGTH_FORMAT CK_PTR CK_SP800_108_DKM_LENGTH_FORMAT_PTR; -+ -+typedef struct CK_DERIVED_KEY { -+ CK_ATTRIBUTE_PTR pTemplate; -+ CK_ULONG ulAttributeCount; -+ CK_OBJECT_HANDLE_PTR phKey; -+} CK_DERIVED_KEY; -+ -+typedef CK_DERIVED_KEY CK_PTR CK_DERIVED_KEY_PTR; -+ -+/* UNFIXED ERRATA: NIST SP800-108 specifies that implementer can decide the -+ * number of bits to take from each PRF invocation. However, all three forms -+ * of the PKCS#11 v3.0 implementation lack a bitwidth for the PRF and only -+ * allow the full-width mechanism varieties. Additionally, outside of the -+ * base key (used as the key to the PRF), there is no way to pass any -+ * additional, PRF-mechanism specific data. */ -+ -+typedef struct CK_SP800_108_KDF_PARAMS { -+ CK_SP800_108_PRF_TYPE prfType; -+ CK_ULONG ulNumberOfDataParams; -+ CK_PRF_DATA_PARAM_PTR pDataParams; -+ CK_ULONG ulAdditionalDerivedKeys; -+ /* ERRATA: in PKCS#11 v3.0, pAdditionalDerivedKeys is typed as -+ * CK_DERVIED_KEY; it needs to be of type CK_DERIVED_KEY_PTR. */ -+ CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; -+} CK_SP800_108_KDF_PARAMS; -+ -+typedef CK_SP800_108_KDF_PARAMS CK_PTR CK_SP800_108_KDF_PARAMS_PTR; -+ -+typedef struct CK_SP800_108_FEEDBACK_KDF_PARAMS { -+ CK_SP800_108_PRF_TYPE prfType; -+ CK_ULONG ulNumberOfDataParams; -+ CK_PRF_DATA_PARAM_PTR pDataParams; -+ CK_ULONG ulIVLen; -+ CK_BYTE_PTR pIV; -+ CK_ULONG ulAdditionalDerivedKeys; -+ /* ERRATA: in PKCS#11 v3.0, pAdditionalDerivedKeys is typed as -+ * CK_DERVIED_KEY; it needs to be of type CK_DERIVED_KEY_PTR. */ -+ CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; -+} CK_SP800_108_FEEDBACK_KDF_PARAMS; -+ -+typedef CK_SP800_108_FEEDBACK_KDF_PARAMS CK_PTR CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR; -+ -+/* CMS is new for version 2.20 */ - typedef struct CK_CMS_SIG_PARAMS { - CK_OBJECT_HANDLE certificateHandle; - CK_MECHANISM_PTR pSigningMechanism; - CK_MECHANISM_PTR pDigestMechanism; -- CK_UTF8CHAR_PTR pContentType; -- CK_BYTE_PTR pRequestedAttributes; -- CK_ULONG ulRequestedAttributesLen; -- CK_BYTE_PTR pRequiredAttributes; -- CK_ULONG ulRequiredAttributesLen; -+ CK_UTF8CHAR_PTR pContentType; -+ CK_BYTE_PTR pRequestedAttributes; -+ CK_ULONG ulRequestedAttributesLen; -+ CK_BYTE_PTR pRequiredAttributes; -+ CK_ULONG ulRequiredAttributesLen; - } CK_CMS_SIG_PARAMS; - - typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; - - typedef struct CK_KEY_DERIVATION_STRING_DATA { - CK_BYTE_PTR pData; -- CK_ULONG ulLen; -+ CK_ULONG ulLen; - } CK_KEY_DERIVATION_STRING_DATA; - --typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ -- CK_KEY_DERIVATION_STRING_DATA_PTR; -- -+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR -+ CK_KEY_DERIVATION_STRING_DATA_PTR; - - /* The CK_EXTRACT_PARAMS is used for the - * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit - * of the base key should be used as the first bit of the -- * derived key -- */ -+ * derived key */ -+/* CK_EXTRACT_PARAMS is new for v2.0 */ - typedef CK_ULONG CK_EXTRACT_PARAMS; - - typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; - --/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to -+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10. -+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to - * indicate the Pseudo-Random Function (PRF) used to generate -- * key bits using PKCS #5 PBKDF2. -- */ -+ * key bits using PKCS #5 PBKDF2. */ - typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; - --typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ -- CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; -+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; - --#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL --#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL --#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL --#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL --#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL --#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL --#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL --#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL -+/* The following PRFs are defined in PKCS #5 v2.1. */ -+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL -+#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL -+#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL - --/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the -+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10. -+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the - * source of the salt value when deriving a key using PKCS #5 -- * PBKDF2. -- */ -+ * PBKDF2. */ - typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; - --typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ -- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; -+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; - - /* The following salt value sources are defined in PKCS #5 v2.0. */ --#define CKZ_SALT_SPECIFIED 0x00000001UL -+#define CKZ_SALT_SPECIFIED 0x00000001UL - --/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the -- * parameters to the CKM_PKCS5_PBKD2 mechanism. -- */ -+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10. -+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the -+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */ -+/* this structure is kept for compatibility. use _PARAMS2. */ - typedef struct CK_PKCS5_PBKD2_PARAMS { -- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; -- CK_VOID_PTR pSaltSourceData; -- CK_ULONG ulSaltSourceDataLen; -- CK_ULONG iterations; -+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; -+ CK_VOID_PTR pSaltSourceData; -+ CK_ULONG ulSaltSourceDataLen; -+ CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; -- CK_VOID_PTR pPrfData; -- CK_ULONG ulPrfDataLen; -- CK_UTF8CHAR_PTR pPassword; -- CK_ULONG_PTR ulPasswordLen; -+ CK_VOID_PTR pPrfData; -+ CK_ULONG ulPrfDataLen; -+ CK_UTF8CHAR_PTR pPassword; -+ CK_ULONG_PTR ulPasswordLen; - } CK_PKCS5_PBKD2_PARAMS; - - typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; - --/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS -- * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism -- * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR. -- */ - typedef struct CK_PKCS5_PBKD2_PARAMS2 { -- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; -- CK_VOID_PTR pSaltSourceData; -- CK_ULONG ulSaltSourceDataLen; -- CK_ULONG iterations; -+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; -+ CK_VOID_PTR pSaltSourceData; -+ CK_ULONG ulSaltSourceDataLen; -+ CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; -- CK_VOID_PTR pPrfData; -- CK_ULONG ulPrfDataLen; -- CK_UTF8CHAR_PTR pPassword; -- CK_ULONG ulPasswordLen; -+ CK_VOID_PTR pPrfData; -+ CK_ULONG ulPrfDataLen; -+ CK_UTF8CHAR_PTR pPassword; -+ CK_ULONG ulPasswordLen; - } CK_PKCS5_PBKD2_PARAMS2; - - typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR; - -+/* OTP is new in v2.40 */ - typedef CK_ULONG CK_OTP_PARAM_TYPE; --typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ -+#define CK_OTP_VALUE 0UL -+#define CK_OTP_PIN 1UL -+#define CK_OTP_CHALLENGE 2UL -+#define CK_OTP_TIME 3UL -+#define CK_OTP_COUNTER 4UL -+#define CK_OTP_FLAGS 5UL -+#define CK_OTP_OUTPUT_LENGTH 6UL -+#define CK_OTP_OUTPUT_FORMAT 7UL - - typedef struct CK_OTP_PARAM { - CK_OTP_PARAM_TYPE type; -- CK_VOID_PTR pValue; -- CK_ULONG ulValueLen; -+ CK_VOID_PTR pValue; -+ CK_ULONG ulValueLen; - } CK_OTP_PARAM; - - typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; - - typedef struct CK_OTP_PARAMS { - CK_OTP_PARAM_PTR pParams; -- CK_ULONG ulCount; -+ CK_ULONG ulCount; - } CK_OTP_PARAMS; - - typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; - - typedef struct CK_OTP_SIGNATURE_INFO { - CK_OTP_PARAM_PTR pParams; -- CK_ULONG ulCount; -+ CK_ULONG ulCount; - } CK_OTP_SIGNATURE_INFO; - - typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; - --#define CK_OTP_VALUE 0UL --#define CK_OTP_PIN 1UL --#define CK_OTP_CHALLENGE 2UL --#define CK_OTP_TIME 3UL --#define CK_OTP_COUNTER 4UL --#define CK_OTP_FLAGS 5UL --#define CK_OTP_OUTPUT_LENGTH 6UL --#define CK_OTP_OUTPUT_FORMAT 7UL -- --#define CKF_NEXT_OTP 0x00000001UL --#define CKF_EXCLUDE_TIME 0x00000002UL --#define CKF_EXCLUDE_COUNTER 0x00000004UL -+#define CKF_NEXT_OTP 0x00000001UL -+#define CKF_EXCLUDE_TIME 0x00000002UL -+#define CKF_EXCLUDE_COUNTER 0x00000004UL - #define CKF_EXCLUDE_CHALLENGE 0x00000008UL --#define CKF_EXCLUDE_PIN 0x00000010UL -+#define CKF_EXCLUDE_PIN 0x00000010UL - #define CKF_USER_FRIENDLY_OTP 0x00000020UL - -+/* KIP is new in v2.40 */ - typedef struct CK_KIP_PARAMS { - CK_MECHANISM_PTR pMechanism; - CK_OBJECT_HANDLE hKey; -- CK_BYTE_PTR pSeed; -- CK_ULONG ulSeedLen; -+ CK_BYTE_PTR pSeed; -+ CK_ULONG ulSeedLen; - } CK_KIP_PARAMS; - - typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; - --typedef struct CK_AES_CTR_PARAMS { -- CK_ULONG ulCounterBits; -- CK_BYTE cb[16]; --} CK_AES_CTR_PARAMS; -- --typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; -- --typedef struct CK_GCM_PARAMS { -- CK_BYTE_PTR pIv; -- CK_ULONG ulIvLen; -- CK_ULONG ulIvBits; -- CK_BYTE_PTR pAAD; -- CK_ULONG ulAADLen; -- CK_ULONG ulTagBits; --} CK_GCM_PARAMS; -- --typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; -- --typedef CK_ULONG CK_GENERATOR_FUNCTION; --#define CKG_NO_GENERATE 0x00000000UL --#define CKG_GENERATE 0x00000001UL --#define CKG_GENERATE_COUNTER 0x00000002UL --#define CKG_GENERATE_RANDOM 0x00000003UL -- --typedef struct CK_GCM_MESSAGE_PARAMS { -- CK_BYTE_PTR pIv; -- CK_ULONG ulIvLen; -- CK_ULONG ulIvFixedBits; -- CK_GENERATOR_FUNCTION ivGenerator; -- CK_BYTE_PTR pTag; -- CK_ULONG ulTagBits; --} CK_GCM_MESSAGE_PARAMS; -- --typedef CK_GCM_MESSAGE_PARAMS CK_GCM_MESSAGE_PARAMS_PTR; -- --typedef struct CK_CCM_PARAMS { -- CK_ULONG ulDataLen; -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceLen; -- CK_BYTE_PTR pAAD; -- CK_ULONG ulAADLen; -- CK_ULONG ulMACLen; --} CK_CCM_PARAMS; -- --typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; -- --typedef struct CK_CCM_MESSAGE_PARAMS { -- CK_ULONG ulDataLen; /*plaintext or ciphertext*/ -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceLen; -- CK_ULONG ulNonceFixedBits; -- CK_GENERATOR_FUNCTION nonceGenerator; -- CK_BYTE_PTR pMAC; -- CK_ULONG ulMACLen; --} CK_CCM_MESSAGE_PARAMS; -- --typedef CK_CCM_MESSAGE_PARAMS CK_CCM_MESSAGE_PARAMS_PTR; -- --/* Deprecated. Use CK_GCM_PARAMS */ --typedef struct CK_AES_GCM_PARAMS { -- CK_BYTE_PTR pIv; -- CK_ULONG ulIvLen; -- CK_ULONG ulIvBits; -- CK_BYTE_PTR pAAD; -- CK_ULONG ulAADLen; -- CK_ULONG ulTagBits; --} CK_AES_GCM_PARAMS; -- --typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR; -- --/* Deprecated. Use CK_CCM_PARAMS */ --typedef struct CK_AES_CCM_PARAMS { -- CK_ULONG ulDataLen; -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceLen; -- CK_BYTE_PTR pAAD; -- CK_ULONG ulAADLen; -- CK_ULONG ulMACLen; --} CK_AES_CCM_PARAMS; -- --typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR; -- --typedef struct CK_CAMELLIA_CTR_PARAMS { -- CK_ULONG ulCounterBits; -- CK_BYTE cb[16]; --} CK_CAMELLIA_CTR_PARAMS; -- --typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; -- --typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { -- CK_BYTE iv[16]; -- CK_BYTE_PTR pData; -- CK_ULONG length; --} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; -- --typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ -- CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; -- --typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { -- CK_BYTE iv[16]; -- CK_BYTE_PTR pData; -- CK_ULONG length; --} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; -- --typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ -- CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; -- -+/* DSA Param Gen is new for v2.40 */ - typedef struct CK_DSA_PARAMETER_GEN_PARAM { - CK_MECHANISM_TYPE hash; -- CK_BYTE_PTR pSeed; -- CK_ULONG ulSeedLen; -- CK_ULONG ulIndex; -+ CK_BYTE_PTR pSeed; -+ CK_ULONG ulSeedLen; -+ CK_ULONG ulIndex; - } CK_DSA_PARAMETER_GEN_PARAM; - - typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR; - -+/* XXXX_AES_KEY_WRAP is new for v2.40 */ - typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS { -- CK_ULONG ulAESKeyBits; -+ CK_ULONG ulAESKeyBits; - CK_EC_KDF_TYPE kdf; -- CK_ULONG ulSharedDataLen; -- CK_BYTE_PTR pSharedData; -+ CK_ULONG ulSharedDataLen; -+ CK_BYTE_PTR pSharedData; - } CK_ECDH_AES_KEY_WRAP_PARAMS; - - typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR; - --typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; -- --typedef CK_ULONG CK_CERTIFICATE_CATEGORY; -- - typedef struct CK_RSA_AES_KEY_WRAP_PARAMS { -- CK_ULONG ulAESKeyBits; -+ CK_ULONG ulAESKeyBits; - CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; - } CK_RSA_AES_KEY_WRAP_PARAMS; - - typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR; - --typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { -- CK_SSL3_RANDOM_DATA RandomInfo; -- CK_VERSION_PTR pVersion; -- CK_MECHANISM_TYPE prfHashMechanism; --} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; -- --typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \ -- CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; -- --typedef struct CK_TLS12_KEY_MAT_PARAMS { -- CK_ULONG ulMacSizeInBits; -- CK_ULONG ulKeySizeInBits; -- CK_ULONG ulIVSizeInBits; -- CK_BBOOL bIsExport; -- CK_SSL3_RANDOM_DATA RandomInfo; -- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -- CK_MECHANISM_TYPE prfHashMechanism; --} CK_TLS12_KEY_MAT_PARAMS; -- --typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; -- --typedef struct CK_TLS_KDF_PARAMS { -- CK_MECHANISM_TYPE prfMechanism; -- CK_BYTE_PTR pLabel; -- CK_ULONG ulLabelLength; -- CK_SSL3_RANDOM_DATA RandomInfo; -- CK_BYTE_PTR pContextData; -- CK_ULONG ulContextDataLength; --} CK_TLS_KDF_PARAMS; -- --typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR; -- --typedef struct CK_TLS_MAC_PARAMS { -- CK_MECHANISM_TYPE prfHashMechanism; -- CK_ULONG ulMacLength; -- CK_ULONG ulServerOrClient; --} CK_TLS_MAC_PARAMS; -- --typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; -- -+/* GOSTR3410 is new for v2.40 */ - typedef struct CK_GOSTR3410_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; -- CK_BYTE_PTR pPublicData; -- CK_ULONG ulPublicDataLen; -- CK_BYTE_PTR pUKM; -- CK_ULONG ulUKMLen; -+ CK_BYTE_PTR pPublicData; -+ CK_ULONG ulPublicDataLen; -+ CK_BYTE_PTR pUKM; -+ CK_ULONG ulUKMLen; - } CK_GOSTR3410_DERIVE_PARAMS; - - typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR; - - typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS { -- CK_BYTE_PTR pWrapOID; -- CK_ULONG ulWrapOIDLen; -- CK_BYTE_PTR pUKM; -- CK_ULONG ulUKMLen; -+ CK_BYTE_PTR pWrapOID; -+ CK_ULONG ulWrapOIDLen; -+ CK_BYTE_PTR pUKM; -+ CK_ULONG ulUKMLen; - CK_OBJECT_HANDLE hKey; - } CK_GOSTR3410_KEY_WRAP_PARAMS; - - typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR; - --typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { -- CK_BYTE iv[16]; -- CK_BYTE_PTR pData; -- CK_ULONG length; --} CK_SEED_CBC_ENCRYPT_DATA_PARAMS; -- --typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ -- CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; -- --/* -- * New PKCS 11 v3.0 data structures. -- */ -- --typedef CK_ULONG CK_PROFILE_ID; --typedef CK_PROFILE_ID CK_PTR CK_PROFILE_ID_PTR; -- --/* Typedefs for Flexible KDF */ --typedef CK_ULONG CK_PRF_DATA_TYPE; --typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; --#define CK_SP800_108_ITERATION_VARIABLE 0x00000001UL --#define CK_SP800_108_OPTIONAL_COUNTER 0x00000002UL --#define CK_SP800_108_DKM_LENGTH 0x00000003UL --#define CK_SP800_108_BYTE_ARRAY 0x00000004UL --#define CK_SP800_108_COUNTER CK_SP800_108_OPTIONAL_COUNTER -- --typedef struct CK_PRF_DATA_PARAM --{ -- CK_PRF_DATA_TYPE type; -- CK_VOID_PTR pValue; -- CK_ULONG ulValueLen; --} CK_PRF_DATA_PARAM; -- --typedef CK_PRF_DATA_PARAM CK_PTR CK_PRF_DATA_PARAM_PTR; -- -- --typedef struct CK_SP800_108_COUNTER_FORMAT --{ -- CK_BBOOL bLittleEndian; -- CK_ULONG ulWidthInBits; --} CK_SP800_108_COUNTER_FORMAT; -- --typedef CK_SP800_108_COUNTER_FORMAT CK_PTR CK_SP800_108_COUNTER_FORMAT_PTR; -- --typedef CK_ULONG CK_SP800_108_DKM_LENGTH_METHOD; --#define CK_SP800_108_DKM_LENGTH_SUM_OF_KEYS 0x00000001UL --#define CK_SP800_108_DKM_LENGTH_SUM_OF_SEGMENTS 0x00000002UL -- --typedef struct CK_SP800_108_DKM_LENGTH_FORMAT --{ -- CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; -- CK_BBOOL bLittleEndian; -- CK_ULONG ulWidthInBits; --} CK_SP800_108_DKM_LENGTH_FORMAT; -- --typedef CK_SP800_108_DKM_LENGTH_FORMAT \ -- CK_PTR CK_SP800_108_DKM_LENGTH_FORMAT_PTR; -- --typedef struct CK_DERIVED_KEY --{ -- CK_ATTRIBUTE_PTR pTemplate; -- CK_ULONG ulAttributeCount; -- CK_OBJECT_HANDLE_PTR phKey; --} CK_DERIVED_KEY; -- --typedef CK_DERIVED_KEY CK_PTR CK_DERIVED_KEY_PTR; -- --typedef struct CK_SP800_108_KDF_PARAMS --{ -- CK_SP800_108_PRF_TYPE prfType; -- CK_ULONG ulNumberOfDataParams; -- CK_PRF_DATA_PARAM_PTR pDataParams; -- CK_ULONG ulAdditionalDerivedKeys; -- CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; --} CK_SP800_108_KDF_PARAMS; -- --typedef CK_SP800_108_KDF_PARAMS CK_PTR CK_SP800_108_KDF_PARAMS_PTR; -- --typedef struct CK_SP800_108_FEEDBACK_KDF_PARAMS --{ -- CK_SP800_108_PRF_TYPE prfType; -- CK_ULONG ulNumberOfDataParams; -- CK_PRF_DATA_PARAM_PTR pDataParams; -- CK_ULONG ulIVLen; -- CK_BYTE_PTR pIV; -- CK_ULONG ulAdditionalDerivedKeys; -- CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; --} CK_SP800_108_FEEDBACK_KDF_PARAMS; -- --typedef CK_SP800_108_FEEDBACK_KDF_PARAMS \ -- CK_PTR CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR; -- --/* EDDSA */ -+/* EDDSA and XEDDSA are new for v3.0 */ - typedef struct CK_EDDSA_PARAMS { -- CK_BBOOL phFlag; -- CK_ULONG ulContextDataLen; -+ CK_BBOOL phFlag; -+ CK_ULONG ulContextDataLen; - CK_BYTE_PTR pContextData; - } CK_EDDSA_PARAMS; -+typedef CK_ULONG CK_XEDDSA_HASH_TYPE; -+typedef CK_XEDDSA_HASH_TYPE CK_PTR CK_XEDDSA_HASH_TYPE_PTR; - --typedef CK_EDDSA_PARAMS CK_PTR CK_EDDSA_PARAMS_PTR; -- --/* Extended ChaCha20/Salsa20 support*/ --typedef struct CK_CHACHA20_PARAMS { -- CK_BYTE_PTR pBlockCounter; -- CK_ULONG blockCounterBits; -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceBits; --} CK_CHACHA20_PARAMS; -- --typedef CK_CHACHA20_PARAMS CK_PTR CK_CHACHA20_PARAMS_PTR; -- --typedef struct CK_SALSA20_PARAMS { -- CK_BYTE_PTR pBlockCounter; -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceBits; --} CK_SALSA20_PARAMS; -- --typedef CK_SALSA20_PARAMS CK_PTR CK_SALSA20_PARAMS_PTR; -- --typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceLen; -- CK_BYTE_PTR pAAD; -- CK_ULONG ulAADLen; --} CK_SALSA20_CHACHA20_POLY1305_PARAMS; -- --typedef CK_SALSA20_CHACHA20_POLY1305_PARAMS \ -- CK_PTR CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR; -- --typedef struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { -- CK_BYTE_PTR pNonce; -- CK_ULONG ulNonceLen; -- CK_BYTE_PTR pTag; --} CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS; -- --typedef CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS \ -- CK_PTR CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS_PTR; -+typedef struct CK_XEDDSA_PARAMS { -+ CK_XEDDSA_HASH_TYPE hash; -+} CK_XEDDSA_PARAMS; -+typedef CK_XEDDSA_PARAMS CK_PTR CK_XEDDSA_PARAMS_PTR; - -+/* X3DH and Ratchet are new in v3.0 */ - typedef CK_ULONG CK_X3DH_KDF_TYPE; - typedef CK_X3DH_KDF_TYPE CK_PTR CK_X3DH_KDF_TYPE_PTR; - --/* X3dh, ratchet */ - typedef struct CK_X3DH_INITIATE_PARAMS { - CK_X3DH_KDF_TYPE kdf; - CK_OBJECT_HANDLE pPeer_identity; - CK_OBJECT_HANDLE pPeer_prekey; -- CK_BYTE_PTR pPrekey_signature; -- CK_BYTE_PTR pOnetime_key; -+ CK_BYTE_PTR pPrekey_signature; -+ CK_BYTE_PTR pOnetime_key; - CK_OBJECT_HANDLE pOwn_identity; - CK_OBJECT_HANDLE pOwn_ephemeral; - } CK_X3DH_INITIATE_PARAMS; - - typedef struct CK_X3DH_RESPOND_PARAMS { - CK_X3DH_KDF_TYPE kdf; -- CK_BYTE_PTR pIdentity_id; -- CK_BYTE_PTR pPrekey_id; -- CK_BYTE_PTR pOnetime_id; -+ CK_BYTE_PTR pIdentity_id; -+ CK_BYTE_PTR pPrekey_id; -+ CK_BYTE_PTR pOnetime_id; - CK_OBJECT_HANDLE pInitiator_identity; -- CK_BYTE_PTR pInitiator_ephemeral; -+ CK_BYTE_PTR pInitiator_ephemeral; - } CK_X3DH_RESPOND_PARAMS; - - typedef CK_ULONG CK_X2RATCHET_KDF_TYPE; - typedef CK_X2RATCHET_KDF_TYPE CK_PTR CK_X2RATCHET_KDF_TYPE_PTR; - - typedef struct CK_X2RATCHET_INITIALIZE_PARAMS { -- CK_BYTE_PTR sk; -- CK_OBJECT_HANDLE peer_public_prekey; -- CK_OBJECT_HANDLE peer_public_identity; -- CK_OBJECT_HANDLE own_public_identity; -- CK_BBOOL bEncryptedHeader; -- CK_ULONG eCurve; -- CK_MECHANISM_TYPE aeadMechanism; -+ CK_BYTE_PTR sk; -+ CK_OBJECT_HANDLE peer_public_prekey; -+ CK_OBJECT_HANDLE peer_public_identity; -+ CK_OBJECT_HANDLE own_public_identity; -+ CK_BBOOL bEncryptedHeader; -+ CK_ULONG eCurve; -+ CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; - } CK_X2RATCHET_INITIALIZE_PARAMS; - --typedef CK_X2RATCHET_INITIALIZE_PARAMS \ -- CK_PTR CK_X2RATCHET_INITIALIZE_PARAMS_PTR; -+typedef CK_X2RATCHET_INITIALIZE_PARAMS -+ CK_PTR CK_X2RATCHET_INITIALIZE_PARAMS_PTR; - - typedef struct CK_X2RATCHET_RESPOND_PARAMS { -- CK_BYTE_PTR sk; -- CK_OBJECT_HANDLE own_prekey; -- CK_OBJECT_HANDLE initiator_identity; -- CK_OBJECT_HANDLE own_public_identity; -- CK_BBOOL bEncryptedHeader; -- CK_ULONG eCurve; -- CK_MECHANISM_TYPE aeadMechanism; -+ CK_BYTE_PTR sk; -+ CK_OBJECT_HANDLE own_prekey; -+ CK_OBJECT_HANDLE initiator_identity; -+ CK_OBJECT_HANDLE own_public_identity; -+ CK_BBOOL bEncryptedHeader; -+ CK_ULONG eCurve; -+ CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; - } CK_X2RATCHET_RESPOND_PARAMS; --typedef CK_X2RATCHET_RESPOND_PARAMS \ -- CK_PTR CK_X2RATCHET_RESPOND_PARAMS_PTR; -+typedef CK_X2RATCHET_RESPOND_PARAMS -+ CK_PTR CK_X2RATCHET_RESPOND_PARAMS_PTR; - --typedef CK_ULONG CK_XEDDSA_HASH_TYPE; --typedef CK_XEDDSA_HASH_TYPE CK_PTR CK_XEDDSA_HASH_TYPE_PTR; -+/* NSS Specific defines */ -+/* stuff that for historic reasons is in this header file but should have -+ * been in pkcs11n.h */ -+#define CKK_INVALID_KEY_TYPE 0xffffffffUL - --/* XEDDSA */ --typedef struct CK_XEDDSA_PARAMS { -- CK_XEDDSA_HASH_TYPE hash; --} CK_XEDDSA_PARAMS; --typedef CK_XEDDSA_PARAMS CK_PTR CK_XEDDSA_PARAMS_PTR; -+#include "pkcs11n.h" - --typedef struct CK_HKDF_PARAMS { -- CK_BBOOL bExtract; -- CK_BBOOL bExpand; -- CK_MECHANISM_TYPE prfHashMechanism; -- CK_ULONG ulSaltType; -- CK_BYTE_PTR pSalt; -- CK_ULONG ulSaltLen; -- CK_OBJECT_HANDLE hSaltKey; -- CK_BYTE_PTR pInfo; -- CK_ULONG ulInfoLen; --} CK_HKDF_PARAMS; --typedef CK_HKDF_PARAMS CK_PTR CK_HKDF_PARAMS_PTR; -- --#define CKF_HKDF_SALT_NULL 0x00000001UL --#define CKF_HKDF_SALT_DATA 0x00000002UL --#define CKF_HKDF_SALT_KEY 0x00000004UL -- --#endif /* _PKCS11T_H_ */ -+/* undo packing */ -+#include "pkcs11u.h" - -+#endif ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11u.h -@@ -0,0 +1,22 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+/* -+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document -+ * is granted provided that it is identified as "RSA Security Inc. Public-Key -+ * Cryptography Standards (PKCS)" in all material mentioning or referencing -+ * this document. -+ */ -+/* -+ * reset any packing set by pkcs11p.h -+ */ -+ -+#if defined(_WIN32) || defined(_WINDOWS) -+#ifdef __clang__ -+#pragma clang diagnostic ignored "-Wpragma-pack" -+#endif -+#ifdef _MSC_VER -+#pragma warning(disable : 4103) -+#endif -+#pragma pack(pop, cryptoki) -+#endif ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/prcpucfg.h -@@ -0,0 +1,1319 @@ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+/* -+ * This file is used by not only Linux but also other glibc systems -+ * such as GNU/Hurd and GNU/k*BSD. -+ */ -+ -+#ifndef nspr_cpucfg___ -+#define nspr_cpucfg___ -+ -+#ifndef XP_UNIX -+#define XP_UNIX -+#endif -+ -+#if !defined(LINUX) && defined(__linux__) -+#define LINUX -+#endif -+ -+#ifdef __FreeBSD_kernel__ -+#define PR_AF_INET6 28 /* same as AF_INET6 */ -+#elif defined(__GNU__) -+#define PR_AF_INET6 26 /* same as AF_INET6 */ -+#else -+#define PR_AF_INET6 10 /* same as AF_INET6 */ -+#endif -+ -+#ifdef __powerpc64__ -+ -+#ifdef __LITTLE_ENDIAN__ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#else -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+#endif -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__powerpc__) -+ -+#ifdef __LITTLE_ENDIAN__ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#else -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+#endif -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__alpha) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__ia64__) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__x86_64__) -+ -+#ifdef __ILP32__ -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#else -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#endif -+ -+#elif defined(__mc68000__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 2 -+#define PR_ALIGN_OF_LONG 2 -+#define PR_ALIGN_OF_INT64 2 -+#define PR_ALIGN_OF_FLOAT 2 -+#define PR_ALIGN_OF_DOUBLE 2 -+#define PR_ALIGN_OF_POINTER 2 -+#define PR_ALIGN_OF_WORD 2 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__sparc__) && defined (__arch64__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__sparc__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__i386__) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__mips__) -+ -+/* For _ABI64 */ -+#include -+ -+#ifdef __MIPSEB__ -+#define IS_BIG_ENDIAN 1 -+#undef IS_LITTLE_ENDIAN -+#elif defined(__MIPSEL__) -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#else -+#error "Unknown MIPS endianness." -+#endif -+ -+#if _MIPS_SIM == _ABI64 -+ -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#else /* _ABI64 */ -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#endif /* _ABI64 */ -+ -+#elif defined(__arm__) -+ -+#ifdef __ARMEB__ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+#elif defined(__ARMEL__) -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#else -+#error "Unknown ARM endianness." -+#endif -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__aarch64__) -+ -+#ifdef __AARCH64EB__ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+#elif defined(__AARCH64EL__) -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#else -+#error "Unknown Aarch64 endianness." -+#endif -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__hppa__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__s390x__) -+ -+#define IS_BIG_ENDIAN 1 -+#undef IS_LITTLE_ENDIAN -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__s390__) -+ -+#define IS_BIG_ENDIAN 1 -+#undef IS_LITTLE_ENDIAN -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__sh__) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__avr32__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__m32r__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__or1k__) -+ -+#undef IS_LITTLE_ENDIAN -+#define IS_BIG_ENDIAN 1 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__riscv) && (__riscv_xlen == 32) -+ -+#undef IS_BIG_ENDIAN -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__riscv) && (__riscv_xlen == 64) -+ -+#undef IS_BIG_ENDIAN -+#define IS_LITTLE_ENDIAN 1 -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 8 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__arc__) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__nios2__) || defined(__microblaze__) || defined(__nds32__) || \ -+ defined(__xtensa__) -+ -+#if defined(__microblaze__) && defined(__BIG_ENDIAN__) -+#define IS_BIG_ENDIAN 1 -+#undef IS_LITTLE_ENDIAN -+#else -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+#endif -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 8 -+#define PR_BYTES_PER_LONG 4 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 4 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 64 -+#define PR_BITS_PER_LONG 32 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 32 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 6 -+#define PR_BITS_PER_LONG_LOG2 5 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 5 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 4 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 4 -+#define PR_ALIGN_OF_POINTER 4 -+#define PR_ALIGN_OF_WORD 4 -+ -+#define PR_BYTES_PER_WORD_LOG2 2 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#elif defined(__e2k__) -+ -+#define IS_LITTLE_ENDIAN 1 -+#undef IS_BIG_ENDIAN -+ -+#define IS_64 -+ -+#define PR_BYTES_PER_BYTE 1 -+#define PR_BYTES_PER_SHORT 2 -+#define PR_BYTES_PER_INT 4 -+#define PR_BYTES_PER_INT64 4 -+#define PR_BYTES_PER_LONG 8 -+#define PR_BYTES_PER_FLOAT 4 -+#define PR_BYTES_PER_DOUBLE 8 -+#define PR_BYTES_PER_WORD 8 -+#define PR_BYTES_PER_DWORD 8 -+ -+#define PR_BITS_PER_BYTE 8 -+#define PR_BITS_PER_SHORT 16 -+#define PR_BITS_PER_INT 32 -+#define PR_BITS_PER_INT64 32 -+#define PR_BITS_PER_LONG 64 -+#define PR_BITS_PER_FLOAT 32 -+#define PR_BITS_PER_DOUBLE 64 -+#define PR_BITS_PER_WORD 64 -+ -+#define PR_BITS_PER_BYTE_LOG2 3 -+#define PR_BITS_PER_SHORT_LOG2 4 -+#define PR_BITS_PER_INT_LOG2 5 -+#define PR_BITS_PER_INT64_LOG2 5 -+#define PR_BITS_PER_LONG_LOG2 6 -+#define PR_BITS_PER_FLOAT_LOG2 5 -+#define PR_BITS_PER_DOUBLE_LOG2 6 -+#define PR_BITS_PER_WORD_LOG2 6 -+ -+#define PR_ALIGN_OF_SHORT 2 -+#define PR_ALIGN_OF_INT 4 -+#define PR_ALIGN_OF_LONG 8 -+#define PR_ALIGN_OF_INT64 4 -+#define PR_ALIGN_OF_FLOAT 4 -+#define PR_ALIGN_OF_DOUBLE 8 -+#define PR_ALIGN_OF_POINTER 8 -+#define PR_ALIGN_OF_WORD 8 -+ -+#define PR_BYTES_PER_WORD_LOG2 3 -+#define PR_BYTES_PER_DWORD_LOG2 3 -+ -+#else -+ -+#error "Unknown CPU architecture" -+ -+#endif -+ -+#ifndef HAVE_LONG_LONG -+#define HAVE_LONG_LONG -+#endif -+#if PR_ALIGN_OF_DOUBLE == 8 -+#define HAVE_ALIGNED_DOUBLES -+#endif -+#if PR_ALIGN_OF_INT64 == 8 -+#define HAVE_ALIGNED_LONGLONGS -+#endif -+ -+#ifndef NO_NSPR_10_SUPPORT -+ -+#define BYTES_PER_BYTE PR_BYTES_PER_BYTE -+#define BYTES_PER_SHORT PR_BYTES_PER_SHORT -+#define BYTES_PER_INT PR_BYTES_PER_INT -+#define BYTES_PER_INT64 PR_BYTES_PER_INT64 -+#define BYTES_PER_LONG PR_BYTES_PER_LONG -+#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT -+#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE -+#define BYTES_PER_WORD PR_BYTES_PER_WORD -+#define BYTES_PER_DWORD PR_BYTES_PER_DWORD -+ -+#define BITS_PER_BYTE PR_BITS_PER_BYTE -+#define BITS_PER_SHORT PR_BITS_PER_SHORT -+#define BITS_PER_INT PR_BITS_PER_INT -+#define BITS_PER_INT64 PR_BITS_PER_INT64 -+#define BITS_PER_LONG PR_BITS_PER_LONG -+#define BITS_PER_FLOAT PR_BITS_PER_FLOAT -+#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE -+#define BITS_PER_WORD PR_BITS_PER_WORD -+ -+#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2 -+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2 -+#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2 -+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2 -+#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2 -+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2 -+#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2 -+#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2 -+ -+#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT -+#define ALIGN_OF_INT PR_ALIGN_OF_INT -+#define ALIGN_OF_LONG PR_ALIGN_OF_LONG -+#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64 -+#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT -+#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE -+#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER -+#define ALIGN_OF_WORD PR_ALIGN_OF_WORD -+ -+#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2 -+#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2 -+#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2 -+ -+#endif /* NO_NSPR_10_SUPPORT */ -+ -+#endif /* nspr_cpucfg___ */ ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/prtypes.h -@@ -0,0 +1,520 @@ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+/* -+** File: prtypes.h -+** Description: Definitions of NSPR's basic types -+** -+** Prototypes and macros used to make up for deficiencies that we have found -+** in ANSI environments. -+** -+** Since we do not wrap and all the other standard headers, authors -+** of portable code will not know in general that they need these definitions. -+** Instead of requiring these authors to find the dependent uses in their code -+** and take the following steps only in those C files, we take steps once here -+** for all C files. -+**/ -+ -+#ifndef prtypes_h___ -+#define prtypes_h___ -+ -+#ifdef MDCPUCFG -+#include MDCPUCFG -+#else -+#include "prcpucfg.h" -+#endif -+ -+#include -+ -+/*********************************************************************** -+** MACROS: PR_EXTERN -+** PR_IMPLEMENT -+** DESCRIPTION: -+** These are only for externally visible routines and globals. For -+** internal routines, just use "extern" for type checking and that -+** will not export internal cross-file or forward-declared symbols. -+** Define a macro for declaring procedures return types. We use this to -+** deal with windoze specific type hackery for DLL definitions. Use -+** PR_EXTERN when the prototype for the method is declared. Use -+** PR_IMPLEMENT for the implementation of the method. -+** -+** Example: -+** in dowhim.h -+** PR_EXTERN( void ) DoWhatIMean( void ); -+** in dowhim.c -+** PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; } -+** -+** -+***********************************************************************/ -+#if defined(WIN32) -+ -+#define PR_EXPORT(__type) extern __declspec(dllexport) __type -+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -+#define PR_IMPORT(__type) __declspec(dllimport) __type -+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type -+ -+#define PR_EXTERN(__type) extern __declspec(dllexport) __type -+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type -+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type -+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type -+ -+#define PR_CALLBACK -+#define PR_CALLBACK_DECL -+#define PR_STATIC_CALLBACK(__x) static __x -+ -+#elif defined(XP_OS2) && defined(__declspec) -+ -+#define PR_EXPORT(__type) extern __declspec(dllexport) __type -+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type -+#define PR_IMPORT(__type) extern __declspec(dllimport) __type -+#define PR_IMPORT_DATA(__type) extern __declspec(dllimport) __type -+ -+#define PR_EXTERN(__type) extern __declspec(dllexport) __type -+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type -+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type -+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type -+ -+#define PR_CALLBACK -+#define PR_CALLBACK_DECL -+#define PR_STATIC_CALLBACK(__x) static __x -+ -+#else /* Unix */ -+ -+/* GCC 3.3 and later support the visibility attribute. */ -+#if (__GNUC__ >= 4) || \ -+ (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -+#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default"))) -+#else -+#define PR_VISIBILITY_DEFAULT -+#endif -+ -+#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type -+#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type -+#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type -+#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type -+ -+#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type -+#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type -+#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type -+#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type -+#define PR_CALLBACK -+#define PR_CALLBACK_DECL -+#define PR_STATIC_CALLBACK(__x) static __x -+ -+#endif -+ -+#if defined(_NSPR_BUILD_) -+#define NSPR_API(__type) PR_EXPORT(__type) -+#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type) -+#else -+#define NSPR_API(__type) PR_IMPORT(__type) -+#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type) -+#endif -+ -+/*********************************************************************** -+** MACROS: PR_BEGIN_MACRO -+** PR_END_MACRO -+** DESCRIPTION: -+** Macro body brackets so that macros with compound statement definitions -+** behave syntactically more like functions when called. -+***********************************************************************/ -+#define PR_BEGIN_MACRO do { -+#define PR_END_MACRO } while (0) -+ -+/*********************************************************************** -+** MACROS: PR_BEGIN_EXTERN_C -+** PR_END_EXTERN_C -+** DESCRIPTION: -+** Macro shorthands for conditional C++ extern block delimiters. -+***********************************************************************/ -+#ifdef __cplusplus -+#define PR_BEGIN_EXTERN_C extern "C" { -+#define PR_END_EXTERN_C } -+#else -+#define PR_BEGIN_EXTERN_C -+#define PR_END_EXTERN_C -+#endif -+ -+/*********************************************************************** -+** MACROS: PR_BIT -+** PR_BITMASK -+** DESCRIPTION: -+** Bit masking macros. XXX n must be <= 31 to be portable -+***********************************************************************/ -+#define PR_BIT(n) ((PRUint32)1 << (n)) -+#define PR_BITMASK(n) (PR_BIT(n) - 1) -+ -+/*********************************************************************** -+** MACROS: PR_ROUNDUP -+** PR_MIN -+** PR_MAX -+** PR_ABS -+** DESCRIPTION: -+** Commonly used macros for operations on compatible types. -+***********************************************************************/ -+#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) -+#define PR_MIN(x,y) ((x)<(y)?(x):(y)) -+#define PR_MAX(x,y) ((x)>(y)?(x):(y)) -+#define PR_ABS(x) ((x)<0?-(x):(x)) -+ -+/*********************************************************************** -+** MACROS: PR_ARRAY_SIZE -+** DESCRIPTION: -+** The number of elements in an array. -+***********************************************************************/ -+#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) -+ -+PR_BEGIN_EXTERN_C -+ -+/* -+** Starting in NSPR 4.9.5, NSPR's exact-width integer types should match -+** the exact-width integer types defined in . This allows sloppy -+** code to use PRInt{N} and int{N}_t interchangeably. -+** -+** The 8-bit and 16-bit integer types can only be defined using char and -+** short. All platforms define the 32-bit integer types using int. So only -+** the 64-bit integer types could be defined differently. -+** -+** NSPR's original strategy was to use the "shortest" 64-bit integer type: -+** if long is 64-bit, then prefer it over long long. This strategy is also -+** used by Linux/glibc, FreeBSD, and NetBSD. -+** -+** Other platforms use a different strategy: simply define the 64-bit -+** integer types using long long. We define the PR_ALTERNATE_INT64_TYPEDEF -+** macro on these platforms. Note that PR_ALTERNATE_INT64_TYPEDEF is for -+** internal use by NSPR headers only. Do not define or test this macro in -+** your code. -+** -+** NOTE: NSPR can't use because C99 requires C++ code to define -+** __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS to make all the macros -+** defined in available. This strange requirement is gone in -+** C11. When most platforms ignore this C99 requirement, NSPR will be able -+** to use . A patch to do that is in NSPR bug 634793. -+*/ -+ -+#if defined(__APPLE__) || defined(__OpenBSD__) -+#define PR_ALTERNATE_INT64_TYPEDEF -+#endif -+ -+/************************************************************************ -+** TYPES: PRUint8 -+** PRInt8 -+** DESCRIPTION: -+** The int8 types are known to be 8 bits each. There is no type that -+** is equivalent to a plain "char". -+************************************************************************/ -+#if PR_BYTES_PER_BYTE == 1 -+typedef unsigned char PRUint8; -+/* -+** There are two scenarios that require us to define PRInt8 as type 'char'. -+** (1) -+** Some cfront-based C++ compilers do not like 'signed char' and -+** issue the warning message: -+** warning: "signed" not implemented (ignored) -+** For these compilers, we have to define PRInt8 as plain 'char'. -+** Make sure that plain 'char' is indeed signed under these compilers. -+** (2) -+** Mozilla C++ code expects the PRInt{N} and int{N}_t types to match (see bug -+** 634793). If a platform defines int8_t as 'char', but NSPR defines it as -+** 'signed char', it results in a type mismatch. -+** On such platforms we define PRInt8 as 'char' to avoid the mismatch. -+*/ -+#if (defined(HPUX) && defined(__cplusplus) /* reason 1*/ \ -+ && !defined(__GNUC__) && __cplusplus < 199707L) \ -+ || (defined(SCO) && defined(__cplusplus) /* reason 1 */ \ -+ && !defined(__GNUC__) && __cplusplus == 1L) \ -+ || (defined(__sun) && defined(__cplusplus)) /* reason 2 */ -+typedef char PRInt8; -+#else -+typedef signed char PRInt8; -+#endif -+#else -+#error No suitable type for PRInt8/PRUint8 -+#endif -+ -+/************************************************************************ -+ * MACROS: PR_INT8_MAX -+ * PR_INT8_MIN -+ * PR_UINT8_MAX -+ * DESCRIPTION: -+ * The maximum and minimum values of a PRInt8 or PRUint8. -+************************************************************************/ -+ -+#define PR_INT8_MAX 127 -+#define PR_INT8_MIN (-128) -+#define PR_UINT8_MAX 255U -+ -+/************************************************************************ -+** TYPES: PRUint16 -+** PRInt16 -+** DESCRIPTION: -+** The int16 types are known to be 16 bits each. -+************************************************************************/ -+#if PR_BYTES_PER_SHORT == 2 -+typedef unsigned short PRUint16; -+typedef short PRInt16; -+#else -+#error No suitable type for PRInt16/PRUint16 -+#endif -+ -+/************************************************************************ -+ * MACROS: PR_INT16_MAX -+ * PR_INT16_MIN -+ * PR_UINT16_MAX -+ * DESCRIPTION: -+ * The maximum and minimum values of a PRInt16 or PRUint16. -+************************************************************************/ -+ -+#define PR_INT16_MAX 32767 -+#define PR_INT16_MIN (-32768) -+#define PR_UINT16_MAX 65535U -+ -+/************************************************************************ -+** TYPES: PRUint32 -+** PRInt32 -+** DESCRIPTION: -+** The int32 types are known to be 32 bits each. -+************************************************************************/ -+#if PR_BYTES_PER_INT == 4 -+typedef unsigned int PRUint32; -+typedef int PRInt32; -+#define PR_INT32(x) x -+#define PR_UINT32(x) x ## U -+#elif PR_BYTES_PER_LONG == 4 -+typedef unsigned long PRUint32; -+typedef long PRInt32; -+#define PR_INT32(x) x ## L -+#define PR_UINT32(x) x ## UL -+#else -+#error No suitable type for PRInt32/PRUint32 -+#endif -+ -+/************************************************************************ -+ * MACROS: PR_INT32_MAX -+ * PR_INT32_MIN -+ * PR_UINT32_MAX -+ * DESCRIPTION: -+ * The maximum and minimum values of a PRInt32 or PRUint32. -+************************************************************************/ -+ -+#define PR_INT32_MAX PR_INT32(2147483647) -+#define PR_INT32_MIN (-PR_INT32_MAX - 1) -+#define PR_UINT32_MAX PR_UINT32(4294967295) -+ -+/************************************************************************ -+** TYPES: PRUint64 -+** PRInt64 -+** DESCRIPTION: -+** The int64 types are known to be 64 bits each. Care must be used when -+** declaring variables of type PRUint64 or PRInt64. Different hardware -+** architectures and even different compilers have varying support for -+** 64 bit values. The only guaranteed portability requires the use of -+** the LL_ macros (see prlong.h). -+** -+** MACROS: PR_INT64 -+** PR_UINT64 -+** DESCRIPTION: -+** The PR_INT64 and PR_UINT64 macros provide a portable way for -+** specifying 64-bit integer constants. They can only be used if -+** PRInt64 and PRUint64 are defined as compiler-supported 64-bit -+** integer types (i.e., if HAVE_LONG_LONG is defined, which is true -+** for all the supported compilers topday). If PRInt64 and PRUint64 -+** are defined as structs, the LL_INIT macro defined in prlong.h has -+** to be used. -+** -+** MACROS: PR_INT64_MAX -+** PR_INT64_MIN -+** PR_UINT64_MAX -+** DESCRIPTION: -+** The maximum and minimum values of a PRInt64 or PRUint64. -+************************************************************************/ -+#ifdef HAVE_LONG_LONG -+/* Keep this in sync with prlong.h. */ -+#if PR_BYTES_PER_LONG == 8 && !defined(PR_ALTERNATE_INT64_TYPEDEF) -+typedef long PRInt64; -+typedef unsigned long PRUint64; -+#define PR_INT64(x) x ## L -+#define PR_UINT64(x) x ## UL -+#elif defined(WIN32) && !defined(__GNUC__) -+typedef __int64 PRInt64; -+typedef unsigned __int64 PRUint64; -+#define PR_INT64(x) x ## i64 -+#define PR_UINT64(x) x ## ui64 -+#else -+typedef long long PRInt64; -+typedef unsigned long long PRUint64; -+#define PR_INT64(x) x ## LL -+#define PR_UINT64(x) x ## ULL -+#endif /* PR_BYTES_PER_LONG == 8 */ -+ -+#define PR_INT64_MAX PR_INT64(0x7fffffffffffffff) -+#define PR_INT64_MIN (-PR_INT64_MAX - 1) -+#define PR_UINT64_MAX PR_UINT64(-1) -+#else /* !HAVE_LONG_LONG */ -+typedef struct { -+#ifdef IS_LITTLE_ENDIAN -+ PRUint32 lo, hi; -+#else -+ PRUint32 hi, lo; -+#endif -+} PRInt64; -+typedef PRInt64 PRUint64; -+ -+#define PR_INT64_MAX (PRInt64){0x7fffffff, 0xffffffff} -+#define PR_INT64_MIN (PRInt64){0xffffffff, 0xffffffff} -+#define PR_UINT64_MAX (PRUint64){0xffffffff, 0xffffffff} -+ -+#endif /* !HAVE_LONG_LONG */ -+ -+/************************************************************************ -+** TYPES: PRUintn -+** PRIntn -+** DESCRIPTION: -+** The PRIntn types are most appropriate for automatic variables. They are -+** guaranteed to be at least 16 bits, though various architectures may -+** define them to be wider (e.g., 32 or even 64 bits). These types are -+** never valid for fields of a structure. -+************************************************************************/ -+#if PR_BYTES_PER_INT >= 2 -+typedef int PRIntn; -+typedef unsigned int PRUintn; -+#else -+#error 'sizeof(int)' not sufficient for platform use -+#endif -+ -+/************************************************************************ -+** TYPES: PRFloat64 -+** DESCRIPTION: -+** NSPR's floating point type is always 64 bits. -+************************************************************************/ -+typedef double PRFloat64; -+ -+/************************************************************************ -+** TYPES: PRSize -+** DESCRIPTION: -+** A type for representing the size of objects. -+************************************************************************/ -+typedef size_t PRSize; -+ -+ -+/************************************************************************ -+** TYPES: PROffset32, PROffset64 -+** DESCRIPTION: -+** A type for representing byte offsets from some location. -+************************************************************************/ -+typedef PRInt32 PROffset32; -+typedef PRInt64 PROffset64; -+ -+/************************************************************************ -+** TYPES: PRPtrDiff -+** DESCRIPTION: -+** A type for pointer difference. Variables of this type are suitable -+** for storing a pointer or pointer subtraction. -+************************************************************************/ -+typedef ptrdiff_t PRPtrdiff; -+ -+/************************************************************************ -+** TYPES: PRUptrdiff -+** DESCRIPTION: -+** A type for pointer difference. Variables of this type are suitable -+** for storing a pointer or pointer sutraction. -+************************************************************************/ -+#ifdef _WIN64 -+typedef PRUint64 PRUptrdiff; -+#else -+typedef unsigned long PRUptrdiff; -+#endif -+ -+/************************************************************************ -+** TYPES: PRBool -+** DESCRIPTION: -+** Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE -+** for clarity of target type in assignments and actual arguments. Use -+** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans -+** just as you would C int-valued conditions. -+************************************************************************/ -+typedef PRIntn PRBool; -+#define PR_TRUE 1 -+#define PR_FALSE 0 -+ -+/************************************************************************ -+** TYPES: PRPackedBool -+** DESCRIPTION: -+** Use PRPackedBool within structs where bitfields are not desirable -+** but minimum and consistant overhead matters. -+************************************************************************/ -+typedef PRUint8 PRPackedBool; -+ -+/* -+** Status code used by some routines that have a single point of failure or -+** special status return. -+*/ -+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus; -+ -+#ifndef __PRUNICHAR__ -+#define __PRUNICHAR__ -+#ifdef WIN32 -+typedef wchar_t PRUnichar; -+#else -+typedef PRUint16 PRUnichar; -+#endif -+#endif -+ -+/* -+** WARNING: The undocumented data types PRWord and PRUword are -+** only used in the garbage collection and arena code. Do not -+** use PRWord and PRUword in new code. -+** -+** A PRWord is an integer that is the same size as a void*. -+** It implements the notion of a "word" in the Java Virtual -+** Machine. (See Sec. 3.4 "Words", The Java Virtual Machine -+** Specification, Addison-Wesley, September 1996. -+** http://java.sun.com/docs/books/vmspec/index.html.) -+*/ -+#ifdef _WIN64 -+typedef PRInt64 PRWord; -+typedef PRUint64 PRUword; -+#else -+typedef long PRWord; -+typedef unsigned long PRUword; -+#endif -+ -+/* -+ * PR_PRETEND_NORETURN, specified at the end of a function declaration, -+ * indicates that for the purposes of static analysis, this function does not -+ * return. (The function definition does not need to be annotated.) -+ * -+ * void PR_Assert(const char *s, const char *file, PRIntn ln) -+ * PR_PRETEND_NORETURN; -+ * -+ * Some static analyzers, like scan-build from clang, can use this information -+ * to eliminate false positives. From the upstream documentation of -+ * scan-build: -+ * This attribute is useful for annotating assertion handlers that actually -+ * can return, but for the purpose of using the analyzer we want to pretend -+ * that such functions do not return. -+ */ -+#ifdef __clang_analyzer__ -+#if __has_extension(attribute_analyzer_noreturn) -+#define PR_PRETEND_NORETURN __attribute__((analyzer_noreturn)) -+#endif -+#endif -+ -+#ifndef PR_PRETEND_NORETURN -+#define PR_PRETEND_NORETURN /* no support */ -+#endif -+ -+/* -+** Compile-time assert. "condition" must be a constant expression. -+** The macro can be used only in places where an "extern" declaration is -+** allowed. -+*/ -+#define PR_STATIC_ASSERT(condition) \ -+ extern void pr_static_assert(int arg[(condition) ? 1 : -1]) -+ -+PR_END_EXTERN_C -+ -+#endif /* prtypes_h___ */ -+ ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11p.h -@@ -0,0 +1,24 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+/* -+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document -+ * is granted provided that it is identified as "RSA Security Inc. Public-Key -+ * Cryptography Standards (PKCS)" in all material mentioning or referencing -+ * this document. -+ */ -+/* these data types are platform/implementation dependent. */ -+/* -+ * Packing was removed from the shipped RSA header files, even -+ * though it's still needed. put in a central file to help merging.. -+ */ -+ -+#if defined(_WIN32) || defined(_WINDOWS) -+#ifdef __clang__ -+#pragma clang diagnostic ignored "-Wpragma-pack" -+#endif -+#ifdef _MSC_VER -+#pragma warning(disable : 4103) -+#endif -+#pragma pack(push, cryptoki, 1) -+#endif ---- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h -+++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h -@@ -63,11 +63,6 @@ - #ifndef _P11_MD_H - #define _P11_MD_H 1 - --#define CK_PTR * --#define CK_DEFINE_FUNCTION(returnType, name) returnType name --#define CK_DECLARE_FUNCTION(returnType, name) returnType name --#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name) --#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name) - #ifndef NULL_PTR - #define NULL_PTR 0 - #endif ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h -@@ -172,8 +172,8 @@ - #define min(a, b) (((a) < (b)) ? (a) : (b)) - #endif - --#define ckBBoolToJBoolean(x) ((x == TRUE) ? JNI_TRUE : JNI_FALSE); --#define jBooleanToCKBBool(x) ((x == JNI_TRUE) ? TRUE : FALSE); -+#define ckBBoolToJBoolean(x) ((x == CK_TRUE) ? JNI_TRUE : JNI_FALSE); -+#define jBooleanToCKBBool(x) ((x == JNI_TRUE) ? CK_TRUE : CK_FALSE); - - #define ckByteToJByte(x) ((jbyte) x) - #define jByteToCKByte(x) ((CK_BYTE) x) ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c -@@ -1543,7 +1543,9 @@ CK_VOID_PTR jMechParamToCKMechParamPtrSl - ckpParamPtr = jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(env, jParam, ckpLength); - break; - // defined by pkcs11.h but we don't support -+#if 0 - case CKM_KEA_DERIVE: // CK_KEA_DERIVE_PARAMS -+#endif - case CKM_RC2_CBC: // CK_RC2_CBC_PARAMS - case CKM_RC2_MAC_GENERAL: // CK_RC2_MAC_GENERAL_PARAMS - case CKM_RC5_ECB: // CK_RC5_PARAMS ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c -@@ -407,7 +407,9 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR - case CKM_TLS_MAC: - case CKM_AES_CTR: - case CKM_RSA_PKCS_PSS: -+#if 0 - case CKM_CAMELLIA_CTR: -+#endif - // params do not contain pointers - break; - default: diff -Nru openjdk-17-17.0.5+8/debian/patches/pass-extra-flags.diff openjdk-17-17.0.6+10/debian/patches/pass-extra-flags.diff --- openjdk-17-17.0.5+8/debian/patches/pass-extra-flags.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/pass-extra-flags.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ ---- a/src/hotspot/make/linux/makefiles/jsig.make -+++ b/src/hotspot/make/linux/makefiles/jsig.make -@@ -54,7 +54,9 @@ endif - $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) - @echo $(LOG_INFO) Making signal interposition lib... - $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ -- $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< -ldl -+ $(LFLAGS_JSIG) $(EXTRA_LDFLAGS) \ -+ $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) \ -+ -o $@ $< -ldl - ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) - $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) - $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ ---- a/src/hotspot/make/linux/makefiles/vm.make -+++ b/src/hotspot/make/linux/makefiles/vm.make -@@ -118,7 +118,8 @@ CFLAGS += $(CFLAGS/NOEX) - - # Extra flags from gnumake's invocation or environment - CFLAGS += $(EXTRA_CFLAGS) --LFLAGS += $(EXTRA_CFLAGS) -+CXXFLAGS += $(EXTRA_CXXFLAGS) -+LFLAGS += $(EXTRA_LDFLAGS) - - # Don't set excutable bit on stack segment - # the same could be done by separate execstack command diff -Nru openjdk-17-17.0.5+8/debian/patches/reproducible-build-jmod.diff openjdk-17-17.0.6+10/debian/patches/reproducible-build-jmod.diff --- openjdk-17-17.0.5+8/debian/patches/reproducible-build-jmod.diff 2022-07-20 09:30:22.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/reproducible-build-jmod.diff 2023-01-17 22:36:38.000000000 +0000 @@ -12,7 +12,7 @@ --- a/make/CreateJmods.gmk +++ b/make/CreateJmods.gmk -@@ -230,6 +230,15 @@ endif +@@ -230,6 +230,15 @@ # Create jmods in the support dir and then move them into place to keep the # module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times. @@ -28,7 +28,7 @@ $(eval $(call SetupExecute, create_$(JMOD_FILE), \ WARN := Creating $(INTERIM_MSG)$(JMOD_FILE), \ DEPS := $(DEPS), \ -@@ -241,7 +250,7 @@ $(eval $(call SetupExecute, create_$(JMO +@@ -241,7 +250,7 @@ --module-path $(JMODS_DIR) $(JMOD_FLAGS) \ $(JMOD_SOURCE_DATE) \ $(JMODS_SUPPORT_DIR)/$(JMOD_FILE), \ diff -Nru openjdk-17-17.0.5+8/debian/patches/reproducible-copyright-headers.diff openjdk-17-17.0.6+10/debian/patches/reproducible-copyright-headers.diff --- openjdk-17-17.0.5+8/debian/patches/reproducible-copyright-headers.diff 2021-04-08 07:40:19.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/reproducible-copyright-headers.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -Description: Makes the generated copyright headers reproducible -Author: Emmanuel Bourg -Forwarded: no ---- a/make/jdk/src/classes/build/tools/cldrconverter/CopyrightHeaders.java -+++ b/make/jdk/src/classes/build/tools/cldrconverter/CopyrightHeaders.java -@@ -26,6 +26,7 @@ - package build.tools.cldrconverter; - - import java.util.Calendar; -+import java.util.Date; - import java.util.GregorianCalendar; - import java.util.Locale; - import java.util.TimeZone; -@@ -146,8 +147,14 @@ class CopyrightHeaders { - } - - private static int getYear() { -- return new GregorianCalendar(TimeZone.getTimeZone("America/Los_Angeles"), -- Locale.US).get(Calendar.YEAR); -+ Date date = new Date(); -+ if (System.getenv("SOURCE_DATE_EPOCH") != null) { -+ date = new Date(1000 * Long.valueOf(System.getenv("SOURCE_DATE_EPOCH"))); -+ } -+ -+ GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); -+ calendar.setTime(date); -+ return calendar.get(Calendar.YEAR); - } - - // no instantiation ---- a/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java -+++ b/make/jdk/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java -@@ -34,9 +34,13 @@ import java.time.ZoneId; - import java.time.ZonedDateTime; - import java.util.ArrayList; - import java.util.Arrays; -+import java.util.Calendar; -+import java.util.Date; -+import java.util.GregorianCalendar; - import java.util.List; - import java.util.Locale; - import java.util.Map; -+import java.util.TimeZone; - import java.util.TreeMap; - import java.util.stream.Collectors; - -@@ -246,8 +250,15 @@ public class EquivMapsGenerator { - + "}"; - - private static String getOpenJDKCopyright() { -- int year = ZonedDateTime.now(ZoneId -- .of("America/Los_Angeles")).getYear(); -+ Date date = new Date(); -+ if (System.getenv("SOURCE_DATE_EPOCH") != null) { -+ date = new Date(1000 * Long.valueOf(System.getenv("SOURCE_DATE_EPOCH"))); -+ } -+ -+ GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); -+ calendar.setTime(date); -+ -+ int year = calendar.get(Calendar.YEAR); - return String.format(Locale.US, COPYRIGHT, year); - } - diff -Nru openjdk-17-17.0.5+8/debian/patches/reproducible-javadoc-timestamp.diff openjdk-17-17.0.6+10/debian/patches/reproducible-javadoc-timestamp.diff --- openjdk-17-17.0.5+8/debian/patches/reproducible-javadoc-timestamp.diff 2019-05-27 17:54:35.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/reproducible-javadoc-timestamp.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -Description: Makes the timestamp in the javadoc files reproducible when SOURCE_DATE_EPOCH is specified -Author: Emmanuel Bourg -Forwarded: no ---- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java -+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java -@@ -239,6 +239,9 @@ public class Head { - */ - public Content toContent() { - Date now = showTimestamp ? calendar.getTime() : null; -+ if (now != null && System.getenv("SOURCE_DATE_EPOCH") != null) { -+ now = new Date(1000 * Long.parseLong(System.getenv("SOURCE_DATE_EPOCH"))); -+ } - - HtmlTree tree = new HtmlTree(HtmlTag.HEAD); - tree.add(getGeneratedBy(showTimestamp, now)); -@@ -250,6 +253,9 @@ public class Head { - - if (showTimestamp) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); -+ if (System.getenv("SOURCE_DATE_EPOCH") != null) { -+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); -+ } - tree.add(HtmlTree.META("dc.created", dateFormat.format(now))); - } - -@@ -282,7 +288,14 @@ public class Head { - private Comment getGeneratedBy(boolean timestamp, Date now) { - String text = "Generated by javadoc"; // marker string, deliberately not localized - if (timestamp) { -- text += " ("+ docletVersion + ") on " + now; -+ text += " ("+ docletVersion + ") on "; -+ if (System.getenv("SOURCE_DATE_EPOCH") == null) { -+ text += now; -+ } else { -+ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); -+ fmt.setTimeZone(TimeZone.getTimeZone("UTC")); -+ text += fmt.format(now); -+ } - } - return new Comment(text); - } diff -Nru openjdk-17-17.0.5+8/debian/patches/riscv64.diff openjdk-17-17.0.6+10/debian/patches/riscv64.diff --- openjdk-17-17.0.5+8/debian/patches/riscv64.diff 2022-07-20 09:30:18.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/riscv64.diff 2023-01-17 22:36:38.000000000 +0000 @@ -25,7 +25,7 @@ --- a/make/autoconf/build-aux/config.sub +++ b/make/autoconf/build-aux/config.sub -@@ -46,8 +46,8 @@ if echo $* | grep pc-msys >/dev/null ; t +@@ -46,8 +46,8 @@ exit fi @@ -36,7 +36,7 @@ . $DIR/autoconf-config.sub "$@" # autoconf-config.sub exits, so we never reach here, but just in # case we do: -@@ -62,6 +62,10 @@ while test $# -gt 0 ; do +@@ -62,6 +62,10 @@ config=`echo $1 | sed 's/^aarch64-/arm-/'` sub_args="$sub_args $config" shift; ;; @@ -47,7 +47,7 @@ - ) # Use stdin as input. sub_args="$sub_args $1" shift; break ;; -@@ -74,7 +78,7 @@ done +@@ -74,7 +78,7 @@ result=`. $DIR/autoconf-config.sub $sub_args "$@"` exitcode=$? @@ -58,7 +58,7 @@ exit $exitcode --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp -@@ -2563,6 +2563,8 @@ void os::get_summary_cpu_info(char* cpui +@@ -2558,6 +2558,8 @@ strncpy(cpuinfo, "IA64", length); #elif defined(PPC) strncpy(cpuinfo, "PPC64", length); diff -Nru openjdk-17-17.0.5+8/debian/patches/s390x-opt.diff openjdk-17-17.0.6+10/debian/patches/s390x-opt.diff --- openjdk-17-17.0.5+8/debian/patches/s390x-opt.diff 2022-07-20 09:27:23.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/s390x-opt.diff 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 -@@ -721,6 +721,9 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], +@@ -735,6 +735,9 @@ fi elif test "x$FLAGS_CPU" = xs390x; then $1_CFLAGS_CPU="-mbackchain -march=z10" diff -Nru openjdk-17-17.0.5+8/debian/patches/series openjdk-17-17.0.6+10/debian/patches/series --- openjdk-17-17.0.5+8/debian/patches/series 2022-07-20 09:30:14.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/series 2023-01-17 22:31:55.000000000 +0000 @@ -3,7 +3,6 @@ icc_loading_with_symlink.diff icedtea-override-redirect-compiz.diff libpcsclite-dlopen.diff -#jexec.diff default-jvm-cfg.diff workaround_expand_exec_shield_cs_limit.diff adlc-parser.diff @@ -17,13 +16,10 @@ zero-x32.diff hotspot-disable-exec-shield-workaround.diff atk-wrapper-security.diff -# java-access-bridge-security.diff -# jdk-pulseaudio.diff dnd-files.diff generated-headers.patch m68k-support.diff reproducible-properties-timestamp.diff -# reproducible-javadoc-timestamp.diff make-debug-print.diff Don-t-optimize-fdlibm-fork-for-Zero-on-linux-sparc-Z.patch keep-gtk2-as-default.patch @@ -31,8 +27,6 @@ jaw-optional.diff reproducible-character-data.diff reproducible-module-info.diff -#reproducible-copyright-headers.diff riscv64.diff reproducible-build-jmod.diff mips.diff -#nspr+nss-headers.diff diff -Nru openjdk-17-17.0.5+8/debian/patches/set-exec-name.diff openjdk-17-17.0.6+10/debian/patches/set-exec-name.diff --- openjdk-17-17.0.5+8/debian/patches/set-exec-name.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/set-exec-name.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ ---- a/src/jdk/src/solaris/bin/java_md.c.orig -+++ b/src/jdk/src/solaris/bin/java_md.c -@@ -688,8 +688,19 @@ - char buf[PATH_MAX+1]; - int len = readlink(self, buf, PATH_MAX); - if (len >= 0) { -+ const char* prefixes[] = {"/cow/", "/persistmnt/", "/rofs/", "/rwfs/", "/squashmnt/", NULL}; -+ const char **prefix; -+ size_t prefix_len = 0; - buf[len] = '\0'; /* readlink doesn't nul terminate */ -- exec_path = JLI_StringDup(buf); -+ for (prefix = prefixes; *prefix; prefix++) { -+ prefix_len = strlen(buf) < strlen(*prefix) ? strlen(buf) : strlen(*prefix); -+ if (!strncmp(*prefix, buf, prefix_len)) { -+ prefix_len--; -+ break; -+ } -+ prefix_len = 0; -+ } -+ exec_path = JLI_StringDup(buf + prefix_len); - } - } - #else /* !__solaris__ && !__linux */ ---- a/src/hotspot/src/os/posix/launcher/java_md.c.orig -+++ b/src/hotspot/src/os/posix/launcher/java_md.c -@@ -967,8 +967,19 @@ - char buf[PATH_MAX+1]; - int len = readlink(self, buf, PATH_MAX); - if (len >= 0) { -- buf[len] = '\0'; /* readlink doesn't nul terminate */ -- exec_path = JLI_StringDup(buf); -+ buf[len] = '\0'; /* readlink doesn't nul terminate */ -+ const char* prefixes[] = {"/cow/", "/persistmnt/", "/rofs/", "/rwfs/", "/squashmnt/", NULL}; -+ const char **prefix; -+ size_t prefix_len = 0; -+ for (prefix = prefixes; *prefix; prefix++) { -+ prefix_len = strlen(buf) < strlen(*prefix) ? strlen(buf) : strlen(*prefix); -+ if (!strncmp(*prefix, buf, prefix_len)) { -+ prefix_len--; -+ break; -+ } -+ prefix_len = 0; -+ } -+ exec_path = JLI_StringDup(buf + prefix_len); - } - } - #else /* !__sun && !__linux */ diff -Nru openjdk-17-17.0.5+8/debian/patches/stack-direction.diff openjdk-17-17.0.6+10/debian/patches/stack-direction.diff --- openjdk-17-17.0.5+8/debian/patches/stack-direction.diff 2017-11-19 13:58:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/stack-direction.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ ---- a/src/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp.old 2010-01-06 16:30:02.000000000 +0100 -+++ b/src/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp 2010-01-06 23:14:47.000000000 +0100 -@@ -144,8 +144,13 @@ - address addr = (address) info->si_addr; - - // check if fault address is within thread stack -+#ifdef __hppa__ -+ if (addr > thread->stack_base() && -+ addr <= thread->stack_base() + thread->stack_size()) { -+#else - if (addr < thread->stack_base() && - addr >= thread->stack_base() - thread->stack_size()) { -+#endif - // stack overflow - if (thread->in_stack_yellow_zone(addr)) { - thread->disable_stack_yellow_zone(); -@@ -294,7 +299,11 @@ - if (res != 0) { - fatal1("pthread_attr_getstack failed with errno = %d", res); - } -+#ifdef __hppa__ -+ address stack_top = stack_bottom - stack_bytes; -+#else - address stack_top = stack_bottom + stack_bytes; -+#endif - - // The block of memory returned by pthread_attr_getstack() includes - // guard pages where present. We need to trim these off. -@@ -321,7 +330,11 @@ - stack_bottom += (total_pages - guard_pages) / 2 * page_bytes; - #endif // IA64 - -+#ifdef __hppa__ -+ stack_bottom -= guard_bytes; -+#else - stack_bottom += guard_bytes; -+#endif - - pthread_attr_destroy(&attr); - -@@ -329,19 +342,36 @@ - // by pthread_attr_getstack is the maximum size it could possibly - // be given what currently mapped. This can be huge, so we cap it. - if (os::Linux::is_initial_thread()) { -+#ifdef __hppa__ -+ stack_bytes = stack_bottom - stack_top; -+#else - stack_bytes = stack_top - stack_bottom; -+#endif - - if (stack_bytes > JavaThread::stack_size_at_create()) - stack_bytes = JavaThread::stack_size_at_create(); - -+#ifdef __hppa__ -+ stack_bottom = stack_top + stack_bytes; -+#else - stack_bottom = stack_top - stack_bytes; -+#endif - } - -+#ifdef __hppa__ -+ assert(os::current_stack_pointer() <= stack_bottom, "should do"); -+ assert(os::current_stack_pointer() > stack_top, "should do"); -+#else - assert(os::current_stack_pointer() >= stack_bottom, "should do"); - assert(os::current_stack_pointer() < stack_top, "should do"); -+#endif - - *bottom = stack_bottom; -+#ifdef __hppa__ -+ *size = stack_bottom - stack_top; -+#else - *size = stack_top - stack_bottom; -+#endif - } - - address os::current_stack_base() { ---- a/src/hotspot/src/share/vm/runtime/thread.cpp.old 2009-10-02 23:16:39.000000000 +0200 -+++ b/src/hotspot/src/share/vm/runtime/thread.cpp 2010-01-06 23:31:24.000000000 +0100 -@@ -713,8 +713,13 @@ - else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread"); - else st->print("Thread"); - -+#ifdef __hppa__ - st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]", - _stack_base - _stack_size, _stack_base); -+#else -+ st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]", -+ _stack_base + _stack_size, _stack_base); -+#endif - - if (osthread()) { - st->print(" [id=%d]", osthread()->thread_id()); -@@ -792,7 +797,11 @@ - bool Thread::is_in_stack(address adr) const { - assert(Thread::current() == this, "is_in_stack can only be called from current thread"); - address end = os::current_stack_pointer(); -+#ifdef __hppa__ -+ if (stack_base() <= adr && adr <= end) return true; -+#else - if (stack_base() >= adr && adr >= end) return true; -+#endif - - return false; - } -@@ -804,7 +813,11 @@ - // should be revisited, and they should be removed if possible. - - bool Thread::is_lock_owned(address adr) const { -+#ifdef __hppa__ -+ return (_stack_base <= adr && adr <= (_stack_base + _stack_size)); -+#else - return (_stack_base >= adr && adr >= (_stack_base - _stack_size)); -+#endif - } - - bool Thread::set_as_starting_thread() { -@@ -2108,7 +2121,11 @@ - - void JavaThread::create_stack_guard_pages() { - if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return; -+#ifdef __hppa__ -+ address low_addr = stack_base(); -+#else - address low_addr = stack_base() - stack_size(); -+#endif - size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size(); - - int allocate = os::allocate_stack_guard_pages(); -@@ -2131,7 +2148,11 @@ - - void JavaThread::remove_stack_guard_pages() { - if (_stack_guard_state == stack_guard_unused) return; -+#ifdef __hppa__ -+ address low_addr = stack_base(); -+#else - address low_addr = stack_base() - stack_size(); -+#endif - size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size(); - - if (os::allocate_stack_guard_pages()) { -@@ -2156,10 +2177,17 @@ - - // The base notation is from the stacks point of view, growing downward. - // We need to adjust it to work correctly with guard_memory() -+#ifdef __hppa__ -+ address base = stack_yellow_zone_base() + stack_yellow_zone_size(); -+ -+ guarantee(base > stack_base(),"Error calculating stack yellow zone"); -+ guarantee(base > os::current_stack_pointer(),"Error calculating stack yellow zone"); -+#else - address base = stack_yellow_zone_base() - stack_yellow_zone_size(); - - guarantee(base < stack_base(),"Error calculating stack yellow zone"); - guarantee(base < os::current_stack_pointer(),"Error calculating stack yellow zone"); -+#endif - - if (os::guard_memory((char *) base, stack_yellow_zone_size())) { - _stack_guard_state = stack_guard_enabled; -@@ -2178,7 +2206,11 @@ - - // The base notation is from the stacks point of view, growing downward. - // We need to adjust it to work correctly with guard_memory() -+#ifdef __hppa__ -+ address base = stack_yellow_zone_base() + stack_yellow_zone_size(); -+#else - address base = stack_yellow_zone_base() - stack_yellow_zone_size(); -+#endif - - if (os::unguard_memory((char *)base, stack_yellow_zone_size())) { - _stack_guard_state = stack_guard_yellow_disabled; -@@ -2192,10 +2224,17 @@ - // The base notation is from the stacks point of view, growing downward. - // We need to adjust it to work correctly with guard_memory() - assert(_stack_guard_state != stack_guard_unused, "must be using guard pages."); -+#ifdef __hppa__ -+ address base = stack_red_zone_base() + stack_red_zone_size(); -+ -+ guarantee(base > stack_base(),"Error calculating stack red zone"); -+ guarantee(base > os::current_stack_pointer(),"Error calculating stack red zone"); -+#else - address base = stack_red_zone_base() - stack_red_zone_size(); - - guarantee(base < stack_base(),"Error calculating stack red zone"); - guarantee(base < os::current_stack_pointer(),"Error calculating stack red zone"); -+#endif - - if(!os::guard_memory((char *) base, stack_red_zone_size())) { - warning("Attempt to guard stack red zone failed."); -@@ -2206,7 +2245,11 @@ - // The base notation is from the stacks point of view, growing downward. - // We need to adjust it to work correctly with guard_memory() - assert(_stack_guard_state != stack_guard_unused, "must be using guard pages."); -+#ifdef __hppa__ -+ address base = stack_red_zone_base() + stack_red_zone_size(); -+#else - address base = stack_red_zone_base() - stack_red_zone_size(); -+#endif - if (!os::unguard_memory((char *)base, stack_red_zone_size())) { - warning("Attempt to unguard stack red zone failed."); - } -@@ -2451,8 +2494,13 @@ - if (osthread()) { - st->print(", id=%d", osthread()->thread_id()); - } -+#ifdef __hppa__ -+ st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")", -+ _stack_base + _stack_size, _stack_base); -+#else - st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")", - _stack_base - _stack_size, _stack_base); -+#endif - st->print("]"); - return; - } diff -Nru openjdk-17-17.0.5+8/debian/patches/system-pcsclite.diff openjdk-17-17.0.6+10/debian/patches/system-pcsclite.diff --- openjdk-17-17.0.5+8/debian/patches/system-pcsclite.diff 2022-07-20 09:27:11.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/system-pcsclite.diff 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/make/autoconf/lib-bundled.m4 +++ b/make/autoconf/lib-bundled.m4 -@@ -41,6 +41,7 @@ AC_DEFUN_ONCE([LIB_SETUP_BUNDLED_LIBS], +@@ -41,6 +41,7 @@ LIB_SETUP_ZLIB LIB_SETUP_LCMS LIB_SETUP_HARFBUZZ @@ -8,7 +8,7 @@ ]) ################################################################################ -@@ -304,3 +305,41 @@ AC_DEFUN_ONCE([LIB_SETUP_HARFBUZZ], +@@ -307,3 +308,41 @@ AC_SUBST(HARFBUZZ_CFLAGS) AC_SUBST(HARFBUZZ_LIBS) ]) @@ -52,7 +52,7 @@ +]) --- a/make/modules/java.smartcardio/Lib.gmk +++ b/make/modules/java.smartcardio/Lib.gmk -@@ -30,12 +30,12 @@ include LibCommon.gmk +@@ -30,12 +30,12 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJ2PCSC, \ NAME := j2pcsc, \ CFLAGS := $(CFLAGS_JDKLIB), \ @@ -70,7 +70,7 @@ --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in -@@ -773,6 +773,7 @@ TAR_SUPPORTS_TRANSFORM:=@TAR_SUPPORTS_TR +@@ -774,6 +774,7 @@ # Build setup USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@ USE_EXTERNAL_LIBGIF:=@USE_EXTERNAL_LIBGIF@ @@ -88,7 +88,7 @@ void *hModule; FPTR_SCardEstablishContext scardEstablishContext; FPTR_SCardConnect scardConnect; -@@ -47,6 +48,7 @@ FPTR_SCardListReaders scardListReaders; +@@ -47,6 +48,7 @@ FPTR_SCardBeginTransaction scardBeginTransaction; FPTR_SCardEndTransaction scardEndTransaction; FPTR_SCardControl scardControl; @@ -96,7 +96,7 @@ /* * Throws a Java Exception by name -@@ -75,7 +77,9 @@ void throwIOException(JNIEnv *env, const +@@ -75,7 +77,9 @@ throwByName(env, "java/io/IOException", msg); } @@ -106,7 +106,7 @@ void *fAddress = dlsym(hModule, functionName); if (fAddress == NULL) { char errorMessage[256]; -@@ -85,9 +89,11 @@ void *findFunction(JNIEnv *env, void *hM +@@ -85,9 +89,11 @@ } return fAddress; } @@ -118,7 +118,7 @@ const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL); if (libName == NULL) { throwNullPointerException(env, "PCSC library name is null"); -@@ -141,4 +147,5 @@ JNIEXPORT void JNICALL Java_sun_security +@@ -141,4 +147,5 @@ #else scardControl = (FPTR_SCardControl) findFunction(env, hModule, "SCardControl132"); #endif // __APPLE__ @@ -135,7 +135,7 @@ typedef LONG (*FPTR_SCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, -@@ -111,3 +113,41 @@ extern FPTR_SCardListReaders scardListRe +@@ -111,3 +113,41 @@ extern FPTR_SCardBeginTransaction scardBeginTransaction; extern FPTR_SCardEndTransaction scardEndTransaction; extern FPTR_SCardControl scardControl; diff -Nru openjdk-17-17.0.5+8/debian/patches/workaround_expand_exec_shield_cs_limit.diff openjdk-17-17.0.6+10/debian/patches/workaround_expand_exec_shield_cs_limit.diff --- openjdk-17-17.0.5+8/debian/patches/workaround_expand_exec_shield_cs_limit.diff 2021-05-27 09:28:52.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/patches/workaround_expand_exec_shield_cs_limit.diff 2023-01-17 22:36:38.000000000 +0000 @@ -1,6 +1,6 @@ --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp -@@ -635,7 +635,7 @@ void os::verify_stack_alignment() { +@@ -651,7 +651,7 @@ * updates (JDK-8023956). */ void os::workaround_expand_exec_shield_cs_limit() { diff -Nru openjdk-17-17.0.5+8/debian/rules openjdk-17-17.0.6+10/debian/rules --- openjdk-17-17.0.5+8/debian/rules 2022-10-19 14:22:50.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/rules 2023-01-17 22:56:50.000000000 +0000 @@ -157,7 +157,13 @@ NJOBS = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) endif -jtreg_pkg = jtreg6 +ifneq (,$(filter $(distrel), sid bookworm bullseye focal jammy kinetic lunar )) + jtreg_pkg = jtreg6 +else ifneq (,$(filter $(distrel), sid bookworm bullseye)) + jtreg_pkg = jtreg +else + jtreg_pkg = +endif with_check = $(if $(findstring nocheck, $(DEB_BUILD_OPTIONS)),,yes) ifneq (,$(filter $(DEB_HOST_ARCH), alpha armel mipsel mips64el riscv64)) @@ -904,6 +910,7 @@ debian/tests/control: debian/tests/control.in debian/rules sed \ + -e 's/@jtreg_pkg@/$(jtreg_pkg)/g' \ -e 's/@min_jtreg_version@/$(min_jtreg_version)/g' \ $< > $@; diff -Nru openjdk-17-17.0.5+8/debian/tests/control openjdk-17-17.0.6+10/debian/tests/control --- openjdk-17-17.0.5+8/debian/tests/control 2022-10-24 12:44:46.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/tests/control 2023-01-17 22:28:11.000000000 +0000 @@ -7,9 +7,9 @@ Restrictions: superficial #Tests: hotspot, jaxp, langtools -#Depends: @, default-jre-headless, jtreg:native (>= 6+1-0~), testng:native, build-essential +#Depends: @, default-jre-headless, jtreg6:native (>= 6+1-0~), testng:native, build-essential #Restrictions: allow-stderr, skippable, flaky #Tests: jdk -#Depends: @, default-jre-headless, jtreg:native (>= 6+1-0~), testng:native, build-essential, xfwm4:native, xvfb, dbus-x11 +#Depends: @, default-jre-headless, jtreg6:native (>= 6+1-0~), testng:native, build-essential, xfwm4:native, xvfb, dbus-x11 #Restrictions: allow-stderr, skippable, flaky diff -Nru openjdk-17-17.0.5+8/debian/tests/control.in openjdk-17-17.0.6+10/debian/tests/control.in --- openjdk-17-17.0.5+8/debian/tests/control.in 2022-07-20 17:10:26.000000000 +0000 +++ openjdk-17-17.0.6+10/debian/tests/control.in 2023-01-17 22:28:11.000000000 +0000 @@ -7,9 +7,9 @@ Restrictions: superficial #Tests: hotspot, jaxp, langtools -#Depends: @, default-jre-headless, jtreg:native (>= @min_jtreg_version@), testng:native, build-essential +#Depends: @, default-jre-headless, @jtreg_pkg@:native (>= @min_jtreg_version@), testng:native, build-essential #Restrictions: allow-stderr, skippable, flaky #Tests: jdk -#Depends: @, default-jre-headless, jtreg:native (>= @min_jtreg_version@), testng:native, build-essential, xfwm4:native, xvfb, dbus-x11 +#Depends: @, default-jre-headless, @jtreg_pkg@:native (>= @min_jtreg_version@), testng:native, build-essential, xfwm4:native, xvfb, dbus-x11 #Restrictions: allow-stderr, skippable, flaky diff -Nru openjdk-17-17.0.5+8/doc/building.html openjdk-17-17.0.6+10/doc/building.html --- openjdk-17-17.0.5+8/doc/building.html 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/doc/building.html 2023-01-10 13:21:55.000000000 +0000 @@ -70,6 +70,9 @@
  • Make Control Variables
  • Running Tests
  • +
  • Signing
  • Cross-compiling

    Test Make Control Variables

    -

    These make control variables only make sense when running tests. Please see Testing the JDK for details.

    +

    These make control variables only make sense when running tests. Please see Testing the JDK (html, markdown) for details.

    • TEST
    • TEST_JOBS
    • @@ -514,7 +517,13 @@

    To execute the most basic tests (tier 1), use:

    make run-test-tier1
    -

    For more details on how to run tests, please see the Testing the JDK document.

    +

    For more details on how to run tests, please see Testing the JDK (html, markdown).

    +

    Signing

    +

    macOS

    +

    Modern versions of macOS require applications to be signed and notarizied before distribution. See Apple's documentation for more background on what this means and how it works. To help support this, the JDK build can be configured to automatically sign all native binaries, and the JDK bundle, with all the options needed for successful notarization, as well as all the entitlements required by the JDK. To enable hardened signing, use configure parameter --with-macosx-codesign=hardened and configure the signing identity you wish to use with --with-macosx-codesign-identity=<identity>. The identity refers to a signing identity from Apple that needs to be preinstalled on the build host.

    +

    When not signing for distribution with the hardened option, the JDK build will still attempt to perform adhoc signing to add the special entitlement com.apple.security.get-task-allow to each binary. This entitlement is required to be able to dump core files from a process. Note that adding this entitlement makes the build invalid for notarization, so it is only added when signing in debug mode. To explicitly enable this kind of adhoc signing, use configure parameter --with-macosx-codesign=debug. It will be enabled by default in most cases.

    +

    It's also possible to completely disable any explicit codesign operations done by the JDK build using the configure parameter --without-macosx-codesign. The exact behavior then depends on the architecture. For macOS on x64, it (at least at the time of this writing) results in completely unsigned binaries that should still work fine for development and debugging purposes. On aarch64, the Xcode linker will apply a default "adhoc" signing, without any entitlements. Such a build does not allow dumping core files.

    +

    The default mode "auto" will try for hardened signing if the debug level is release and either the default identity or the specified identity is valid. If hardened isn't possible, then debug signing is chosen if it works. If nothing works, the codesign build step is disabled.

    Cross-compiling

    Cross-compiling means using one platform (the build platform) to generate output that can ran on another platform (the target platform).

    The typical reason for cross-compiling is that the build is performed on a more powerful desktop computer, but the resulting binaries will be able to run on a different, typically low-performing system. Most of the complications that arise when building for embedded is due to this separation of build and target systems.

    diff -Nru openjdk-17-17.0.5+8/doc/building.md openjdk-17-17.0.6+10/doc/building.md --- openjdk-17-17.0.5+8/doc/building.md 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/doc/building.md 2023-01-10 13:21:55.000000000 +0000 @@ -818,7 +818,7 @@ #### Test Make Control Variables These make control variables only make sense when running tests. Please see -[Testing the JDK](testing.html) for details. +**Testing the JDK** ([html](testing.html), [markdown](testing.md)) for details. * `TEST` * `TEST_JOBS` @@ -865,8 +865,44 @@ make run-test-tier1 ``` -For more details on how to run tests, please see the [Testing -the JDK](testing.html) document. +For more details on how to run tests, please see **Testing the JDK** +([html](testing.html), [markdown](testing.md)). + +## Signing + +### macOS + +Modern versions of macOS require applications to be signed and notarizied before +distribution. See Apple's documentation for more background on what this means +and how it works. To help support this, the JDK build can be configured to +automatically sign all native binaries, and the JDK bundle, with all the options +needed for successful notarization, as well as all the entitlements required by +the JDK. To enable `hardened` signing, use configure parameter +`--with-macosx-codesign=hardened` and configure the signing identity you wish to +use with `--with-macosx-codesign-identity=`. The identity refers to a +signing identity from Apple that needs to be preinstalled on the build host. + +When not signing for distribution with the hardened option, the JDK build will +still attempt to perform `adhoc` signing to add the special entitlement +`com.apple.security.get-task-allow` to each binary. This entitlement is required +to be able to dump core files from a process. Note that adding this entitlement +makes the build invalid for notarization, so it is only added when signing in +`debug` mode. To explicitly enable this kind of adhoc signing, use configure +parameter `--with-macosx-codesign=debug`. It will be enabled by default in most +cases. + +It's also possible to completely disable any explicit codesign operations done +by the JDK build using the configure parameter `--without-macosx-codesign`. +The exact behavior then depends on the architecture. For macOS on x64, it (at +least at the time of this writing) results in completely unsigned binaries that +should still work fine for development and debugging purposes. On aarch64, the +Xcode linker will apply a default "adhoc" signing, without any entitlements. +Such a build does not allow dumping core files. + +The default mode "auto" will try for `hardened` signing if the debug level is +`release` and either the default identity or the specified identity is valid. +If hardened isn't possible, then `debug` signing is chosen if it works. If +nothing works, the codesign build step is disabled. ## Cross-compiling diff -Nru openjdk-17-17.0.5+8/.gitattributes openjdk-17-17.0.6+10/.gitattributes --- openjdk-17-17.0.5+8/.gitattributes 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.gitattributes 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1 @@ +* -text diff -Nru openjdk-17-17.0.5+8/.github/actions/config/action.yml openjdk-17-17.0.6+10/.github/actions/config/action.yml --- openjdk-17-17.0.5+8/.github/actions/config/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/config/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,46 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Config' +description: 'Read JDK Configuration Variables' +inputs: + var: + description: 'The name of the variable to read' + required: true +outputs: + value: + description: 'The value of the configuration variable' + value: ${{ steps.read-config.outputs.value }} + +runs: + using: composite + steps: + - name: 'Read configuration variable from repo' + id: read-config + run: | + # Extract value from configuration file + value="$(grep -h ${{ inputs.var }}= make/conf/github-actions.conf | cut -d '=' -f 2-)" + echo "value=$value" >> $GITHUB_OUTPUT + shell: bash diff -Nru openjdk-17-17.0.5+8/.github/actions/do-build/action.yml openjdk-17-17.0.6+10/.github/actions/do-build/action.yml --- openjdk-17-17.0.5+8/.github/actions/do-build/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/do-build/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,80 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Do build' +description: 'Build the JDK using make' +inputs: + make-target: + description: 'Make target(s)' + required: true + platform: + description: 'Platform name' + required: true + debug-suffix: + description: 'File name suffix denoting debug level, possibly empty' + required: false + +runs: + using: composite + steps: + - name: 'Build' + id: build + run: > + make LOG=info ${{ inputs.make-target }} + || bash ./.github/scripts/gen-build-failure-report.sh "$GITHUB_STEP_SUMMARY" + shell: bash + + - name: 'Check for failure' + id: check + run: | + # Check for failure marker file + build_dir="$(ls -d build/*)" + if [[ -e $build_dir/build-failure ]]; then + # Collect relevant log files + mkdir failure-logs + cp \ + $build_dir/spec.gmk \ + $build_dir/build.log \ + $build_dir/configure.log \ + $build_dir/make-support/failure-summary.log \ + $build_dir/make-support/failure-logs/* \ + failure-logs/ 2> /dev/null || true + echo 'failure=true' >> $GITHUB_OUTPUT + fi + shell: bash + + - name: 'Upload build logs' + uses: actions/upload-artifact@v3 + with: + name: failure-logs-${{ inputs.platform }}${{ inputs.debug-suffix }} + path: failure-logs + if: steps.check.outputs.failure == 'true' + + # This is the best way I found to abort the job with an error message + - name: 'Notify about build failures' + uses: actions/github-script@v6 + with: + script: core.setFailed('Build failed. See summary for details.') + if: steps.check.outputs.failure == 'true' diff -Nru openjdk-17-17.0.5+8/.github/actions/get-bootjdk/action.yml openjdk-17-17.0.6+10/.github/actions/get-bootjdk/action.yml --- openjdk-17-17.0.5+8/.github/actions/get-bootjdk/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/get-bootjdk/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,109 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Get BootJDK' +description: 'Download the BootJDK from cache or source location' +inputs: + platform: + description: 'Platform' + required: true +outputs: + path: + description: 'Path to the installed BootJDK' + value: ${{ steps.path-name.outputs.path }} + +runs: + using: composite + steps: + - name: 'Determine platform prefix' + id: platform-prefix + run: | + # Convert platform name to upper case + platform_prefix="$(echo ${{ inputs.platform }} | tr [a-z-] [A-Z_])" + echo "value=$platform_prefix" >> $GITHUB_OUTPUT + shell: bash + + - name: 'Get URL configuration' + id: url + uses: ./.github/actions/config + with: + var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_URL + + - name: 'Get SHA256 configuration' + id: sha256 + uses: ./.github/actions/config + with: + var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_SHA256 + + - name: 'Get file extension configuration' + id: ext + uses: ./.github/actions/config + with: + var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_EXT + + - name: 'Check cache for BootJDK' + id: get-cached-bootjdk + uses: actions/cache@v3 + with: + path: bootjdk/jdk + key: boot-jdk-${{ inputs.platform }}-${{ steps.sha256.outputs.value }} + + # macOS is missing sha256sum + - name: 'Install sha256sum' + run: | + # Run Homebrew installation + brew install coreutils + shell: bash + if: steps.get-cached-bootjdk.outputs.cache-hit != 'true' && runner.os == 'macOS' + + - name: 'Download BootJDK' + run: | + # Download BootJDK and verify checksum + mkdir -p bootjdk/jdk + mkdir -p bootjdk/unpacked + wget --progress=dot:mega -O bootjdk/jdk.${{ steps.ext.outputs.value }} '${{ steps.url.outputs.value }}' + echo '${{ steps.sha256.outputs.value }} bootjdk/jdk.${{ steps.ext.outputs.value }}' | sha256sum -c >/dev/null - + shell: bash + if: steps.get-cached-bootjdk.outputs.cache-hit != 'true' + + - name: 'Unpack BootJDK' + run: | + # Unpack the BootJDK and move files to a common location + if [[ '${{ steps.ext.outputs.value }}' == 'tar.gz' ]]; then + tar -xf bootjdk/jdk.${{ steps.ext.outputs.value }} -C bootjdk/unpacked + else + unzip -q bootjdk/jdk.${{ steps.ext.outputs.value }} -d bootjdk/unpacked + fi + jdk_root="$(dirname $(find bootjdk/unpacked -name bin -type d))" + mv "$jdk_root"/* bootjdk/jdk/ + shell: bash + if: steps.get-cached-bootjdk.outputs.cache-hit != 'true' + + - name: 'Export path to where BootJDK is installed' + id: path-name + run: | + # Export the path + echo 'path=bootjdk/jdk' >> $GITHUB_OUTPUT + shell: bash diff -Nru openjdk-17-17.0.5+8/.github/actions/get-bundles/action.yml openjdk-17-17.0.6+10/.github/actions/get-bundles/action.yml --- openjdk-17-17.0.5+8/.github/actions/get-bundles/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/get-bundles/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,109 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Get bundles' +description: 'Download resulting JDK bundles' +inputs: + platform: + description: 'Platform name' + required: true + debug-suffix: + description: 'File name suffix denoting debug level, possibly empty' + required: false +outputs: + jdk-path: + description: 'Path to the installed JDK bundle' + value: ${{ steps.path-name.outputs.jdk }} + symbols-path: + description: 'Path to the installed symbols bundle' + value: ${{ steps.path-name.outputs.symbols }} + tests-path: + description: 'Path to the installed tests bundle' + value: ${{ steps.path-name.outputs.tests }} + +runs: + using: composite + steps: + - name: 'Download bundles artifact' + id: download-bundles + uses: actions/download-artifact@v3 + with: + name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} + path: bundles + continue-on-error: true + + - name: 'Download bundles artifact (retry)' + uses: actions/download-artifact@v3 + with: + name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} + path: bundles + if: steps.download-bundles.outcome == 'failure' + + - name: 'Unpack bundles' + run: | + if [[ -e bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip ]]; then + echo 'Unpacking jdk bundle...' + mkdir -p bundles/jdk + unzip -q bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip -d bundles/jdk + fi + + if [[ -e bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then + echo 'Unpacking jdk bundle...' + mkdir -p bundles/jdk + tar -xf bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/jdk + fi + + if [[ -e bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then + echo 'Unpacking symbols bundle...' + mkdir -p bundles/symbols + tar -xf bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/symbols + fi + + if [[ -e bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then + echo 'Unpacking tests bundle...' + mkdir -p bundles/tests + tar -xf bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/tests + fi + shell: bash + + - name: 'Export paths to where bundles are installed' + id: path-name + run: | + # Export the paths + + jdk_dir="$GITHUB_WORKSPACE/$(dirname $(find bundles/jdk -name bin -type d))" + symbols_dir="$GITHUB_WORKSPACE/$(dirname $(find bundles/symbols -name bin -type d))" + tests_dir="$GITHUB_WORKSPACE/bundles/tests" + + if [[ '${{ runner.os }}' == 'Windows' ]]; then + jdk_dir="$(cygpath $jdk_dir)" + symbols_dir="$(cygpath $symbols_dir)" + tests_dir="$(cygpath $tests_dir)" + fi + + echo "jdk=$jdk_dir" >> $GITHUB_OUTPUT + echo "symbols=$symbols_dir" >> $GITHUB_OUTPUT + echo "tests=$tests_dir" >> $GITHUB_OUTPUT + shell: bash diff -Nru openjdk-17-17.0.5+8/.github/actions/get-gtest/action.yml openjdk-17-17.0.6+10/.github/actions/get-gtest/action.yml --- openjdk-17-17.0.5+8/.github/actions/get-gtest/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/get-gtest/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,54 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Get GTest' +description: 'Download GTest source' +outputs: + path: + description: 'Path to the installed GTest' + value: ${{ steps.path-name.outputs.path }} + +runs: + using: composite + steps: + - name: 'Get GTest version configuration' + id: version + uses: ./.github/actions/config + with: + var: GTEST_VERSION + + - name: 'Checkout GTest source' + uses: actions/checkout@v3 + with: + repository: google/googletest + ref: 'release-${{ steps.version.outputs.value }}' + path: gtest + + - name: 'Export path to where GTest is installed' + id: path-name + run: | + # Export the path + echo 'path=gtest' >> $GITHUB_OUTPUT + shell: bash diff -Nru openjdk-17-17.0.5+8/.github/actions/get-jtreg/action.yml openjdk-17-17.0.6+10/.github/actions/get-jtreg/action.yml --- openjdk-17-17.0.5+8/.github/actions/get-jtreg/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/get-jtreg/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,72 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Get JTReg' +description: 'Download JTReg from cache or source location' +outputs: + path: + description: 'Path to the installed JTReg' + value: ${{ steps.path-name.outputs.path }} + +runs: + using: composite + steps: + - name: 'Get JTReg version configuration' + id: version + uses: ./.github/actions/config + with: + var: JTREG_VERSION + + - name: 'Check cache for JTReg' + id: get-cached-jtreg + uses: actions/cache@v3 + with: + path: jtreg/installed + key: jtreg-${{ steps.version.outputs.value }} + + - name: 'Checkout the JTReg source' + uses: actions/checkout@v3 + with: + repository: openjdk/jtreg + ref: jtreg-${{ steps.version.outputs.value }} + path: jtreg/src + if: steps.get-cached-jtreg.outputs.cache-hit != 'true' + + - name: 'Build JTReg' + run: | + # Build JTReg and move files to the proper locations + bash make/build.sh --jdk "$JAVA_HOME_11_X64" + mkdir ../installed + mv build/images/jtreg/* ../installed + working-directory: jtreg/src + shell: bash + if: steps.get-cached-jtreg.outputs.cache-hit != 'true' + + - name: 'Export path to where JTReg is installed' + id: path-name + run: | + # Export the path + echo 'path=jtreg/installed' >> $GITHUB_OUTPUT + shell: bash diff -Nru openjdk-17-17.0.5+8/.github/actions/get-msys2/action.yml openjdk-17-17.0.6+10/.github/actions/get-msys2/action.yml --- openjdk-17-17.0.5+8/.github/actions/get-msys2/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/get-msys2/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,44 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Get MSYS2' +description: 'Download MSYS2 and prepare a Windows host' + +runs: + using: composite + steps: + - name: 'Install MSYS2' + uses: msys2/setup-msys2@v2 + with: + install: 'autoconf tar unzip zip make' + path-type: minimal + location: msys2 + + # We can't run bash until this is completed, so stick with pwsh + - name: 'Set MSYS2 path' + run: | + # Prepend msys2/msys64/usr/bin to the PATH + echo "$env:GITHUB_WORKSPACE/msys2/msys64/usr/bin" >> $env:GITHUB_PATH + shell: pwsh diff -Nru openjdk-17-17.0.5+8/.github/actions/upload-bundles/action.yml openjdk-17-17.0.6+10/.github/actions/upload-bundles/action.yml --- openjdk-17-17.0.5+8/.github/actions/upload-bundles/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/actions/upload-bundles/action.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,77 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Upload bundles' +description: 'Upload resulting JDK bundles' +inputs: + platform: + description: 'Platform name' + required: true + debug-suffix: + description: 'File name suffix denoting debug level, possibly empty' + required: false + +runs: + using: composite + steps: + + - name: 'Determine bundle names' + id: bundles + run: | + # Rename bundles to consistent names + jdk_bundle_zip="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}.zip 2> /dev/null || true)" + jdk_bundle_tar_gz="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}.tar.gz 2> /dev/null || true)" + symbols_bundle="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}-symbols.tar.gz 2> /dev/null || true)" + tests_bundle="$(ls build/*/bundles/jdk-*_bin-tests${{ inputs.debug-suffix }}.tar.gz 2> /dev/null || true)" + + mkdir bundles + + if [[ "$jdk_bundle_zip" != "" ]]; then + mv "$jdk_bundle_zip" "bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip" + fi + if [[ "$jdk_bundle_tar_gz" != "" ]]; then + mv "$jdk_bundle_tar_gz" "bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz" + fi + if [[ "$symbols_bundle" != "" ]]; then + mv "$symbols_bundle" "bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz" + fi + if [[ "$tests_bundle" != "" ]]; then + mv "$tests_bundle" "bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz" + fi + + if [[ "$jdk_bundle_zip$jdk_bundle_tar_gz$symbols_bundle$tests_bundle" != "" ]]; then + echo 'bundles-found=true' >> $GITHUB_OUTPUT + else + echo 'bundles-found=false' >> $GITHUB_OUTPUT + fi + shell: bash + + - name: 'Upload bundles artifact' + uses: actions/upload-artifact@v3 + with: + name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} + path: bundles + retention-days: 1 + if: steps.bundles.outputs.bundles-found == 'true' diff -Nru openjdk-17-17.0.5+8/.github/scripts/gen-build-failure-report.sh openjdk-17-17.0.6+10/.github/scripts/gen-build-failure-report.sh --- openjdk-17-17.0.5+8/.github/scripts/gen-build-failure-report.sh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/scripts/gen-build-failure-report.sh 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +GITHUB_STEP_SUMMARY="$1" +BUILD_DIR="$(ls -d build/*)" + +# Send signal to the do-build action that we failed +touch "$BUILD_DIR/build-failure" + +( + echo '### :boom: Build failure summary' + echo '' + echo 'The build failed. Here follows the failure summary from the build.' + echo '
    View build failure summary' + echo '' + echo '```' + if [[ -f "$BUILD_DIR/make-support/failure-summary.log" ]]; then + cat "$BUILD_DIR/make-support/failure-summary.log" + else + echo "Failure summary ($BUILD_DIR/make-support/failure-summary.log) not found" + fi + echo '```' + echo '
    ' + echo '' + + echo '' + echo ':arrow_right: To see the entire test log, click the job in the list to the left. To download logs, see the `failure-logs` [artifact above](#artifacts).' +) >> $GITHUB_STEP_SUMMARY diff -Nru openjdk-17-17.0.5+8/.github/scripts/gen-test-results.sh openjdk-17-17.0.6+10/.github/scripts/gen-test-results.sh --- openjdk-17-17.0.5+8/.github/scripts/gen-test-results.sh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/scripts/gen-test-results.sh 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,92 @@ +#!/bin/bash +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +GITHUB_STEP_SUMMARY="$1" + +test_suite_name=$(cat build/run-test-prebuilt/test-support/test-last-ids.txt) +results_dir=build/run-test-prebuilt/test-results/$test_suite_name/text +report_dir=build/run-test-prebuilt/test-support/$test_suite_name + +failures=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/newfailures.txt 2> /dev/null || true) +errors=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/other_errors.txt 2> /dev/null || true) + +if [[ "$failures" = "" && "$errors" = "" ]]; then + # If we have nothing to report, exit this step now + exit 0 +fi + +echo "### Test output for failed tests" >> $GITHUB_STEP_SUMMARY +for test in $failures $errors; do + anchor="$(echo "$test" | tr [A-Z/] [a-z_])" + base_path="$(echo "$test" | tr '#' '_')" + report_file="$report_dir/$base_path.jtr" + hs_err_files=$(ls $report_dir/$base_path/hs_err*.log 2> /dev/null || true) + echo "#### $test" + + echo '
    View test results' + echo '' + echo '```' + if [[ -f "$report_file" ]]; then + cat "$report_file" + else + echo "Error: Result file $report_file not found" + fi + echo '```' + echo '
    ' + echo '' + + if [[ "$hs_err_files" != "" ]]; then + echo '
    View HotSpot error log' + echo '' + for hs_err in $hs_err_files; do + echo '```' + echo "$hs_err:" + echo '' + cat "$hs_err" + echo '```' + done + + echo '
    ' + echo '' + fi + +done >> $GITHUB_STEP_SUMMARY + +# With many failures, the summary can easily exceed 1024 kB, the limit set by Github +# Trim it down if so. +summary_size=$(wc -c < $GITHUB_STEP_SUMMARY) +if [[ $summary_size -gt 1000000 ]]; then + # Trim to below 1024 kB, and cut off after the last detail group + head -c 1000000 $GITHUB_STEP_SUMMARY | tac | sed -n -e '/<\/details>/,$ p' | tac > $GITHUB_STEP_SUMMARY.tmp + mv $GITHUB_STEP_SUMMARY.tmp $GITHUB_STEP_SUMMARY + ( + echo '' + echo ':x: **WARNING: Summary is too large and has been truncated.**' + echo '' + ) >> $GITHUB_STEP_SUMMARY +fi + +echo ':arrow_right: To see the entire test log, click the job in the list to the left.' >> $GITHUB_STEP_SUMMARY diff -Nru openjdk-17-17.0.5+8/.github/scripts/gen-test-summary.sh openjdk-17-17.0.6+10/.github/scripts/gen-test-summary.sh --- openjdk-17-17.0.5+8/.github/scripts/gen-test-summary.sh 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/scripts/gen-test-summary.sh 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +GITHUB_STEP_SUMMARY="$1" +GITHUB_OUTPUT="$2" + +test_suite_name=$(cat build/run-test-prebuilt/test-support/test-last-ids.txt) +results_dir=build/run-test-prebuilt/test-results/$test_suite_name/text + +if [[ ! -f build/run-test-prebuilt/make-support/exit-with-error ]]; then + # There were no failures, exit now + exit +fi + +failures=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/newfailures.txt 2> /dev/null || true) +errors=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/other_errors.txt 2> /dev/null || true) +failure_count=$(echo $failures | wc -w || true) +error_count=$(echo $errors | wc -w || true) + +if [[ "$failures" = "" && "$errors" = "" ]]; then + # We know something went wrong, but not what + echo 'error-message=Unspecified test suite failure. Please see log for job for details.' >> $GITHUB_OUTPUT + exit 0 +fi + +echo 'failure=true' >> $GITHUB_OUTPUT +echo "error-message=Test run reported $failure_count test failure(s) and $error_count error(s). See summary for details." >> $GITHUB_OUTPUT + +echo '### :boom: Test failures summary' >> $GITHUB_STEP_SUMMARY + +if [[ "$failures" != "" ]]; then + echo '' >> $GITHUB_STEP_SUMMARY + echo 'These tests reported failure:' >> $GITHUB_STEP_SUMMARY + for test in $failures; do + anchor="$(echo "$test" | tr [A-Z/] [a-z_])" + echo "* [$test](#user-content-$anchor)" + done >> $GITHUB_STEP_SUMMARY +fi + +if [[ "$errors" != "" ]]; then + echo '' >> $GITHUB_STEP_SUMMARY + echo 'These tests reported errors:' >> $GITHUB_STEP_SUMMARY + for test in $errors; do + anchor="$(echo "$test" | tr [A-Z/] [a-z_])" + echo "* [$test](#user-content-$anchor)" + done >> $GITHUB_STEP_SUMMARY +fi diff -Nru openjdk-17-17.0.5+8/.github/workflows/build-cross-compile.yml openjdk-17-17.0.6+10/.github/workflows/build-cross-compile.yml --- openjdk-17-17.0.5+8/.github/workflows/build-cross-compile.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/build-cross-compile.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,154 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Build (cross-compile)' + +on: + workflow_call: + inputs: + gcc-major-version: + required: false + type: string + default: '10' + apt-gcc-version: + required: false + type: string + default: '10.3.0-1ubuntu1~20.04' + apt-gcc-cross-suffix: + required: false + type: string + default: 'cross1' + +jobs: + build-cross-compile: + name: build + runs-on: ubuntu-20.04 + + strategy: + fail-fast: false + matrix: + target-cpu: + - aarch64 + - arm + - s390x + - ppc64le + include: + - target-cpu: aarch64 + debian-arch: arm64 + gnu-arch: aarch64 + - target-cpu: arm + debian-arch: armhf + gnu-arch: arm + gnu-abi: eabihf + - target-cpu: s390x + debian-arch: s390x + gnu-arch: s390x + - target-cpu: ppc64le + debian-arch: ppc64el + gnu-arch: powerpc64le + + steps: + - name: 'Checkout the JDK source' + uses: actions/checkout@v3 + + - name: 'Get the BootJDK' + id: bootjdk + uses: ./.github/actions/get-bootjdk + with: + platform: linux-x64 + + # Use linux-x64 JDK bundle as build JDK + - name: 'Get build JDK' + id: buildjdk + uses: ./.github/actions/get-bundles + with: + platform: linux-x64 + + # Upgrading apt to solve libc6 installation bugs, see JDK-8260460. + - name: 'Install toolchain and dependencies' + run: | + # Install dependencies using apt-get + sudo apt-get update + sudo apt-get install --only-upgrade apt + sudo apt-get install \ + gcc-${{ inputs.gcc-major-version }}=${{ inputs.apt-gcc-version }} \ + g++-${{ inputs.gcc-major-version }}=${{ inputs.apt-gcc-version }} \ + gcc-${{ inputs.gcc-major-version }}-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}=${{ inputs.apt-gcc-version }}${{ inputs.apt-gcc-cross-suffix }} \ + g++-${{ inputs.gcc-major-version }}-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}=${{ inputs.apt-gcc-version }}${{ inputs.apt-gcc-cross-suffix }} \ + libxrandr-dev libxtst-dev libcups2-dev libasound2-dev + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ inputs.gcc-major-version }} 100 --slave /usr/bin/g++ g++ /usr/bin/g++-${{ inputs.gcc-major-version }} + + - name: 'Check cache for sysroot' + id: get-cached-sysroot + uses: actions/cache@v3 + with: + path: sysroot + key: sysroot-${{ matrix.debian-arch }}-${{ hashFiles('./.github/workflows/build-cross-compile.yml') }} + + - name: 'Install sysroot dependencies' + run: sudo apt-get install debootstrap qemu-user-static + if: steps.get-cached-sysroot.outputs.cache-hit != 'true' + + - name: 'Create sysroot' + run: > + sudo qemu-debootstrap + --arch=${{ matrix.debian-arch }} + --verbose + --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev + --resolve-deps + buster + sysroot + https://httpredir.debian.org/debian/ + if: steps.get-cached-sysroot.outputs.cache-hit != 'true' + + - name: 'Prepare sysroot' + run: | + # Prepare sysroot and remove unused files to minimize cache + sudo chroot sysroot symlinks -cr . + sudo chown ${USER} -R sysroot + rm -rf sysroot/{dev,proc,run,sys} + if: steps.get-cached-sysroot.outputs.cache-hit != 'true' + + - name: 'Configure' + run: > + bash configure + --with-conf-name=linux-${{ matrix.target-cpu }} + --with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA} + --with-boot-jdk=${{ steps.bootjdk.outputs.path }} + --with-zlib=system + --enable-debug + --disable-precompiled-headers + --openjdk-target=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}} + --with-sysroot=sysroot + --with-build-jdk=${{ steps.buildjdk.outputs.jdk-path }} + CC=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-gcc-10 + CXX=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-g++-10 + + - name: 'Build' + id: build + uses: ./.github/actions/do-build + with: + make-target: 'hotspot' + platform: linux-${{ matrix.target-cpu }} diff -Nru openjdk-17-17.0.5+8/.github/workflows/build-linux.yml openjdk-17-17.0.6+10/.github/workflows/build-linux.yml --- openjdk-17-17.0.5+8/.github/workflows/build-linux.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/build-linux.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,132 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Build (linux)' + +on: + workflow_call: + inputs: + platform: + required: true + type: string + extra-conf-options: + required: false + type: string + make-target: + required: false + type: string + default: 'product-bundles test-bundles' + debug-levels: + required: false + type: string + default: '[ "debug", "release" ]' + apt-gcc-version: + required: true + type: string + apt-architecture: + required: false + type: string + apt-extra-packages: + required: false + type: string + +jobs: + build-linux: + name: build + runs-on: ubuntu-20.04 + + strategy: + fail-fast: false + matrix: + debug-level: ${{ fromJSON(inputs.debug-levels) }} + include: + - debug-level: debug + flags: --with-debug-level=fastdebug + suffix: -debug + + steps: + - name: 'Checkout the JDK source' + uses: actions/checkout@v3 + + - name: 'Get the BootJDK' + id: bootjdk + uses: ./.github/actions/get-bootjdk + with: + platform: linux-x64 + + - name: 'Get JTReg' + id: jtreg + uses: ./.github/actions/get-jtreg + + - name: 'Get GTest' + id: gtest + uses: ./.github/actions/get-gtest + + - name: 'Set architecture' + id: arch + run: | + # Set a proper suffix for packages if using a different architecture + if [[ '${{ inputs.apt-architecture }}' != '' ]]; then + echo 'suffix=:${{ inputs.apt-architecture }}' >> $GITHUB_OUTPUT + fi + + # Upgrading apt to solve libc6 installation bugs, see JDK-8260460. + - name: 'Install toolchain and dependencies' + run: | + # Install dependencies using apt-get + if [[ '${{ inputs.apt-architecture }}' != '' ]]; then + sudo dpkg --add-architecture ${{ inputs.apt-architecture }} + fi + sudo apt-get update + sudo apt-get install --only-upgrade apt + sudo apt-get install gcc-${{ inputs.apt-gcc-version }} g++-${{ inputs.apt-gcc-version }} libxrandr-dev${{ steps.arch.outputs.suffix }} libxtst-dev${{ steps.arch.outputs.suffix }} libcups2-dev${{ steps.arch.outputs.suffix }} libasound2-dev${{ steps.arch.outputs.suffix }} ${{ inputs.apt-extra-packages }} + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 + + - name: 'Configure' + run: > + bash configure + --with-conf-name=${{ inputs.platform }} + ${{ matrix.flags }} + --with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA} + --with-boot-jdk=${{ steps.bootjdk.outputs.path }} + --with-jtreg=${{ steps.jtreg.outputs.path }} + --with-gtest=${{ steps.gtest.outputs.path }} + --enable-jtreg-failure-handler + --with-zlib=system + ${{ inputs.extra-conf-options }} + + - name: 'Build' + id: build + uses: ./.github/actions/do-build + with: + make-target: '${{ inputs.make-target }}' + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' + + - name: 'Upload bundles' + uses: ./.github/actions/upload-bundles + with: + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' diff -Nru openjdk-17-17.0.5+8/.github/workflows/build-macos.yml openjdk-17-17.0.6+10/.github/workflows/build-macos.yml --- openjdk-17-17.0.5+8/.github/workflows/build-macos.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/build-macos.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,114 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Build (macos)' + +on: + workflow_call: + inputs: + platform: + required: true + type: string + extra-conf-options: + required: false + type: string + make-target: + required: false + type: string + default: 'product-bundles test-bundles' + debug-levels: + required: false + type: string + default: '[ "debug", "release" ]' + xcode-toolset-version: + required: true + type: string + +jobs: + build-macos: + name: build + runs-on: macos-11 + + strategy: + fail-fast: false + matrix: + debug-level: ${{ fromJSON(inputs.debug-levels) }} + include: + - debug-level: debug + flags: --with-debug-level=fastdebug + suffix: -debug + + steps: + - name: 'Checkout the JDK source' + uses: actions/checkout@v3 + + - name: 'Get the BootJDK' + id: bootjdk + uses: ./.github/actions/get-bootjdk + with: + platform: macos-x64 + + - name: 'Get JTReg' + id: jtreg + uses: ./.github/actions/get-jtreg + + - name: 'Get GTest' + id: gtest + uses: ./.github/actions/get-gtest + + - name: 'Install toolchain and dependencies' + run: | + # Run Homebrew installation and xcode-select + brew install make + sudo xcode-select --switch /Applications/Xcode_${{ inputs.xcode-toolset-version }}.app/Contents/Developer + # This will make GNU make available as 'make' and not only as 'gmake' + echo '/usr/local/opt/make/libexec/gnubin' >> $GITHUB_PATH + + - name: 'Configure' + run: > + bash configure + --with-conf-name=${{ inputs.platform }} + ${{ matrix.flags }} + --with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA} + --with-boot-jdk=${{ steps.bootjdk.outputs.path }} + --with-jtreg=${{ steps.jtreg.outputs.path }} + --with-gtest=${{ steps.gtest.outputs.path }} + --enable-jtreg-failure-handler + --with-zlib=system + ${{ inputs.extra-conf-options }} + + - name: 'Build' + id: build + uses: ./.github/actions/do-build + with: + make-target: '${{ inputs.make-target }}' + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' + + - name: 'Upload bundles' + uses: ./.github/actions/upload-bundles + with: + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' diff -Nru openjdk-17-17.0.5+8/.github/workflows/build-windows.yml openjdk-17-17.0.6+10/.github/workflows/build-windows.yml --- openjdk-17-17.0.5+8/.github/workflows/build-windows.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/build-windows.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,131 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Build (windows)' + +on: + workflow_call: + inputs: + platform: + required: true + type: string + extra-conf-options: + required: false + type: string + make-target: + required: false + type: string + default: 'product-bundles test-bundles' + debug-levels: + required: false + type: string + default: '[ "debug", "release" ]' + msvc-toolset-version: + required: true + type: string + msvc-toolset-architecture: + required: true + type: string + +env: + # These are needed to make the MSYS2 bash work properly + MSYS2_PATH_TYPE: minimal + CHERE_INVOKING: 1 + +jobs: + build-windows: + name: build + runs-on: windows-2019 + defaults: + run: + shell: bash + + strategy: + fail-fast: false + matrix: + debug-level: ${{ fromJSON(inputs.debug-levels) }} + include: + - debug-level: debug + flags: --with-debug-level=fastdebug + suffix: -debug + + steps: + - name: 'Checkout the JDK source' + uses: actions/checkout@v3 + + - name: 'Get MSYS2' + uses: ./.github/actions/get-msys2 + + - name: 'Get the BootJDK' + id: bootjdk + uses: ./.github/actions/get-bootjdk + with: + platform: windows-x64 + + - name: 'Get JTReg' + id: jtreg + uses: ./.github/actions/get-jtreg + + - name: 'Get GTest' + id: gtest + uses: ./.github/actions/get-gtest + + - name: 'Install toolchain and dependencies' + run: | + # Run Visual Studio Installer + '/c/Program Files (x86)/Microsoft Visual Studio/Installer/vs_installer.exe' \ + modify --quiet --installPath 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise' \ + --add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }} + + - name: 'Configure' + run: > + bash configure + --with-conf-name=${{ inputs.platform }} + ${{ matrix.flags }} + --with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA} + --with-boot-jdk=${{ steps.bootjdk.outputs.path }} + --with-jtreg=${{ steps.jtreg.outputs.path }} + --with-gtest=${{ steps.gtest.outputs.path }} + --enable-jtreg-failure-handler + --with-msvc-toolset-version=${{ inputs.msvc-toolset-version }} + ${{ inputs.extra-conf-options }} + env: + # We need a minimal PATH on Windows + # Set PATH to "", so just GITHUB_PATH is included + PATH: '' + + - name: 'Build' + id: build + uses: ./.github/actions/do-build + with: + make-target: '${{ inputs.make-target }}' + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' + + - name: 'Upload bundles' + uses: ./.github/actions/upload-bundles + with: + platform: ${{ inputs.platform }} + debug-suffix: '${{ matrix.suffix }}' diff -Nru openjdk-17-17.0.5+8/.github/workflows/main.yml openjdk-17-17.0.6+10/.github/workflows/main.yml --- openjdk-17-17.0.5+8/.github/workflows/main.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/main.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,331 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'OpenJDK GHA Sanity Checks' + +on: + push: + branches-ignore: + - master + - pr/* + workflow_dispatch: + inputs: + platforms: + description: 'Platform(s) to execute on (comma separated, e.g. "linux-x64, macos, aarch64")' + required: true + default: 'linux-x64, linux-x86, linux-x64-variants, linux-cross-compile, macos-x64, macos-aarch64, windows-x64, windows-aarch64' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + ### + ### Determine platforms to include + ### + + select: + name: 'Select platforms' + runs-on: ubuntu-20.04 + outputs: + linux-x64: ${{ steps.include.outputs.linux-x64 }} + linux-x86: ${{ steps.include.outputs.linux-x86 }} + linux-x64-variants: ${{ steps.include.outputs.linux-x64-variants }} + linux-cross-compile: ${{ steps.include.outputs.linux-cross-compile }} + macos-x64: ${{ steps.include.outputs.macos-x64 }} + macos-aarch64: ${{ steps.include.outputs.macos-aarch64 }} + windows-x64: ${{ steps.include.outputs.windows-x64 }} + windows-aarch64: ${{ steps.include.outputs.windows-aarch64 }} + + steps: + # This function must be inlined in main.yml, or we'd be forced to checkout the repo + - name: 'Check what jobs to run' + id: include + run: | + # Determine which platform jobs to run + + # Returns 'true' if the input platform list matches any of the platform monikers given as argument, + # 'false' otherwise. + # arg $1: platform name or names to look for + function check_platform() { + if [[ '${{ !secrets.JDK_SUBMIT_FILTER || startsWith(github.ref, 'refs/heads/submit/') }}' == 'false' ]]; then + # If JDK_SUBMIT_FILTER is set, and this is not a "submit/" branch, don't run anything + echo 'false' + return + fi + + if [[ $GITHUB_EVENT_NAME == workflow_dispatch ]]; then + input='${{ github.event.inputs.platforms }}' + elif [[ $GITHUB_EVENT_NAME == push ]]; then + input='${{ secrets.JDK_SUBMIT_PLATFORMS }}' + else + echo 'Internal error in GHA' + exit 1 + fi + + normalized_input="$(echo ,$input, | tr -d ' ')" + if [[ "$normalized_input" == ",," ]]; then + # For an empty input, assume all platforms should run + echo 'true' + return + else + # Check for all acceptable platform names + for part in $* ; do + if echo "$normalized_input" | grep -q -e ",$part," ; then + echo 'true' + return + fi + done + fi + + echo 'false' + } + + echo "linux-x64=$(check_platform linux-x64 linux x64)" >> $GITHUB_OUTPUT + echo "linux-x86=$(check_platform linux-x86 linux x86)" >> $GITHUB_OUTPUT + echo "linux-x64-variants=$(check_platform linux-x64-variants variants)" >> $GITHUB_OUTPUT + echo "linux-cross-compile=$(check_platform linux-cross-compile cross-compile)" >> $GITHUB_OUTPUT + echo "macos-x64=$(check_platform macos-x64 macos x64)" >> $GITHUB_OUTPUT + echo "macos-aarch64=$(check_platform macos-aarch64 macos aarch64)" >> $GITHUB_OUTPUT + echo "windows-x64=$(check_platform windows-x64 windows x64)" >> $GITHUB_OUTPUT + echo "windows-aarch64=$(check_platform windows-aarch64 windows aarch64)" >> $GITHUB_OUTPUT + + ### + ### Build jobs + ### + + build-linux-x64: + name: linux-x64 + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x64 + apt-gcc-version: '10=10.3.0-1ubuntu1~20.04' + # The linux-x64 jdk bundle is used as buildjdk for the cross-compile job + if: needs.select.outputs.linux-x64 == 'true' || needs.select.outputs.linux-cross-compile == 'true' + + build-linux-x86: + name: linux-x86 + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x86 + apt-gcc-version: '10-multilib' + apt-architecture: 'i386' + # Some multilib libraries do not have proper inter-dependencies, so we have to + # install their dependencies manually. + apt-extra-packages: 'libfreetype6-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386' + extra-conf-options: '--with-target-bits=32' + if: needs.select.outputs.linux-x86 == 'true' + + build-linux-x64-hs-nopch: + name: linux-x64-hs-nopch + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x64 + make-target: 'hotspot' + debug-levels: '[ "debug" ]' + apt-gcc-version: '10=10.3.0-1ubuntu1~20.04' + extra-conf-options: '--disable-precompiled-headers' + if: needs.select.outputs.linux-x64-variants == 'true' + + build-linux-x64-hs-zero: + name: linux-x64-hs-zero + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x64 + make-target: 'hotspot' + debug-levels: '[ "debug" ]' + apt-gcc-version: '10=10.3.0-1ubuntu1~20.04' + extra-conf-options: '--with-jvm-variants=zero --disable-precompiled-headers' + if: needs.select.outputs.linux-x64-variants == 'true' + + build-linux-x64-hs-minimal: + name: linux-x64-hs-minimal + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x64 + make-target: 'hotspot' + debug-levels: '[ "debug" ]' + apt-gcc-version: '10=10.3.0-1ubuntu1~20.04' + extra-conf-options: '--with-jvm-variants=minimal --disable-precompiled-headers' + if: needs.select.outputs.linux-x64-variants == 'true' + + build-linux-x64-hs-optimized: + name: linux-x64-hs-optimized + needs: select + uses: ./.github/workflows/build-linux.yml + with: + platform: linux-x64 + make-target: 'hotspot' + # Technically this is not the "debug" level, but we can't inject a new matrix state for just this job + debug-levels: '[ "debug" ]' + apt-gcc-version: '10=10.3.0-1ubuntu1~20.04' + extra-conf-options: '--with-debug-level=optimized --disable-precompiled-headers' + if: needs.select.outputs.linux-x64-variants == 'true' + + build-linux-cross-compile: + name: linux-cross-compile + needs: + - select + - build-linux-x64 + uses: ./.github/workflows/build-cross-compile.yml + if: needs.select.outputs.linux-cross-compile == 'true' + + build-macos-x64: + name: macos-x64 + needs: select + uses: ./.github/workflows/build-macos.yml + with: + platform: macos-x64 + xcode-toolset-version: '11.7' + if: needs.select.outputs.macos-x64 == 'true' + + build-macos-aarch64: + name: macos-aarch64 + needs: select + uses: ./.github/workflows/build-macos.yml + with: + platform: macos-aarch64 + xcode-toolset-version: '12.4' + extra-conf-options: '--openjdk-target=aarch64-apple-darwin' + if: needs.select.outputs.macos-aarch64 == 'true' + + build-windows-x64: + name: windows-x64 + needs: select + uses: ./.github/workflows/build-windows.yml + with: + platform: windows-x64 + msvc-toolset-version: '14.25' + msvc-toolset-architecture: 'x86.x64' + if: needs.select.outputs.windows-x64 == 'true' + + build-windows-aarch64: + name: windows-aarch64 + needs: select + uses: ./.github/workflows/build-windows.yml + with: + platform: windows-aarch64 + msvc-toolset-version: '14.29' + msvc-toolset-architecture: 'arm64' + make-target: 'hotspot' + extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin' + if: needs.select.outputs.windows-aarch64 == 'true' + + ### + ### Test jobs + ### + + test-linux-x64: + name: linux-x64 + needs: + - build-linux-x64 + uses: ./.github/workflows/test.yml + with: + platform: linux-x64 + bootjdk-platform: linux-x64 + runs-on: ubuntu-20.04 + + test-linux-x86: + name: linux-x86 + needs: + - build-linux-x86 + uses: ./.github/workflows/test.yml + with: + platform: linux-x86 + bootjdk-platform: linux-x64 + runs-on: ubuntu-20.04 + + test-macos-x64: + name: macos-x64 + needs: + - build-macos-x64 + uses: ./.github/workflows/test.yml + with: + platform: macos-x64 + bootjdk-platform: macos-x64 + runs-on: macos-11 + + test-windows-x64: + name: windows-x64 + needs: + - build-windows-x64 + uses: ./.github/workflows/test.yml + with: + platform: windows-x64 + bootjdk-platform: windows-x64 + runs-on: windows-2019 + + # Remove bundles so they are not misconstrued as binary distributions from the JDK project + remove-bundles: + name: 'Remove bundle artifacts' + runs-on: ubuntu-20.04 + if: always() + needs: + - build-linux-x64 + - build-linux-x86 + - build-linux-x64-hs-nopch + - build-linux-x64-hs-zero + - build-linux-x64-hs-minimal + - build-linux-x64-hs-optimized + - build-linux-cross-compile + - build-macos-x64 + - build-macos-aarch64 + - build-windows-x64 + - build-windows-aarch64 + - test-linux-x64 + - test-linux-x86 + - test-macos-x64 + - test-windows-x64 + + steps: + # Hack to get hold of the api environment variables that are only defined for actions + - name: 'Get API configuration' + id: api + uses: actions/github-script@v6 + with: + script: 'return { url: process.env["ACTIONS_RUNTIME_URL"], token: process.env["ACTIONS_RUNTIME_TOKEN"] }' + + - name: 'Remove bundle artifacts' + run: | + # Find and remove all bundle artifacts + ALL_ARTIFACT_URLS="$(curl -s \ + -H 'Accept: application/json;api-version=6.0-preview' \ + -H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \ + '${{ fromJson(steps.api.outputs.result).url }}_apis/pipelines/workflows/${{ github.run_id }}/artifacts?api-version=6.0-preview')" + BUNDLE_ARTIFACT_URLS="$(echo "$ALL_ARTIFACT_URLS" | jq -r -c '.value | map(select(.name|startswith("bundles-"))) | .[].url')" + for url in $BUNDLE_ARTIFACT_URLS; do + echo "Removing $url" + curl -s \ + -H 'Accept: application/json;api-version=6.0-preview' \ + -H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \ + -X DELETE "$url" \ + || echo "Failed to remove bundle" + done diff -Nru openjdk-17-17.0.5+8/.github/workflows/test.yml openjdk-17-17.0.6+10/.github/workflows/test.yml --- openjdk-17-17.0.5+8/.github/workflows/test.yml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/.github/workflows/test.yml 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,205 @@ +# +# Copyright (c) 2022, 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. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# 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. +# + +name: 'Run tests' + +on: + workflow_call: + inputs: + platform: + required: true + type: string + bootjdk-platform: + required: true + type: string + runs-on: + required: true + type: string + +env: + # These are needed to make the MSYS2 bash work properly + MSYS2_PATH_TYPE: minimal + CHERE_INVOKING: 1 + +jobs: + test: + name: test + runs-on: ${{ inputs.runs-on }} + defaults: + run: + shell: bash + + strategy: + fail-fast: false + matrix: + test-name: + - 'jdk/tier1 part 1' + - 'jdk/tier1 part 2' + - 'jdk/tier1 part 3' + - 'langtools/tier1' + - 'hs/tier1 common' + - 'hs/tier1 compiler' + - 'hs/tier1 gc' + - 'hs/tier1 runtime' + - 'hs/tier1 serviceability' + + include: + - test-name: 'jdk/tier1 part 1' + test-suite: 'test/jdk/:tier1_part1' + + - test-name: 'jdk/tier1 part 2' + test-suite: 'test/jdk/:tier1_part2' + + - test-name: 'jdk/tier1 part 3' + test-suite: 'test/jdk/:tier1_part3' + + - test-name: 'langtools/tier1' + test-suite: 'test/langtools/:tier1' + + - test-name: 'hs/tier1 common' + test-suite: 'test/hotspot/jtreg/:tier1_common' + debug-suffix: -debug + + - test-name: 'hs/tier1 compiler' + test-suite: 'test/hotspot/jtreg/:tier1_compiler' + debug-suffix: -debug + + - test-name: 'hs/tier1 gc' + test-suite: 'test/hotspot/jtreg/:tier1_gc' + debug-suffix: -debug + + - test-name: 'hs/tier1 runtime' + test-suite: 'test/hotspot/jtreg/:tier1_runtime' + debug-suffix: -debug + + - test-name: 'hs/tier1 serviceability' + test-suite: 'test/hotspot/jtreg/:tier1_serviceability' + debug-suffix: -debug + + steps: + - name: 'Checkout the JDK source' + uses: actions/checkout@v3 + + - name: 'Get MSYS2' + uses: ./.github/actions/get-msys2 + if: runner.os == 'Windows' + + - name: 'Get the BootJDK' + id: bootjdk + uses: ./.github/actions/get-bootjdk + with: + platform: ${{ inputs.bootjdk-platform }} + + - name: 'Get JTReg' + id: jtreg + uses: ./.github/actions/get-jtreg + + - name: 'Get bundles' + id: bundles + uses: ./.github/actions/get-bundles + with: + platform: ${{ inputs.platform }} + debug-suffix: ${{ matrix.debug-suffix }} + + - name: 'Install dependencies' + run: | + # On macOS we need to install some dependencies for testing + brew install make + sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer + # This will make GNU make available as 'make' and not only as 'gmake' + echo '/usr/local/opt/make/libexec/gnubin' >> $GITHUB_PATH + if: runner.os == 'macOS' + + - name: 'Set PATH' + id: path + run: | + # We need a minimal PATH on Windows + # Set PATH to "", so just GITHUB_PATH is included + if [[ '${{ runner.os }}' == 'Windows' ]]; then + echo "value=" >> $GITHUB_OUTPUT + else + echo "value=$PATH" >> $GITHUB_OUTPUT + fi + + - name: 'Run tests' + id: run-tests + run: > + make test-prebuilt + TEST='${{ matrix.test-suite }}' + BOOT_JDK=${{ steps.bootjdk.outputs.path }} + JT_HOME=${{ steps.jtreg.outputs.path }} + JDK_IMAGE_DIR=${{ steps.bundles.outputs.jdk-path }} + SYMBOLS_IMAGE_DIR=${{ steps.bundles.outputs.symbols-path }} + TEST_IMAGE_DIR=${{ steps.bundles.outputs.tests-path }} + JTREG='JAVA_OPTIONS=-XX:-CreateCoredumpOnCrash;VERBOSE=fail,error,time;KEYWORDS=!headful' + && bash ./.github/scripts/gen-test-summary.sh "$GITHUB_STEP_SUMMARY" "$GITHUB_OUTPUT" + env: + PATH: ${{ steps.path.outputs.value }} + + # This is a separate step, since if the markdown from a step gets bigger than + # 1024 kB it is skipped, but then the short summary above is still generated + - name: 'Generate test report' + run: bash ./.github/scripts/gen-test-results.sh "$GITHUB_STEP_SUMMARY" + if: always() + + - name: 'Package test results' + id: package + run: | + # Package test-results and relevant parts of test-support + mkdir results + + if [[ -d build/run-test-prebuilt/test-results ]]; then + cd build/run-test-prebuilt/test-results/ + zip -r -9 "$GITHUB_WORKSPACE/results/test-results.zip" . + cd $GITHUB_WORKSPACE + else + echo '::warning ::Missing test-results directory' + fi + + if [[ -d build/run-test-prebuilt/test-support ]]; then + cd build/run-test-prebuilt/test-support/ + zip -r -9 "$GITHUB_WORKSPACE/results/test-support.zip" . -i *.jtr -i */hs_err*.log -i */replay*.log + cd $GITHUB_WORKSPACE + else + echo '::warning ::Missing test-support directory' + fi + + artifact_name="results-${{ inputs.platform }}-$(echo ${{ matrix.test-name }} | tr '/ ' '__')" + echo "artifact-name=$artifact_name" >> $GITHUB_OUTPUT + if: always() + + - name: 'Upload test results' + uses: actions/upload-artifact@v3 + with: + path: results + name: ${{ steps.package.outputs.artifact-name }} + if: always() + + # This is the best way I found to abort the job with an error message + - name: 'Notify about test failures' + uses: actions/github-script@v6 + with: + script: core.setFailed('${{ steps.run-tests.outputs.error-message }}') + if: steps.run-tests.outputs.failure == 'true' diff -Nru openjdk-17-17.0.5+8/.gitignore openjdk-17-17.0.6+10/.gitignore --- openjdk-17-17.0.5+8/.gitignore 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/.gitignore 2023-01-10 13:21:55.000000000 +0000 @@ -16,3 +16,5 @@ **/JTreport/** **/JTwork/** /src/utils/LogCompilation/target/ +/.project/ +/.settings/ diff -Nru openjdk-17-17.0.5+8/.jcheck/conf openjdk-17-17.0.6+10/.jcheck/conf --- openjdk-17-17.0.5+8/.jcheck/conf 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/.jcheck/conf 2023-01-10 13:21:55.000000000 +0000 @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=17.0.5 +version=17.0.6 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff -Nru openjdk-17-17.0.5+8/make/autoconf/basic_tools.m4 openjdk-17-17.0.6+10/make/autoconf/basic_tools.m4 --- openjdk-17-17.0.5+8/make/autoconf/basic_tools.m4 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/basic_tools.m4 2023-01-10 13:21:55.000000000 +0000 @@ -160,25 +160,23 @@ AC_DEFUN([BASIC_CHECK_MAKE_OUTPUT_SYNC], [ # Check if make supports the output sync option and if so, setup using it. - AC_MSG_CHECKING([if make --output-sync is supported]) - if $MAKE --version -O > /dev/null 2>&1; then - OUTPUT_SYNC_SUPPORTED=true - AC_MSG_RESULT([yes]) - AC_MSG_CHECKING([for output-sync value]) - AC_ARG_WITH([output-sync], [AS_HELP_STRING([--with-output-sync], - [set make output sync type if supported by make. @<:@recurse@:>@])], - [OUTPUT_SYNC=$with_output_sync]) - if test "x$OUTPUT_SYNC" = "x"; then - OUTPUT_SYNC=none - fi - AC_MSG_RESULT([$OUTPUT_SYNC]) - if ! $MAKE --version -O$OUTPUT_SYNC > /dev/null 2>&1; then - AC_MSG_ERROR([Make did not the support the value $OUTPUT_SYNC as output sync type.]) - fi - else - OUTPUT_SYNC_SUPPORTED=false - AC_MSG_RESULT([no]) - fi + UTIL_ARG_WITH(NAME: output-sync, TYPE: literal, + VALID_VALUES: [none recurse line target], DEFAULT: recurse, + OPTIONAL: true, ENABLED_DEFAULT: true, + ENABLED_RESULT: OUTPUT_SYNC_SUPPORTED, + CHECKING_MSG: [for make --output-sync value], + DESC: [set make --output-sync type if supported by make], + CHECK_AVAILABLE: + [ + AC_MSG_CHECKING([if make --output-sync is supported]) + if ! $MAKE --version -O > /dev/null 2>&1; then + AC_MSG_RESULT([no]) + AVAILABLE=false + else + AC_MSG_RESULT([yes]) + fi + ] + ) AC_SUBST(OUTPUT_SYNC_SUPPORTED) AC_SUBST(OUTPUT_SYNC) ]) @@ -378,43 +376,6 @@ UTIL_REQUIRE_PROGS(MIG, mig) UTIL_REQUIRE_PROGS(XATTR, xattr) UTIL_LOOKUP_PROGS(CODESIGN, codesign) - - if test "x$CODESIGN" != "x"; then - # Check for user provided code signing identity. - # If no identity was provided, fall back to "openjdk_codesign". - AC_ARG_WITH([macosx-codesign-identity], [AS_HELP_STRING([--with-macosx-codesign-identity], - [specify the code signing identity])], - [MACOSX_CODESIGN_IDENTITY=$with_macosx_codesign_identity], - [MACOSX_CODESIGN_IDENTITY=openjdk_codesign] - ) - - AC_SUBST(MACOSX_CODESIGN_IDENTITY) - - # Verify that the codesign certificate is present - AC_MSG_CHECKING([if codesign certificate is present]) - $RM codesign-testfile - $TOUCH codesign-testfile - $CODESIGN -s "$MACOSX_CODESIGN_IDENTITY" codesign-testfile 2>&AS_MESSAGE_LOG_FD \ - >&AS_MESSAGE_LOG_FD || CODESIGN= - $RM codesign-testfile - if test "x$CODESIGN" = x; then - AC_MSG_RESULT([no]) - else - AC_MSG_RESULT([yes]) - # Verify that the codesign has --option runtime - AC_MSG_CHECKING([if codesign has --option runtime]) - $RM codesign-testfile - $TOUCH codesign-testfile - $CODESIGN --option runtime -s "$MACOSX_CODESIGN_IDENTITY" codesign-testfile \ - 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD || CODESIGN= - $RM codesign-testfile - if test "x$CODESIGN" = x; then - AC_MSG_ERROR([codesign does not have --option runtime. macOS 10.13.6 and above is required.]) - else - AC_MSG_RESULT([yes]) - fi - fi - fi UTIL_REQUIRE_PROGS(SETFILE, SetFile) fi if ! test "x$OPENJDK_TARGET_OS" = "xwindows"; then diff -Nru openjdk-17-17.0.5+8/make/autoconf/compare.sh.in openjdk-17-17.0.6+10/make/autoconf/compare.sh.in --- openjdk-17-17.0.5+8/make/autoconf/compare.sh.in 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/compare.sh.in 2023-01-10 13:21:55.000000000 +0000 @@ -40,6 +40,7 @@ export BASH="@BASH@" export CAT="@CAT@" export CMP="@CMP@" +export CODESIGN="@CODESIGN@" export CP="@CP@" export CUT="@CUT@" export DIFF="@DIFF@" diff -Nru openjdk-17-17.0.5+8/make/autoconf/configure.ac openjdk-17-17.0.6+10/make/autoconf/configure.ac --- openjdk-17-17.0.5+8/make/autoconf/configure.ac 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/configure.ac 2023-01-10 13:21:55.000000000 +0000 @@ -249,6 +249,7 @@ JDKOPT_ENABLE_DISABLE_MANPAGES JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT +JDKOPT_SETUP_MACOSX_SIGNING ############################################################################### # diff -Nru openjdk-17-17.0.5+8/make/autoconf/jdk-options.m4 openjdk-17-17.0.6+10/make/autoconf/jdk-options.m4 --- openjdk-17-17.0.5+8/make/autoconf/jdk-options.m4 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/jdk-options.m4 2023-01-10 13:21:55.000000000 +0000 @@ -727,3 +727,105 @@ AC_SUBST(SOURCE_DATE) AC_SUBST(ENABLE_REPRODUCIBLE_BUILD) ]) + +################################################################################ +# +# Setup signing on macOS. This can either be setup to sign with a real identity +# and enabling the hardened runtime, or it can simply add the debug entitlement +# com.apple.security.get-task-allow without actually signing any binaries. The +# latter is needed to be able to debug processes and dump core files on modern +# versions of macOS. It can also be skipped completely. +# +# Check if codesign will run with the given parameters +# $1: Parameters to run with +# $2: Checking message +# Sets CODESIGN_SUCCESS=true/false +AC_DEFUN([JDKOPT_CHECK_CODESIGN_PARAMS], +[ + PARAMS="$1" + MESSAGE="$2" + CODESIGN_TESTFILE="$CONFIGURESUPPORT_OUTPUTDIR/codesign-testfile" + $RM "$CODESIGN_TESTFILE" + $TOUCH "$CODESIGN_TESTFILE" + CODESIGN_SUCCESS=false + $CODESIGN $PARAMS "$CODESIGN_TESTFILE" 2>&AS_MESSAGE_LOG_FD \ + >&AS_MESSAGE_LOG_FD && CODESIGN_SUCCESS=true + $RM "$CODESIGN_TESTFILE" + AC_MSG_CHECKING([$MESSAGE]) + if test "x$CODESIGN_SUCCESS" = "xtrue"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi +]) + +AC_DEFUN([JDKOPT_CHECK_CODESIGN_HARDENED], +[ + JDKOPT_CHECK_CODESIGN_PARAMS([-s "$MACOSX_CODESIGN_IDENTITY" --option runtime], + [if codesign with hardened runtime is possible]) +]) + +AC_DEFUN([JDKOPT_CHECK_CODESIGN_DEBUG], +[ + JDKOPT_CHECK_CODESIGN_PARAMS([-s -], [if debug mode codesign is possible]) +]) + +AC_DEFUN([JDKOPT_SETUP_MACOSX_SIGNING], +[ + ENABLE_CODESIGN=false + if test "x$OPENJDK_TARGET_OS" = "xmacosx" && test "x$CODESIGN" != "x"; then + + UTIL_ARG_WITH(NAME: macosx-codesign, TYPE: literal, OPTIONAL: true, + VALID_VALUES: [hardened debug auto], DEFAULT: auto, + ENABLED_DEFAULT: true, + CHECKING_MSG: [for macosx code signing mode], + DESC: [set the macosx code signing mode (hardened, debug, auto)] + ) + + MACOSX_CODESIGN_MODE=disabled + if test "x$MACOSX_CODESIGN_ENABLED" = "xtrue"; then + + # Check for user provided code signing identity. + UTIL_ARG_WITH(NAME: macosx-codesign-identity, TYPE: string, + DEFAULT: openjdk_codesign, CHECK_VALUE: UTIL_CHECK_STRING_NON_EMPTY, + DESC: [specify the macosx code signing identity], + CHECKING_MSG: [for macosx code signing identity] + ) + AC_SUBST(MACOSX_CODESIGN_IDENTITY) + + if test "x$MACOSX_CODESIGN" = "xauto"; then + # Only try to default to hardened signing on release builds + if test "x$DEBUG_LEVEL" = "xrelease"; then + JDKOPT_CHECK_CODESIGN_HARDENED + if test "x$CODESIGN_SUCCESS" = "xtrue"; then + MACOSX_CODESIGN_MODE=hardened + fi + fi + if test "x$MACOSX_CODESIGN_MODE" = "xdisabled"; then + JDKOPT_CHECK_CODESIGN_DEBUG + if test "x$CODESIGN_SUCCESS" = "xtrue"; then + MACOSX_CODESIGN_MODE=debug + fi + fi + AC_MSG_CHECKING([for macosx code signing mode]) + AC_MSG_RESULT([$MACOSX_CODESIGN_MODE]) + elif test "x$MACOSX_CODESIGN" = "xhardened"; then + JDKOPT_CHECK_CODESIGN_HARDENED + if test "x$CODESIGN_SUCCESS" = "xfalse"; then + AC_MSG_ERROR([Signing with hardened runtime is not possible]) + fi + MACOSX_CODESIGN_MODE=hardened + elif test "x$MACOSX_CODESIGN" = "xdebug"; then + JDKOPT_CHECK_CODESIGN_DEBUG + if test "x$CODESIGN_SUCCESS" = "xfalse"; then + AC_MSG_ERROR([Signing in debug mode is not possible]) + fi + MACOSX_CODESIGN_MODE=debug + else + AC_MSG_ERROR([unknown value for --with-macosx-codesign: $MACOSX_CODESIGN]) + fi + fi + AC_SUBST(MACOSX_CODESIGN_IDENTITY) + AC_SUBST(MACOSX_CODESIGN_MODE) + fi +]) diff -Nru openjdk-17-17.0.5+8/make/autoconf/spec.gmk.in openjdk-17-17.0.6+10/make/autoconf/spec.gmk.in --- openjdk-17-17.0.5+8/make/autoconf/spec.gmk.in 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/spec.gmk.in 2023-01-10 13:21:55.000000000 +0000 @@ -443,7 +443,8 @@ # The highest allowed version of macosx MACOSX_VERSION_MAX=@MACOSX_VERSION_MAX@ -# The macosx code signing identity to use +# The macosx code signing configuration +MACOSX_CODESIGN_MODE:=@MACOSX_CODESIGN_MODE@ MACOSX_CODESIGN_IDENTITY=@MACOSX_CODESIGN_IDENTITY@ # Toolchain type: gcc, clang, xlc, microsoft... diff -Nru openjdk-17-17.0.5+8/make/autoconf/util.m4 openjdk-17-17.0.6+10/make/autoconf/util.m4 --- openjdk-17-17.0.5+8/make/autoconf/util.m4 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/autoconf/util.m4 2023-01-10 13:21:55.000000000 +0000 @@ -325,12 +325,12 @@ # Creates a command-line option using the --enable-* pattern. Will return a # value of 'true' or 'false' in the RESULT variable, depending on whether the # option was enabled or not by the user. The option can not be turned on if it -# is not available, as specified by AVAILABLE and/or AVAILABLE_CHECK. +# is not available, as specified by AVAILABLE and/or CHECK_AVAILABLE. # # Arguments: # NAME: The base name of this option (i.e. what follows --enable-). Required. # RESULT: The name of the variable to set to the result. Defaults to -# _RESULT. +# _ENABLED. # DEFAULT: The default value for this option. Can be true, false or auto. # Defaults to true. # AVAILABLE: If true, this option is allowed to be selected. Defaults to true. @@ -376,7 +376,7 @@ m4_define([ARG_DESC], m4_if(ARG_DESC, , [Enable the ARG_NAME feature], m4_normalize(ARG_DESC))) # If CHECKING_MSG is not specified, set it to a generic description. - m4_define([ARG_CHECKING_MSG], m4_if(ARG_CHECKING_MSG, , [for --enable-ARG_NAME], ARG_CHECKING_MSG)) + m4_define([ARG_CHECKING_MSG], m4_if(ARG_CHECKING_MSG, , [for --enable-ARG_NAME], m4_normalize(ARG_CHECKING_MSG))) # If the code blocks are not given, set them to the empty statements to avoid # tripping up bash. @@ -463,3 +463,351 @@ fi ]) +############################################################################### +# Helper functions for ARG_WITH, to validate different types of argument + +# Dispatcher to call the correct UTIL_CHECK_TYPE_* function depending on the ARG_TYPE +AC_DEFUN([UTIL_CHECK_TYPE], +[ + UTIL_CHECK_TYPE_$1($2) +]) + +AC_DEFUN([UTIL_CHECK_TYPE_string], +[ + # All strings always passes +]) + +AC_DEFUN([UTIL_CHECK_TYPE_integer], +[ + # Check that the argument is an integer + # Additional [] needed to keep m4 from mangling shell constructs. + [ if [[ ! "$1" =~ ^[0-9]+$ ]] ; then ] + FAILURE="Not an integer: $1" + fi +]) + +AC_DEFUN([UTIL_CHECK_TYPE_file], +[ + # Check that the argument is an existing file + if test ! -f "$1" ; then + FAILURE="File $1 does not exist or is not readable" + fi +]) + +AC_DEFUN([UTIL_CHECK_TYPE_directory], +[ + # Check that the argument is an existing directory + if test ! -d "$1" ; then + FAILURE="Directory $1 does not exist or is not readable" + fi + + if test "[x]ARG_CHECK_FOR_FILES" != x; then + for file in ARG_CHECK_FOR_FILES; do + found_files=$($ECHO $(ls $1/$file 2> /dev/null)) + if test "x$found_files" = x; then + FAILURE="Directory $1 does not contain $file" + break + elif ! test -e "$found_files"; then + FAILURE="Directory $1 contains multiple $file: $found_files" + break + fi + done + fi +]) + +AC_DEFUN([UTIL_CHECK_TYPE_literal], +[ + # Check if it contains a space between non-space characters + # Additional [] needed to keep m4 from mangling shell constructs. + [ if [[ "$1" =~ [^' ']' '+[^' '] ]] ; then ] + FAILURE="Multiple words: $1" + fi + + # Check that the selected variants are valid + UTIL_GET_NON_MATCHING_VALUES(invalid_value, $1, \ + ARG_VALID_VALUES) + if test "x$invalid_value" != x; then + FAILURE="Invalid value: $invalid_value. Valid values are: ARG_VALID_VALUES" + fi +]) + +AC_DEFUN([UTIL_CHECK_TYPE_multivalue], +[ + # We accept either space or comma as separator, but use space internally + values=`$ECHO $1 | $SED -e 's/,/ /g'` + + # Check that the selected variants are valid + UTIL_GET_NON_MATCHING_VALUES(invalid_value, $values, \ + ARG_VALID_VALUES) + if test "x$invalid_value" != x; then + FAILURE="Invalid value(s): $invalid_value. Valid values are: ARG_VALID_VALUES" + fi + + # Update to version without comma + ARG_RESULT=$($ECHO $values) +]) + +AC_DEFUN([UTIL_CHECK_TYPE_features], +[ + # We accept either space or comma as separator, but use space internally + feature_list=`$ECHO $1 | $SED -e 's/,/ /g'` + features_enabled=`$ECHO $feature_list | \ + $AWK '{ for (i=1; i<=NF; i++) if (!match($i, /^-.*/)) printf("%s ", $i) }'` + features_disabled=`$ECHO $feature_list | \ + $AWK '{ for (i=1; i<=NF; i++) if (match($i, /^-.*/)) printf("%s ", substr($i, 2))}'` + + # Check that the selected features are valid + UTIL_GET_NON_MATCHING_VALUES(invalid_features, $features_enabled \ + $features_disabled, ARG_VALID_VALUES) + if test "x$invalid_features" != x; then + FAILURE="Invalid feature(s): $invalid_features. Valid values are: ARG_VALID_VALUES" + fi + + # Update to version without comma + ARG_RESULT=$($ECHO $feature_list) +]) + +############################################################################### +# Creates a command-line option using the --with-* pattern. Will return a +# string in the RESULT variable with the option provided by the user, or the +# empty string if the --with-* option was not given. The option can not be given +# if it is not available, as specified by AVAILABLE and/or CHECK_AVAILABLE. +# +# Arguments: +# NAME: The base name of this option (i.e. what follows --with-). Required. +# TYPE: The type of the value. Can be one of "string", "integer", "file", +# "directory", "literal", "multivalue" or "features". Required. +# DEFAULT: The default value for this option. Can be any valid string. +# Required. +# OPTIONAL: If this feature can be disabled. Defaults to false. If true, +# the feature can be disabled using --without-FOO, --with-FOO=no, or +# --with-FOO=. Check the ENABLED_RESULT variable for the enabled/disabled +# state. +# RESULT: The name of the variable to set to the result. Defaults to +# . Set to empty if ENABLED_RESULT is false. +# ENABLED_DEFAULT: If the value is enabled by default. Defaults to false. Only +# relevant if OPTIONAL is true. +# ENABLED_RESULT: The name of the variable to set to the enabled/disabled +# result state. Defaults to _ENABLED. +# AVAILABLE: If true, this option is allowed to be selected. Defaults to true. +# DESC: A description of this option. Defaults to a generic and unhelpful +# string. +# DEFAULT_DESC: A message describing the default value, for the help. Defaults +# to the literal value of DEFAULT, or "" if DEFAULT is empty. +# CHECKING_MSG: The message to present to user when checking this option. +# Defaults to a generic message. +# CHECK_AVAILABLE: An optional code block to execute to determine if the +# option should be available. Must set AVAILABLE to 'false' if not. +# VALID_VALUES: A list of literals that are the allowed values. Only valid if +# TYPE is "literal", "multivalue" or "features". +# CHECK_VALUE: An optional code block to execute to determine if the value +# is correct. Must set FAILURE to a non-empty string if not. This string +# will be displayed. The value is given in $RESULT. +# CHECK_FOR_FILES: A list of files to verify the presence for. Only valid if +# TYPE is "directory". Paths are relative the directory given as value. +# Wildcards are accepted. Exactly one matching file must be found, for each +# listed file, or FAILURE is set. +# IF_AUTO: An optional code block to execute if the value is "auto", either by +# default or given by the command line. Must set RESULT to the calculated +# value. +# IF_GIVEN: An optional code block to execute if the option was given on the +# command line (regardless of the value). +# IF_NOT_GIVEN: An optional code block to execute if the option was not given +# on the command line (regardless of the value). +# +UTIL_DEFUN_NAMED([UTIL_ARG_WITH], + [*NAME *TYPE *DEFAULT OPTIONAL RESULT ENABLED_DEFAULT ENABLED_RESULT + AVAILABLE DESC DEFAULT_DESC CHECKING_MSG CHECK_AVAILABLE VALID_VALUES + CHECK_VALUE CHECK_FOR_FILES IF_AUTO IF_GIVEN IF_NOT_GIVEN], [$@], +[ + ########################## + # Part 1: Set up m4 macros + ########################## + + # If ENABLED_DEFAULT is not specified, set it to 'false'. + m4_define([ARG_ENABLED_DEFAULT], m4_if(ARG_ENABLED_DEFAULT, , false, ARG_ENABLED_DEFAULT)) + + # If AVAILABLE is not specified, set it to 'true'. + m4_define([ARG_AVAILABLE], m4_if(ARG_AVAILABLE, , true, ARG_AVAILABLE)) + + # If OPTIONAL is not specified, set it to 'false'. + m4_define([ARG_OPTIONAL], m4_if(ARG_OPTIONAL, , false, ARG_OPTIONAL)) + + # If DEFAULT_DESC is not specified, calculate it from DEFAULT. + m4_define([ARG_DEFAULT_DESC], m4_if(ARG_DEFAULT_DESC, , m4_if(ARG_DEFAULT, , , ARG_DEFAULT), ARG_DEFAULT_DESC)) + + # If RESULT is not specified, set it to 'ARG_NAME'. + m4_define([ARG_RESULT], m4_if(ARG_RESULT, , m4_translit(ARG_NAME, [a-z-], [A-Z_]), ARG_RESULT)) + + # If ENABLED_RESULT is not specified, set it to 'ARG_NAME[_ENABLED]'. + m4_define([ARG_ENABLED_RESULT], m4_if(ARG_ENABLED_RESULT, , m4_translit(ARG_NAME, [a-z-], [A-Z_])[_ENABLED], ARG_ENABLED_RESULT)) + + # Construct shell variable names for the option + m4_define(ARG_OPTION, [with_]m4_translit(ARG_NAME, [-], [_])) + m4_define(ARG_GIVEN, m4_translit(ARG_NAME, [a-z-], [A-Z_])[_GIVEN]) + + # If DESC is not specified, set it to a generic description. + m4_define([ARG_DESC], m4_if(ARG_DESC, , [Give a value for the ARG_NAME feature], m4_normalize(ARG_DESC))) + + # If CHECKING_MSG is not specified, set it to a generic description. + m4_define([ARG_CHECKING_MSG], m4_if(ARG_CHECKING_MSG, , [for --with-ARG_NAME], m4_normalize(ARG_CHECKING_MSG))) + + m4_define([ARG_HAS_AUTO_BLOCK], m4_if(ARG_IF_AUTO, , false, true)) + + # If the code blocks are not given, set them to the empty statements to avoid + # tripping up bash. + m4_define([ARG_CHECK_AVAILABLE], m4_if(ARG_CHECK_AVAILABLE, , :, ARG_CHECK_AVAILABLE)) + m4_define([ARG_CHECK_VALUE], m4_if(ARG_CHECK_VALUE, , :, ARG_CHECK_VALUE)) + m4_define([ARG_CHECK_FOR_FILES], m4_if(ARG_CHECK_FOR_FILES, , :, ARG_CHECK_FOR_FILES)) + m4_define([ARG_IF_AUTO], m4_if(ARG_IF_AUTO, , :, ARG_IF_AUTO)) + m4_define([ARG_IF_GIVEN], m4_if(ARG_IF_GIVEN, , :, ARG_IF_GIVEN)) + m4_define([ARG_IF_NOT_GIVEN], m4_if(ARG_IF_NOT_GIVEN, , :, ARG_IF_NOT_GIVEN)) + + ########################## + # Part 2: Set up autoconf shell code + ########################## + + # Check that OPTIONAL has a valid value + if test "[x]ARG_OPTIONAL" != xtrue && test "[x]ARG_OPTIONAL" != xfalse ; then + AC_MSG_ERROR([Internal error: Argument OPTIONAL to [UTIL_ARG_WITH] can only be true or false, was: 'ARG_OPTIONAL']) + fi + + # Check that ENABLED_DEFAULT has a valid value + if test "[x]ARG_ENABLED_DEFAULT" != xtrue && test "[x]ARG_ENABLED_DEFAULT" != xfalse ; then + AC_MSG_ERROR([Internal error: Argument ENABLED_DEFAULT to [UTIL_ARG_WITH] can only be true or false, was: 'ARG_ENABLED_DEFAULT']) + fi + + # Check that AVAILABLE has a valid value + if test "[x]ARG_AVAILABLE" != xtrue && test "[x]ARG_AVAILABLE" != xfalse; then + AC_MSG_ERROR([Internal error: Argument AVAILABLE to [UTIL_ARG_WITH] can only be true or false, was: 'ARG_AVAILABLE']) + fi + + # Check that TYPE has a valid value + # Need to assign since we can't expand ARG TYPE inside the m4 quoted if statement + TEST_TYPE="ARG_TYPE" + # Additional [] needed to keep m4 from mangling shell constructs. + [ if [[ ! "$TEST_TYPE" =~ ^(string|integer|file|directory|literal|multivalue|features)$ ]] ; then ] + AC_MSG_ERROR([Internal error: Argument TYPE to [UTIL_ARG_WITH] must be a valid type, was: 'ARG_TYPE']) + fi + + AC_ARG_WITH(ARG_NAME, AS_HELP_STRING([--with-]ARG_NAME, + [ARG_DESC [ARG_DEFAULT_DESC]]), [ARG_GIVEN=true], [ARG_GIVEN=false]) + + # Check if the option is available + AVAILABLE=ARG_AVAILABLE + # Run the available check block (if any), which can overwrite AVAILABLE. + ARG_CHECK_AVAILABLE + + # Check if the option should be turned on + echo check msg:ARG_CHECKING_MSG: + AC_MSG_CHECKING(ARG_CHECKING_MSG) + + if test x$AVAILABLE = xfalse; then + ARG_RESULT="$ARG_OPTION" + ARG_ENABLED_RESULT=false + REASON="not available" + else + if test x$ARG_GIVEN = xfalse; then + ARG_RESULT="ARG_DEFAULT" + if test "[x]ARG_OPTIONAL" = xtrue; then + ARG_ENABLED_RESULT=ARG_ENABLED_DEFAULT + else + ARG_ENABLED_RESULT=true + fi + REASON="default" + + else # ARG_GIVEN is true + # Special treatment of "yes" and "no" for "--with-ARG" and "--without-ARG" + if test "x$ARG_OPTION" = xyes || test "x$ARG_OPTION" = xno || test "x$ARG_OPTION" = x ; then + if test "[x]ARG_OPTIONAL" = xfalse; then + if test "x$ARG_OPTION" = x; then + # If not optional, the empty string is a valid value + ARG_RESULT="" + ARG_ENABLED_RESULT=true + REASON="from command line" + else + AC_MSG_RESULT([invalid]) + AC_MSG_ERROR([Option [--with-]ARG_NAME must have a specified value]) + fi + else + if test "x$ARG_OPTION" = xyes; then + ARG_RESULT="ARG_DEFAULT" + ARG_ENABLED_RESULT=true + REASON="default as enabled from command line" + else + # For optional values, both --without-FOO and --with-FOO= disables + ARG_RESULT="" + ARG_ENABLED_RESULT=false + REASON="from command line" + fi + fi + else + # The most common case -- the user gives a value for the option. + ARG_RESULT="$ARG_OPTION" + ARG_ENABLED_RESULT=true + REASON="from command line" + fi + fi + fi + + if test "x$ARG_ENABLED_RESULT" = xfalse; then + if test "x$REASON" = "xnot available"; then + AC_MSG_RESULT([, $REASON]) + if test "x$ARG_RESULT" != "x" && test "x$ARG_RESULT" != "xno" ; then + AC_MSG_WARN([Option [--with-]ARG_NAME is not available for this configuration]) + fi + else + AC_MSG_RESULT([, $REASON]) + fi + ARG_RESULT="" + else + if test [x]ARG_HAS_AUTO_BLOCK = xtrue && test "x$ARG_RESULT" = xauto; then + # Execute "auto" payload + ARG_IF_AUTO + + ARG_RESULT="$RESULT" + REASON="$REASON (calculated from 'auto')" + fi + + if test "x$ARG_RESULT" = x; then + AC_MSG_RESULT([, $REASON]) + else + AC_MSG_RESULT([$ARG_RESULT, $REASON]) + fi + fi + + # Verify value + # First use our dispatcher to verify that type requirements are satisfied + UTIL_CHECK_TYPE(ARG_TYPE, $ARG_RESULT) + + if test "x$FAILURE" = x; then + # Execute custom verification payload, if present + RESULT="$ARG_RESULT" + + ARG_CHECK_VALUE + + ARG_RESULT="$RESULT" + fi + + if test "x$FAILURE" != x; then + AC_MSG_NOTICE([Invalid value for [--with-]ARG_NAME: "$ARG_RESULT"]) + AC_MSG_NOTICE([$FAILURE]) + AC_MSG_ERROR([Cannot continue]) + fi + + # Execute result payloads, if present + if test x$ARG_GIVEN = xtrue; then + ARG_IF_GIVEN + else + ARG_IF_NOT_GIVEN + fi +]) + +############################################################################### +# Helper functions for CHECK_VALUE in ARG_WITH. +AC_DEFUN([UTIL_CHECK_STRING_NON_EMPTY], +[ + if test "x$RESULT" = "x"; then + FAILURE="Value cannot be empty" + fi +]) diff -Nru openjdk-17-17.0.5+8/make/Bundles.gmk openjdk-17-17.0.6+10/make/Bundles.gmk --- openjdk-17-17.0.5+8/make/Bundles.gmk 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/Bundles.gmk 2023-01-10 13:21:55.000000000 +0000 @@ -278,16 +278,7 @@ $(SYMBOLS_EXCLUDE_PATTERN), \ $(ALL_JRE_FILES)) - # On Macosx release builds, when there is a code signing certificate available, - # the final bundle layout can be signed. - SIGN_BUNDLE := false - ifeq ($(call isTargetOs, macosx)+$(DEBUG_LEVEL), true+release) - ifneq ($(CODESIGN), ) - SIGN_BUNDLE := true - endif - endif - - ifeq ($(SIGN_BUNDLE), true) + ifeq ($(MACOSX_CODESIGN_MODE), hardened) # Macosx release build and code signing available. ################################################################################ diff -Nru openjdk-17-17.0.5+8/make/common/modules/LauncherCommon.gmk openjdk-17-17.0.6+10/make/common/modules/LauncherCommon.gmk --- openjdk-17-17.0.5+8/make/common/modules/LauncherCommon.gmk 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/common/modules/LauncherCommon.gmk 2023-01-10 13:21:55.000000000 +0000 @@ -44,7 +44,6 @@ LAUNCHER_SRC := $(TOPDIR)/src/java.base/share/native/launcher LAUNCHER_CFLAGS += -I$(TOPDIR)/src/java.base/share/native/launcher \ - -I$(TOPDIR)/src/java.desktop/share/native/include \ -I$(TOPDIR)/src/java.base/share/native/libjli \ -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli \ -I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjli \ diff -Nru openjdk-17-17.0.5+8/make/common/NativeCompilation.gmk openjdk-17-17.0.6+10/make/common/NativeCompilation.gmk --- openjdk-17-17.0.5+8/make/common/NativeCompilation.gmk 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/common/NativeCompilation.gmk 2023-01-10 13:21:55.000000000 +0000 @@ -267,10 +267,15 @@ # specialized file is found, returns the default file. # $1 Executable to find entitlements file for. ENTITLEMENTS_DIR := $(TOPDIR)/make/data/macosxsigning -DEFAULT_ENTITLEMENTS_FILE := $(ENTITLEMENTS_DIR)/default.plist +ifeq ($(MACOSX_CODESIGN_MODE), debug) + CODESIGN_PLIST_SUFFIX := -debug +else + CODESIGN_PLIST_SUFFIX := +endif +DEFAULT_ENTITLEMENTS_FILE := $(ENTITLEMENTS_DIR)/default$(CODESIGN_PLIST_SUFFIX).plist GetEntitlementsFile = \ - $(foreach f, $(ENTITLEMENTS_DIR)/$(strip $(notdir $1)).plist, \ + $(foreach f, $(ENTITLEMENTS_DIR)/$(strip $(notdir $1))$(CODESIGN_PLIST_SUFFIX).plist, \ $(if $(wildcard $f), $f, $(DEFAULT_ENTITLEMENTS_FILE)) \ ) @@ -1206,11 +1211,16 @@ $$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_NAME).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1 endif endif - # This only works if the openjdk_codesign identity is present on the system. Let - # silently fail otherwise. - ifneq ($(CODESIGN), ) + # On macosx, optionally run codesign on every binary. + # Remove signature explicitly first to avoid warnings if the linker + # added a default adhoc signature. + ifeq ($(MACOSX_CODESIGN_MODE), hardened) + $(CODESIGN) --remove-signature $$@ $(CODESIGN) -f -s "$(MACOSX_CODESIGN_IDENTITY)" --timestamp --options runtime \ --entitlements $$(call GetEntitlementsFile, $$@) $$@ + else ifeq ($(MACOSX_CODESIGN_MODE), debug) + $(CODESIGN) --remove-signature $$@ + $(CODESIGN) -f -s - --entitlements $$(call GetEntitlementsFile, $$@) $$@ endif endif diff -Nru openjdk-17-17.0.5+8/make/conf/jib-profiles.js openjdk-17-17.0.6+10/make/conf/jib-profiles.js --- openjdk-17-17.0.5+8/make/conf/jib-profiles.js 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/conf/jib-profiles.js 2023-01-10 13:21:55.000000000 +0000 @@ -564,7 +564,7 @@ "ANT_HOME": input.get("ant", "home_path") } }; - [ "linux-x64", "macosx-x64", "windows-x64"] + [ "linux-x64", "macosx-aarch64", "macosx-x64", "windows-x64", "linux-aarch64"] .forEach(function (name) { var maketestName = name + "-testmake"; profiles[maketestName] = concatObjects(profiles[name], testmakeBase); diff -Nru openjdk-17-17.0.5+8/make/conf/version-numbers.conf openjdk-17-17.0.6+10/make/conf/version-numbers.conf --- openjdk-17-17.0.5+8/make/conf/version-numbers.conf 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/conf/version-numbers.conf 2023-01-10 13:21:55.000000000 +0000 @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=17 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=5 +DEFAULT_VERSION_UPDATE=6 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2022-10-18 +DEFAULT_VERSION_DATE=2023-01-17 DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 diff -Nru openjdk-17-17.0.5+8/make/data/autoheaders/assemblyprefix.h openjdk-17-17.0.6+10/make/data/autoheaders/assemblyprefix.h --- openjdk-17-17.0.5+8/make/data/autoheaders/assemblyprefix.h 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/autoheaders/assemblyprefix.h 2023-01-10 13:21:55.000000000 +0000 @@ -4,7 +4,9 @@ # # 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. +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. # # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff -Nru openjdk-17-17.0.5+8/make/data/cldr/common/bcp47/timezone.xml openjdk-17-17.0.6+10/make/data/cldr/common/bcp47/timezone.xml --- openjdk-17-17.0.5+8/make/data/cldr/common/bcp47/timezone.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/cldr/common/bcp47/timezone.xml 2023-01-10 13:21:55.000000000 +0000 @@ -279,6 +279,7 @@ + @@ -393,7 +394,7 @@ - + diff -Nru openjdk-17-17.0.5+8/make/data/cldr/common/main/es_419.xml openjdk-17-17.0.6+10/make/data/cldr/common/main/es_419.xml --- openjdk-17-17.0.5+8/make/data/cldr/common/main/es_419.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/cldr/common/main/es_419.xml 2023-01-10 13:21:55.000000000 +0000 @@ -1019,11 +1019,8 @@ - 0 billón 0 billón - 00 billones 00 billones - 000 billones 000 billones diff -Nru openjdk-17-17.0.5+8/make/data/cldr/common/main/es_MX.xml openjdk-17-17.0.6+10/make/data/cldr/common/main/es_MX.xml --- openjdk-17-17.0.5+8/make/data/cldr/common/main/es_MX.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/cldr/common/main/es_MX.xml 2023-01-10 13:21:55.000000000 +0000 @@ -713,11 +713,8 @@ - 0 billón 0 billones - 00 billones 00 billones - 000 billones 000 billones diff -Nru openjdk-17-17.0.5+8/make/data/cldr/common/main/root.xml openjdk-17-17.0.6+10/make/data/cldr/common/main/root.xml --- openjdk-17-17.0.5+8/make/data/cldr/common/main/root.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/cldr/common/main/root.xml 2023-01-10 13:21:55.000000000 +0000 @@ -2932,6 +2932,18 @@ Ho Chi Minh + + Bahía de Banderas + + + Cancún + + + Ciudad Juárez + + + Mérida + diff -Nru openjdk-17-17.0.5+8/make/data/cldr/common/supplemental/metaZones.xml openjdk-17-17.0.6+10/make/data/cldr/common/supplemental/metaZones.xml --- openjdk-17-17.0.5+8/make/data/cldr/common/supplemental/metaZones.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/cldr/common/supplemental/metaZones.xml 2023-01-10 13:21:55.000000000 +0000 @@ -331,7 +331,14 @@ - + + + + + + + + @@ -618,14 +625,14 @@ - + + - - + diff -Nru openjdk-17-17.0.5+8/make/data/currency/CurrencyData.properties openjdk-17-17.0.6+10/make/data/currency/CurrencyData.properties --- openjdk-17-17.0.5+8/make/data/currency/CurrencyData.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/currency/CurrencyData.properties 2023-01-10 13:21:55.000000000 +0000 @@ -32,7 +32,7 @@ # Version of the currency code information in this class. # It is a serial number that accompanies with each amendment. -dataVersion=172 +dataVersion=174 # List of all valid ISO 4217 currency codes. # To ensure compatibility, do not remove codes. @@ -189,7 +189,7 @@ # COTE D'IVOIRE CI=XOF # CROATIA -HR=HRK +HR=HRK;2022-12-31-23-00-00;EUR # CUBA CU=CUP # Cura\u00e7ao diff -Nru openjdk-17-17.0.5+8/make/data/macosxsigning/default-debug.plist openjdk-17-17.0.6+10/make/data/macosxsigning/default-debug.plist --- openjdk-17-17.0.5+8/make/data/macosxsigning/default-debug.plist 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/macosxsigning/default-debug.plist 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,18 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.debugger + + com.apple.security.get-task-allow + + + diff -Nru openjdk-17-17.0.5+8/make/data/macosxsigning/java-debug.plist openjdk-17-17.0.6+10/make/data/macosxsigning/java-debug.plist --- openjdk-17-17.0.5+8/make/data/macosxsigning/java-debug.plist 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/macosxsigning/java-debug.plist 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,20 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.debugger + + com.apple.security.device.audio-input + + com.apple.security.get-task-allow + + + diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/africa openjdk-17-17.0.6+10/make/data/tzdata/africa --- openjdk-17-17.0.5+8/make/data/tzdata/africa 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/africa 2023-01-10 13:21:55.000000000 +0000 @@ -120,22 +120,6 @@ 0:00 Algeria WE%sT 1981 May 1:00 - CET -# Angola -# Benin -# See Africa/Lagos. - -# Botswana -# See Africa/Maputo. - -# Burkina Faso -# See Africa/Abidjan. - -# Burundi -# See Africa/Maputo. - -# Cameroon -# See Africa/Lagos. - # Cape Verde / Cabo Verde # # From Paul Eggert (2018-02-16): @@ -150,9 +134,6 @@ -2:00 - -02 1975 Nov 25 2:00 -1:00 - -01 -# Central African Republic -# See Africa/Lagos. - # Chad # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena @@ -160,33 +141,29 @@ 1:00 1:00 WAST 1980 Mar 8 1:00 - WAT -# Comoros -# See Africa/Nairobi. - -# Democratic Republic of the Congo -# See Africa/Lagos for the western part and Africa/Maputo for the eastern. +# Burkina Faso +# Côte d'Ivoire (Ivory Coast) +# The Gambia +# Ghana +# Guinea +# Iceland +# Mali +# Mauritania +# St Helena +# Senegal +# Sierra Leone +# Togo -# Republic of the Congo -# See Africa/Lagos. +# The other parts of the St Helena territory are similar: +# Tristan da Cunha: on GMT, say Whitman and the CIA +# Ascension: on GMT, say the USNO (1995-12-21) and the CIA +# Gough (scientific station since 1955; sealers wintered previously): +# on GMT, says the CIA +# Inaccessible, Nightingale: uninhabited -# Côte d'Ivoire / Ivory Coast # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Abidjan -0:16:08 - LMT 1912 0:00 - GMT -Link Africa/Abidjan Africa/Accra # Ghana -Link Africa/Abidjan Africa/Bamako # Mali -Link Africa/Abidjan Africa/Banjul # The Gambia -Link Africa/Abidjan Africa/Conakry # Guinea -Link Africa/Abidjan Africa/Dakar # Senegal -Link Africa/Abidjan Africa/Freetown # Sierra Leone -Link Africa/Abidjan Africa/Lome # Togo -Link Africa/Abidjan Africa/Nouakchott # Mauritania -Link Africa/Abidjan Africa/Ouagadougou # Burkina Faso -Link Africa/Abidjan Atlantic/Reykjavik # Iceland -Link Africa/Abidjan Atlantic/St_Helena # St Helena - -# Djibouti -# See Africa/Nairobi. ############################################################################### @@ -382,33 +359,6 @@ Zone Africa/Cairo 2:05:09 - LMT 1900 Oct 2:00 Egypt EE%sT -# Equatorial Guinea -# See Africa/Lagos. - -# Eritrea -# See Africa/Nairobi. - -# Eswatini (formerly Swaziland) -# See Africa/Johannesburg. - -# Ethiopia -# See Africa/Nairobi. -# -# Unfortunately tzdb records only Western clock time in use in Ethiopia, -# as the tzdb format is not up to properly recording a common Ethiopian -# timekeeping practice that is based on solar time. See: -# Mortada D. If you have a meeting in Ethiopia, you'd better double -# check the time. PRI's The World. 2015-01-30 15:15 -05. -# https://www.pri.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time - -# Gabon -# See Africa/Lagos. - -# The Gambia -# Ghana -# Guinea -# See Africa/Abidjan. - # Guinea-Bissau # # From Paul Eggert (2018-02-16): @@ -421,7 +371,16 @@ -1:00 - -01 1975 0:00 - GMT +# Comoros +# Djibouti +# Eritrea +# Ethiopia # Kenya +# Madagascar +# Mayotte +# Somalia +# Tanzania +# Uganda # From P Chan (2020-10-24): # @@ -464,6 +423,14 @@ # The 1908-05-01 announcement does not give an effective date, # so just say "1908 May". +# From Paul Eggert (2018-09-11): +# Unfortunately tzdb records only Western clock time in use in Ethiopia, +# as the tzdb format is not up to properly recording a common Ethiopian +# timekeeping practice that is based on solar time. See: +# Mortada D. If you have a meeting in Ethiopia, you'd better double +# check the time. PRI's The World. 2015-01-30 15:15 -05. +# https://www.pri.org/stories/2015-01-30/if-you-have-meeting-ethiopia-you-better-double-check-time + # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Nairobi 2:27:16 - LMT 1908 May 2:30 - +0230 1928 Jun 30 24:00 @@ -471,18 +438,6 @@ 2:30 - +0230 1936 Dec 31 24:00 2:45 - +0245 1942 Jul 31 24:00 3:00 - EAT -Link Africa/Nairobi Africa/Addis_Ababa # Ethiopia -Link Africa/Nairobi Africa/Asmara # Eritrea -Link Africa/Nairobi Africa/Dar_es_Salaam # Tanzania -Link Africa/Nairobi Africa/Djibouti -Link Africa/Nairobi Africa/Kampala # Uganda -Link Africa/Nairobi Africa/Mogadishu # Somalia -Link Africa/Nairobi Indian/Antananarivo # Madagascar -Link Africa/Nairobi Indian/Comoro -Link Africa/Nairobi Indian/Mayotte - -# Lesotho -# See Africa/Johannesburg. # Liberia # @@ -563,16 +518,6 @@ 1:00 Libya CE%sT 2013 Oct 25 2:00 2:00 - EET -# Madagascar -# See Africa/Nairobi. - -# Malawi -# See Africa/Maputo. - -# Mali -# Mauritania -# See Africa/Abidjan. - # Mauritius # From Steffen Thorsen (2008-06-25): @@ -666,8 +611,6 @@ # Agalega Is, Rodriguez # no information; probably like Indian/Mauritius -# Mayotte -# See Africa/Nairobi. # Morocco # See Africa/Ceuta for Spanish Morocco. @@ -1160,7 +1103,14 @@ 0:00 Morocco +00/+01 2018 Oct 28 3:00 1:00 Morocco +01/+00 +# Botswana +# Burundi +# Democratic Republic of the Congo (eastern) +# Malawi # Mozambique +# Rwanda +# Zambia +# Zimbabwe # # Shanks gives 1903-03-01 for the transition to CAT. # Perhaps the 1911-05-26 Portuguese decree @@ -1170,14 +1120,6 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Maputo 2:10:20 - LMT 1903 Mar 2:00 - CAT -Link Africa/Maputo Africa/Blantyre # Malawi -Link Africa/Maputo Africa/Bujumbura # Burundi -Link Africa/Maputo Africa/Gaborone # Botswana -Link Africa/Maputo Africa/Harare # Zimbabwe -Link Africa/Maputo Africa/Kigali # Rwanda -Link Africa/Maputo Africa/Lubumbashi # E Dem. Rep. of Congo -Link Africa/Maputo Africa/Lusaka # Zambia - # Namibia @@ -1256,9 +1198,16 @@ # 2:00 - CAT # End of rearguard section. -# Niger -# See Africa/Lagos. +# Angola +# Benin +# Cameroon +# Central African Republic +# Democratic Republic of the Congo (western) +# Republic of the Congo +# Equatorial Guinea +# Gabon +# Niger # Nigeria # From P Chan (2020-12-03): @@ -1324,32 +1273,6 @@ 0:13:35 - LMT 1914 Jan 1 0:30 - +0030 1919 Sep 1 1:00 - WAT -Link Africa/Lagos Africa/Bangui # Central African Republic -Link Africa/Lagos Africa/Brazzaville # Rep. of the Congo -Link Africa/Lagos Africa/Douala # Cameroon -Link Africa/Lagos Africa/Kinshasa # Dem. Rep. of the Congo (west) -Link Africa/Lagos Africa/Libreville # Gabon -Link Africa/Lagos Africa/Luanda # Angola -Link Africa/Lagos Africa/Malabo # Equatorial Guinea -Link Africa/Lagos Africa/Niamey # Niger -Link Africa/Lagos Africa/Porto-Novo # Benin - -# Réunion -# See Asia/Dubai. -# -# The Crozet Islands also observe Réunion time; see the 'antarctica' file. - -# Rwanda -# See Africa/Maputo. - -# St Helena -# See Africa/Abidjan. -# The other parts of the St Helena territory are similar: -# Tristan da Cunha: on GMT, say Whitman and the CIA -# Ascension: on GMT, say the USNO (1995-12-21) and the CIA -# Gough (scientific station since 1955; sealers wintered previously): -# on GMT, says the CIA -# Inaccessible, Nightingale: uninhabited # São Tomé and Príncipe @@ -1378,19 +1301,10 @@ 1:00 - WAT 2019 Jan 1 02:00 0:00 - GMT -# Senegal -# See Africa/Abidjan. - -# Seychelles -# See Asia/Dubai. - -# Sierra Leone -# See Africa/Abidjan. - -# Somalia -# See Africa/Nairobi. - +# Eswatini (Swaziland) +# Lesotho # South Africa + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule SA 1942 1943 - Sep Sun>=15 2:00 1:00 - Rule SA 1943 1944 - Mar Sun>=15 2:00 0 - @@ -1398,8 +1312,6 @@ Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 1:30 - SAST 1903 Mar 2:00 SA SAST -Link Africa/Johannesburg Africa/Maseru # Lesotho -Link Africa/Johannesburg Africa/Mbabane # Eswatini # # Marion and Prince Edward Is # scientific station since 1947 @@ -1448,12 +1360,6 @@ 3:00 - EAT 2021 Feb 1 00:00 2:00 - CAT -# Tanzania -# See Africa/Nairobi. - -# Togo -# See Africa/Abidjan. - # Tunisia # From Gwillim Law (2005-04-30): @@ -1551,10 +1457,3 @@ Zone Africa/Tunis 0:40:44 - LMT 1881 May 12 0:09:21 - PMT 1911 Mar 11 # Paris Mean Time 1:00 Tunisia CE%sT - -# Uganda -# See Africa/Nairobi. - -# Zambia -# Zimbabwe -# See Africa/Maputo. diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/antarctica openjdk-17-17.0.6+10/make/data/tzdata/antarctica --- openjdk-17-17.0.5+8/make/data/tzdata/antarctica 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/antarctica 2023-01-10 13:21:55.000000000 +0000 @@ -329,4 +329,4 @@ # we have to go around and set them back 5 minutes or so. # Maybe if we let them run fast all of the time, we'd get to leave here sooner!! # -# See 'australasia' for Antarctica/McMurdo. +# See Pacific/Auckland. diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/asia openjdk-17-17.0.6+10/make/data/tzdata/asia --- openjdk-17-17.0.5+8/make/data/tzdata/asia 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/asia 2023-01-10 13:21:55.000000000 +0000 @@ -172,9 +172,6 @@ 4:00 EUAsia +04/+05 1997 4:00 Azer +04/+05 -# Bahrain -# See Asia/Qatar. - # Bangladesh # From Alexander Krivenyshev (2009-05-13): # According to newspaper Asian Tribune (May 6, 2009) Bangladesh may introduce @@ -277,10 +274,8 @@ 5:00 - +05 1996 6:00 - +06 -# Brunei -# See Asia/Kuching. - -# Burma / Myanmar +# Cocos (Keeling) Islands +# Myanmar (Burma) # Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon. @@ -296,11 +291,6 @@ 6:30 - +0630 1942 May 9:00 - +09 1945 May 3 6:30 - +0630 -Link Asia/Yangon Indian/Cocos - -# Cambodia -# See Asia/Bangkok. - # China @@ -688,10 +678,9 @@ 8:00 PRC C%sT # Xinjiang time, used by many in western China; represented by Ürümqi / Ürümchi # / Wulumuqi. (Please use Asia/Shanghai if you prefer Beijing time.) +# Vostok base in Antarctica matches this since 1970. Zone Asia/Urumqi 5:50:20 - LMT 1928 6:00 - +06 -Link Asia/Urumqi Antarctica/Vostok - # Hong Kong @@ -1195,10 +1184,6 @@ 3:00 - +03 2017 Oct 29 1:00u 2:00 EUAsia EE%sT -# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72. -# However, for various reasons many users expect to find it under Europe. -Link Asia/Nicosia Europe/Nicosia - # Georgia # From Paul Eggert (1994-11-19): # Today's _Economist_ (p 60) reports that Georgia moved its clocks forward @@ -2254,6 +2239,17 @@ # From the Arabic version, it seems to say it would be at midnight # (assume 24:00) on the last Thursday in February, starting from 2022. +# From Issam Al-Zuwairi (2022-10-05): +# The Council of Ministers in Jordan decided Wednesday 5th October 2022, +# that daylight saving time (DST) will be throughout the year.... +# +# From Brian Inglis (2022-10-06): +# https://petra.gov.jo/Include/InnerPage.jsp?ID=45567&lang=en&name=en_news +# +# From Paul Eggert (2022-10-05): +# Like Syria, model this as a transition from EEST +03 (DST) to plain +03 +# (non-DST) at the point where DST would otherwise have ended. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Jordan 1973 only - Jun 6 0:00 1:00 S Rule Jordan 1973 1975 - Oct 1 0:00 0 - @@ -2285,11 +2281,12 @@ Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 - Rule Jordan 2013 only - Dec 20 0:00 0 - Rule Jordan 2014 2021 - Mar lastThu 24:00 1:00 S -Rule Jordan 2014 max - Oct lastFri 0:00s 0 - -Rule Jordan 2022 max - Feb lastThu 24:00 1:00 S +Rule Jordan 2014 2022 - Oct lastFri 0:00s 0 - +Rule Jordan 2022 only - Feb lastThu 24:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Amman 2:23:44 - LMT 1931 - 2:00 Jordan EE%sT + 2:00 Jordan EE%sT 2022 Oct 28 0:00s + 3:00 - +03 # Kazakhstan @@ -2715,14 +2712,6 @@ 8:30 - KST 2018 May 4 23:30 9:00 - KST -############################################################################### - -# Kuwait -# See Asia/Riyadh. - -# Laos -# See Asia/Bangkok. - # Lebanon # Rule NAME FROM TO - IN ON AT SAVE LETTER/S @@ -2754,7 +2743,9 @@ Zone Asia/Beirut 2:22:00 - LMT 1880 2:00 Lebanon EE%sT -# Malaysia +# Brunei +# Malaysia (eastern) +# # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule NBorneo 1935 1941 - Sep 14 0:00 0:20 - Rule NBorneo 1935 1941 - Dec 14 0:00 0 - @@ -2771,14 +2762,12 @@ 8:00 NBorneo +08/+0820 1942 Feb 16 9:00 - +09 1945 Sep 12 8:00 - +08 -Link Asia/Kuching Asia/Brunei # Maldives # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Indian/Maldives 4:54:00 - LMT 1880 # Malé 4:54:00 - MMT 1960 # Malé Mean Time 5:00 - +05 -Link Indian/Maldives Indian/Kerguelen # Mongolia @@ -2941,9 +2930,6 @@ 5:30 - +0530 1986 5:45 - +0545 -# Oman -# See Asia/Dubai. - # Pakistan # From Rives McDow (2002-03-13): @@ -3398,10 +3384,6 @@ # The winter time in 2015 started on October 23 at 01:00. # https://wafa.ps/ar_page.aspx?id=CgpCdYa670694628582aCgpCdY # http://www.palestinecabinet.gov.ps/portal/meeting/details/27583 -# -# From Paul Eggert (2019-04-10): -# For now, guess spring-ahead transitions are at 00:00 on the Saturday -# preceding March's last Sunday (i.e., Sat>=24). # From P Chan (2021-10-18): # http://wafa.ps/Pages/Details/34701 @@ -3418,6 +3400,18 @@ # From Heba Hamad (2022-03-10): # summer time will begin in Palestine from Sunday 03-27-2022, 00:00 AM. +# From Heba Hamad (2022-08-30): +# winter time will begin in Palestine from Saturday 10-29, 02:00 AM by +# 60 minutes backwards. Also the state of Palestine adopted the summer +# and winter time for the years: 2023,2024,2025,2026 ... +# https://mm.icann.org/pipermail/tz/attachments/20220830/9f024566/Time-0001.pdf +# (2022-08-31): ... the Saturday before the last Sunday in March and October +# at 2:00 AM ,for the years from 2023 to 2026. +# (2022-09-05): https://mtit.pna.ps/Site/New/1453 +# +# From Paul Eggert (2022-08-31): +# For now, assume that this rule will also be used after 2026. + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S Rule EgyptAsia 1957 1958 - Oct 1 0:00 0 - @@ -3448,14 +3442,16 @@ Rule Palestine 2014 only - Oct 24 0:00 0 - Rule Palestine 2015 only - Mar 28 0:00 1:00 S Rule Palestine 2015 only - Oct 23 1:00 0 - -Rule Palestine 2016 2018 - Mar Sat>=24 1:00 1:00 S -Rule Palestine 2016 2018 - Oct Sat>=24 1:00 0 - +Rule Palestine 2016 2018 - Mar Sat<=30 1:00 1:00 S +Rule Palestine 2016 2018 - Oct Sat<=30 1:00 0 - Rule Palestine 2019 only - Mar 29 0:00 1:00 S -Rule Palestine 2019 only - Oct Sat>=24 0:00 0 - -Rule Palestine 2020 2021 - Mar Sat>=24 0:00 1:00 S +Rule Palestine 2019 only - Oct Sat<=30 0:00 0 - +Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S Rule Palestine 2020 only - Oct 24 1:00 0 - -Rule Palestine 2021 max - Oct Fri>=23 1:00 0 - -Rule Palestine 2022 max - Mar Sun>=25 0:00 1:00 S +Rule Palestine 2021 only - Oct 29 1:00 0 - +Rule Palestine 2022 only - Mar 27 0:00 1:00 S +Rule Palestine 2022 max - Oct Sat<=30 2:00 0 - +Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -3544,14 +3540,18 @@ 9:00 - JST 1944 Nov 8:00 Phil P%sT +# Bahrain # Qatar # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Qatar 3:26:08 - LMT 1920 # Al Dawhah / Doha 4:00 - +04 1972 Jun 3:00 - +03 -Link Asia/Qatar Asia/Bahrain +# Kuwait # Saudi Arabia +# Yemen +# +# Japan's year-round bases in Antarctica match this since 1970. # # From Paul Eggert (2018-08-29): # Time in Saudi Arabia and other countries in the Arabian peninsula was not @@ -3596,9 +3596,6 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Riyadh 3:06:52 - LMT 1947 Mar 14 3:00 - +03 -Link Asia/Riyadh Antarctica/Syowa -Link Asia/Riyadh Asia/Aden # Yemen -Link Asia/Riyadh Asia/Kuwait # Singapore # taken from Mok Ly Yng (2003-10-30) @@ -3611,9 +3608,8 @@ 7:20 - +0720 1941 Sep 1 7:30 - +0730 1942 Feb 16 9:00 - +09 1945 Sep 12 - 7:30 - +0730 1982 Jan 1 + 7:30 - +0730 1981 Dec 31 16:00u 8:00 - +08 -Link Asia/Singapore Asia/Kuala_Lumpur # Spratly Is # no information @@ -3828,19 +3824,27 @@ # Our brief summary: # https://www.timeanddate.com/news/time/syria-dst-2012.html -# From Arthur David Olson (2012-03-27): -# Assume last Friday in March going forward XXX. +# From Steffen Thorsen (2022-10-05): +# Syria is adopting year-round DST, starting this autumn.... +# From https://www.enabbaladi.net/archives/607812 +# "This [the decision] came after the weekly government meeting today, +# Tuesday 4 October ..." +# +# From Paul Eggert (2022-10-05): +# Like Jordan, model this as a transition from EEST +03 (DST) to plain +03 +# (non-DST) at the point where DST would otherwise have ended. Rule Syria 2008 only - Apr Fri>=1 0:00 1:00 S Rule Syria 2008 only - Nov 1 0:00 0 - Rule Syria 2009 only - Mar lastFri 0:00 1:00 S Rule Syria 2010 2011 - Apr Fri>=1 0:00 1:00 S -Rule Syria 2012 max - Mar lastFri 0:00 1:00 S -Rule Syria 2009 max - Oct lastFri 0:00 0 - +Rule Syria 2012 2022 - Mar lastFri 0:00 1:00 S +Rule Syria 2009 2022 - Oct lastFri 0:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq - 2:00 Syria EE%sT + 2:00 Syria EE%sT 2022 Oct 28 0:00 + 3:00 - +03 # Tajikistan # From Shanks & Pottenger. @@ -3851,14 +3855,15 @@ 5:00 1:00 +06 1991 Sep 9 2:00s 5:00 - +05 +# Cambodia +# Christmas I +# Laos # Thailand +# Vietnam (northern) # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Bangkok 6:42:04 - LMT 1880 6:42:04 - BMT 1920 Apr # Bangkok Mean Time 7:00 - +07 -Link Asia/Bangkok Asia/Phnom_Penh # Cambodia -Link Asia/Bangkok Asia/Vientiane # Laos -Link Asia/Bangkok Indian/Christmas # Turkmenistan # From Shanks & Pottenger. @@ -3869,13 +3874,15 @@ 4:00 RussiaAsia +04/+05 1992 Jan 19 2:00 5:00 - +05 +# Oman +# Réunion +# Seychelles # United Arab Emirates +# +# The Crozet Is also observe Réunion time; see the 'antarctica' file. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Asia/Dubai 3:41:12 - LMT 1920 4:00 - +04 -Link Asia/Dubai Asia/Muscat # Oman -Link Asia/Dubai Indian/Mahe -Link Asia/Dubai Indian/Reunion # Uzbekistan # Byalokoz 1919 says Uzbekistan was 4:27:53. @@ -3895,7 +3902,7 @@ 5:00 RussiaAsia +05/+06 1992 5:00 - +05 -# Vietnam +# Vietnam (southern) # From Paul Eggert (2014-10-04): # Milne gives 7:16:56 for the meridian of Saigon in 1899, as being @@ -3969,7 +3976,3 @@ # For timestamps in north Vietnam back to 1970 (the tzdb cutoff), # use Asia/Bangkok; see the VN entries in the file zone1970.tab. # For timestamps before 1970, see Asia/Hanoi in the file 'backzone'. - - -# Yemen -# See Asia/Riyadh. diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/australasia openjdk-17-17.0.6+10/make/data/tzdata/australasia --- openjdk-17-17.0.5+8/make/data/tzdata/australasia 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/australasia 2023-01-10 13:21:55.000000000 +0000 @@ -274,13 +274,6 @@ 10:00 1:00 AEDT 2011 10:00 AT AE%sT -# Christmas -# See Asia/Bangkok. - -# Cocos (Keeling) Is -# See Asia/Yangon. - - # Fiji # Milne gives 11:55:44 for Suva. @@ -416,8 +409,14 @@ # concerned shifting arrival and departure times, which may look like a simple # thing but requires some significant logistical adjustments domestically and # internationally." -# Assume for now that DST will resume with the recent pre-2020 rules for the -# 2022/2023 season. + +# From Shalvin Narayan (2022-10-27): +# Please note that there will not be any daylight savings time change +# in Fiji for 2022-2023.... +# https://www.facebook.com/FijianGovernment/posts/pfbid0mmWVTYmTibn66ybpFda75pDcf34SSpoSaskJW5gXwaKo5Sgc7273Q4fXWc6kQV6Hl +# +# From Paul Eggert (2022-10-27): +# For now, assume DST is suspended indefinitely. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 - @@ -432,8 +431,6 @@ Rule Fiji 2015 2021 - Jan Sun>=12 3:00 0 - Rule Fiji 2019 only - Nov Sun>=8 2:00 1:00 - Rule Fiji 2020 only - Dec 20 2:00 1:00 - -Rule Fiji 2022 max - Nov Sun>=8 2:00 1:00 - -Rule Fiji 2023 max - Jan Sun>=12 3:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva 12:00 Fiji +12/+13 @@ -449,7 +446,9 @@ # Clipperton (near North America) is administered from French Polynesia; # it is uninhabited. + # Guam +# N Mariana Is # Rule NAME FROM TO - IN ON AT SAVE LETTER/S # http://guamlegislature.com/Public_Laws_5th/PL05-025.pdf @@ -489,17 +488,20 @@ 9:00 - +09 1944 Jul 31 10:00 Guam G%sT 2000 Dec 23 10:00 - ChST # Chamorro Standard Time -Link Pacific/Guam Pacific/Saipan # N Mariana Is -# Kiribati + +# Kiribati (Gilbert Is) +# Marshall Is +# Tuvalu +# Wake +# Wallis & Futuna # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Tarawa 11:32:04 - LMT 1901 # Bairiki 12:00 - +12 -Link Pacific/Tarawa Pacific/Funafuti -Link Pacific/Tarawa Pacific/Majuro -Link Pacific/Tarawa Pacific/Wake -Link Pacific/Tarawa Pacific/Wallis +# Kiribati (except Gilbert Is) +# See Pacific/Tarawa for the Gilbert Is. +# Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Kanton 0 - -00 1937 Aug 31 -12:00 - -12 1979 Oct -11:00 - -11 1994 Dec 31 @@ -509,9 +511,6 @@ -10:00 - -10 1994 Dec 31 14:00 - +14 -# N Mariana Is -# See Pacific/Guam. - # Marshall Is # See Pacific/Tarawa for most locations. # Zone NAME STDOFF RULES FORMAT [UNTIL] @@ -561,6 +560,7 @@ ############################################################################### # New Zealand +# McMurdo Station and Scott Base in Antarctica use Auckland time. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule NZ 1927 only - Nov 6 2:00 1:00 S @@ -596,7 +596,6 @@ Zone Pacific/Auckland 11:39:04 - LMT 1868 Nov 2 11:30 NZ NZ%sT 1946 Jan 1 12:00 NZ NZ%sT -Link Pacific/Auckland Antarctica/McMurdo Zone Pacific/Chatham 12:13:48 - LMT 1868 Nov 2 12:15 - +1215 1946 Jan 1 @@ -695,8 +694,6 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 # Port Moresby Mean Time 10:00 - +10 -Link Pacific/Port_Moresby Antarctica/DumontDUrville -Link Pacific/Port_Moresby Pacific/Chuuk # # From Paul Eggert (2014-10-13): # Base the Bougainville entry on the Arawa-Kieta region, which appears to have @@ -729,10 +726,10 @@ -8:00 - -08 # American Samoa +# Midway Zone Pacific/Pago_Pago 12:37:12 - LMT 1892 Jul 5 -11:22:48 - LMT 1911 -11:00 - SST # S=Samoa -Link Pacific/Pago_Pago Pacific/Midway # in US minor outlying islands # Samoa (formerly and also known as Western Samoa) @@ -824,7 +821,6 @@ # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Pacific/Guadalcanal 10:39:48 - LMT 1912 Oct # Honiara 11:00 - +11 -Link Pacific/Guadalcanal Pacific/Pohnpei # Tokelau # @@ -864,9 +860,6 @@ 13:00 - +13 1999 13:00 Tonga +13/+14 -# Tuvalu -# See Pacific/Tarawa. - # US minor outlying islands @@ -917,15 +910,9 @@ # Kingman # uninhabited -# Midway -# See Pacific/Pago_Pago. - # Palmyra # uninhabited since World War II; was probably like Pacific/Kiritimati -# Wake -# See Pacific/Tarawa. - # Vanuatu @@ -962,9 +949,6 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila 11:00 Vanuatu +11/+12 -# Wallis and Futuna -# See Pacific/Tarawa. - ############################################################################### # NOTES diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/backward openjdk-17-17.0.6+10/make/data/tzdata/backward --- openjdk-17-17.0.5+8/make/data/tzdata/backward 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/backward 2023-01-10 13:21:55.000000000 +0000 @@ -27,7 +27,7 @@ # 2009-05-17 by Arthur David Olson. # This file provides links from old or merged timezone names to current ones. -# Many names changed in late 1993, and many merged names moved here +# Many names changed in 1993 and in 1995, and many merged names moved here # in the period from 2013 through 2022. Several of these names are # also present in the file 'backzone', which has data important only # for pre-1970 timestamps and so is out of scope for tzdb proper. @@ -36,50 +36,24 @@ # building with 'make BACKWARD=', in practice downstream users # typically use this file for backward compatibility. -# Link TARGET LINK-NAME -Link Africa/Nairobi Africa/Asmera -Link Africa/Abidjan Africa/Timbuktu -Link America/Argentina/Catamarca America/Argentina/ComodRivadavia -Link America/Adak America/Atka -Link America/Argentina/Buenos_Aires America/Buenos_Aires -Link America/Argentina/Catamarca America/Catamarca -Link America/Panama America/Coral_Harbour -Link America/Argentina/Cordoba America/Cordoba -Link America/Tijuana America/Ensenada -Link America/Indiana/Indianapolis America/Fort_Wayne -Link America/Nuuk America/Godthab -Link America/Indiana/Indianapolis America/Indianapolis -Link America/Argentina/Jujuy America/Jujuy -Link America/Indiana/Knox America/Knox_IN -Link America/Kentucky/Louisville America/Louisville -Link America/Argentina/Mendoza America/Mendoza -Link America/Toronto America/Montreal -Link America/Rio_Branco America/Porto_Acre -Link America/Argentina/Cordoba America/Rosario -Link America/Tijuana America/Santa_Isabel -Link America/Denver America/Shiprock -Link America/Puerto_Rico America/Virgin -Link Pacific/Auckland Antarctica/South_Pole -Link Asia/Ashgabat Asia/Ashkhabad -Link Asia/Kolkata Asia/Calcutta -Link Asia/Shanghai Asia/Chongqing -Link Asia/Shanghai Asia/Chungking -Link Asia/Dhaka Asia/Dacca -Link Asia/Shanghai Asia/Harbin -Link Asia/Urumqi Asia/Kashgar -Link Asia/Kathmandu Asia/Katmandu -Link Asia/Macau Asia/Macao -Link Asia/Yangon Asia/Rangoon -Link Asia/Ho_Chi_Minh Asia/Saigon -Link Asia/Jerusalem Asia/Tel_Aviv -Link Asia/Thimphu Asia/Thimbu -Link Asia/Makassar Asia/Ujung_Pandang -Link Asia/Ulaanbaatar Asia/Ulan_Bator -Link Atlantic/Faroe Atlantic/Faeroe -Link Europe/Berlin Atlantic/Jan_Mayen -Link Australia/Sydney Australia/ACT -Link Australia/Sydney Australia/Canberra -Link Australia/Hobart Australia/Currie +# This file is divided into sections, one for each major reason for a +# backward compatibility link. Each section is sorted by link name. + +# A "#= TARGET1" comment labels each link inserted only because some +# .zi parsers (including tzcode through 2022e) mishandle links to links. +# The comment says what the target would be if these parsers were fixed +# so that data could contain links to links. For example, the line +# "Link Australia/Sydney Australia/ACT #= Australia/Canberra" would be +# "Link Australia/Canberra Australia/ACT" were it not that data lines +# refrain from linking to links like Australia/Canberra, which means +# the Australia/ACT line links instead to Australia/Sydney, +# Australia/Canberra's target. + + +# Pre-1993 naming conventions + +# Link TARGET LINK-NAME #= TARGET1 +Link Australia/Sydney Australia/ACT #= Australia/Canberra Link Australia/Lord_Howe Australia/LHI Link Australia/Sydney Australia/NSW Link Australia/Darwin Australia/North @@ -89,7 +63,7 @@ Link Australia/Melbourne Australia/Victoria Link Australia/Perth Australia/West Link Australia/Broken_Hill Australia/Yancowinna -Link America/Rio_Branco Brazil/Acre +Link America/Rio_Branco Brazil/Acre #= America/Porto_Acre Link America/Noronha Brazil/DeNoronha Link America/Sao_Paulo Brazil/East Link America/Manaus Brazil/West @@ -109,18 +83,36 @@ Link America/Havana Cuba Link Africa/Cairo Egypt Link Europe/Dublin Eire +# Vanguard section, for most .zi parsers. +#Link GMT Etc/GMT +#Link GMT Etc/GMT+0 +#Link GMT Etc/GMT-0 +#Link GMT Etc/GMT0 +#Link GMT Etc/Greenwich +# Rearguard section, for TZUpdater 2.3.2 and earlier. +Link Etc/GMT Etc/GMT+0 +Link Etc/GMT Etc/GMT-0 +Link Etc/GMT Etc/GMT0 +Link Etc/GMT Etc/Greenwich +# End of rearguard section. Link Etc/UTC Etc/UCT -Link Europe/London Europe/Belfast -Link Europe/Kyiv Europe/Kiev -Link Europe/Chisinau Europe/Tiraspol +Link Etc/UTC Etc/Universal +Link Etc/UTC Etc/Zulu Link Europe/London GB Link Europe/London GB-Eire +# Vanguard section, for most .zi parsers. +#Link GMT GMT+0 +#Link GMT GMT-0 +#Link GMT GMT0 +#Link GMT Greenwich +# Rearguard section, for TZUpdater 2.3.2 and earlier. Link Etc/GMT GMT+0 Link Etc/GMT GMT-0 Link Etc/GMT GMT0 Link Etc/GMT Greenwich +# End of rearguard section. Link Asia/Hong_Kong Hongkong -Link Africa/Abidjan Iceland +Link Africa/Abidjan Iceland #= Atlantic/Reykjavik Link Asia/Tehran Iran Link Asia/Jerusalem Israel Link America/Jamaica Jamaica @@ -132,14 +124,8 @@ Link America/Mexico_City Mexico/General Link Pacific/Auckland NZ Link Pacific/Chatham NZ-CHAT -Link America/Denver Navajo +Link America/Denver Navajo #= America/Shiprock Link Asia/Shanghai PRC -Link Pacific/Kanton Pacific/Enderbury -Link Pacific/Honolulu Pacific/Johnston -Link Pacific/Guadalcanal Pacific/Ponape -Link Pacific/Pago_Pago Pacific/Samoa -Link Pacific/Port_Moresby Pacific/Truk -Link Pacific/Port_Moresby Pacific/Yap Link Europe/Warsaw Poland Link Europe/Lisbon Portugal Link Asia/Taipei ROC @@ -163,3 +149,193 @@ Link Etc/UTC Universal Link Europe/Moscow W-SU Link Etc/UTC Zulu + + +# Two-part names that were renamed mostly to three-part names in 1995 + +# Link TARGET LINK-NAME #= TARGET1 +Link America/Argentina/Buenos_Aires America/Buenos_Aires +Link America/Argentina/Catamarca America/Catamarca +Link America/Argentina/Cordoba America/Cordoba +Link America/Indiana/Indianapolis America/Indianapolis +Link America/Argentina/Jujuy America/Jujuy +Link America/Indiana/Knox America/Knox_IN +Link America/Kentucky/Louisville America/Louisville +Link America/Argentina/Mendoza America/Mendoza +Link America/Puerto_Rico America/Virgin #= America/St_Thomas +Link Pacific/Pago_Pago Pacific/Samoa + + +# Pre-2013 practice, which typically had a Zone per zone.tab line + +# Link TARGET LINK-NAME +Link Africa/Abidjan Africa/Accra +Link Africa/Nairobi Africa/Addis_Ababa +Link Africa/Nairobi Africa/Asmara +Link Africa/Abidjan Africa/Bamako +Link Africa/Lagos Africa/Bangui +Link Africa/Abidjan Africa/Banjul +Link Africa/Maputo Africa/Blantyre +Link Africa/Lagos Africa/Brazzaville +Link Africa/Maputo Africa/Bujumbura +Link Africa/Abidjan Africa/Conakry +Link Africa/Abidjan Africa/Dakar +Link Africa/Nairobi Africa/Dar_es_Salaam +Link Africa/Nairobi Africa/Djibouti +Link Africa/Lagos Africa/Douala +Link Africa/Abidjan Africa/Freetown +Link Africa/Maputo Africa/Gaborone +Link Africa/Maputo Africa/Harare +Link Africa/Nairobi Africa/Kampala +Link Africa/Maputo Africa/Kigali +Link Africa/Lagos Africa/Kinshasa +Link Africa/Lagos Africa/Libreville +Link Africa/Abidjan Africa/Lome +Link Africa/Lagos Africa/Luanda +Link Africa/Maputo Africa/Lubumbashi +Link Africa/Maputo Africa/Lusaka +Link Africa/Lagos Africa/Malabo +Link Africa/Johannesburg Africa/Maseru +Link Africa/Johannesburg Africa/Mbabane +Link Africa/Nairobi Africa/Mogadishu +Link Africa/Lagos Africa/Niamey +Link Africa/Abidjan Africa/Nouakchott +Link Africa/Abidjan Africa/Ouagadougou +Link Africa/Lagos Africa/Porto-Novo +Link America/Puerto_Rico America/Anguilla +Link America/Puerto_Rico America/Antigua +Link America/Puerto_Rico America/Aruba +Link America/Panama America/Atikokan +Link America/Puerto_Rico America/Blanc-Sablon +Link America/Panama America/Cayman +Link America/Phoenix America/Creston +Link America/Puerto_Rico America/Curacao +Link America/Puerto_Rico America/Dominica +Link America/Puerto_Rico America/Grenada +Link America/Puerto_Rico America/Guadeloupe +Link America/Puerto_Rico America/Kralendijk +Link America/Puerto_Rico America/Lower_Princes +Link America/Puerto_Rico America/Marigot +Link America/Puerto_Rico America/Montserrat +Link America/Toronto America/Nassau +Link America/Puerto_Rico America/Port_of_Spain +Link America/Puerto_Rico America/St_Barthelemy +Link America/Puerto_Rico America/St_Kitts +Link America/Puerto_Rico America/St_Lucia +Link America/Puerto_Rico America/St_Thomas +Link America/Puerto_Rico America/St_Vincent +Link America/Puerto_Rico America/Tortola +Link Pacific/Port_Moresby Antarctica/DumontDUrville +Link Pacific/Auckland Antarctica/McMurdo +Link Asia/Riyadh Antarctica/Syowa +Link Asia/Urumqi Antarctica/Vostok +Link Europe/Berlin Arctic/Longyearbyen +Link Asia/Riyadh Asia/Aden +Link Asia/Qatar Asia/Bahrain +Link Asia/Kuching Asia/Brunei +Link Asia/Singapore Asia/Kuala_Lumpur +Link Asia/Riyadh Asia/Kuwait +Link Asia/Dubai Asia/Muscat +Link Asia/Bangkok Asia/Phnom_Penh +Link Asia/Bangkok Asia/Vientiane +Link Africa/Abidjan Atlantic/Reykjavik +Link Africa/Abidjan Atlantic/St_Helena +Link Europe/Brussels Europe/Amsterdam +Link Europe/Prague Europe/Bratislava +Link Europe/Zurich Europe/Busingen +Link Europe/Berlin Europe/Copenhagen +Link Europe/London Europe/Guernsey +Link Europe/London Europe/Isle_of_Man +Link Europe/London Europe/Jersey +Link Europe/Belgrade Europe/Ljubljana +Link Europe/Brussels Europe/Luxembourg +Link Europe/Helsinki Europe/Mariehamn +Link Europe/Paris Europe/Monaco +Link Europe/Berlin Europe/Oslo +Link Europe/Belgrade Europe/Podgorica +Link Europe/Rome Europe/San_Marino +Link Europe/Belgrade Europe/Sarajevo +Link Europe/Belgrade Europe/Skopje +Link Europe/Berlin Europe/Stockholm +Link Europe/Zurich Europe/Vaduz +Link Europe/Rome Europe/Vatican +Link Europe/Belgrade Europe/Zagreb +Link Africa/Nairobi Indian/Antananarivo +Link Asia/Bangkok Indian/Christmas +Link Asia/Yangon Indian/Cocos +Link Africa/Nairobi Indian/Comoro +Link Indian/Maldives Indian/Kerguelen +Link Asia/Dubai Indian/Mahe +Link Africa/Nairobi Indian/Mayotte +Link Asia/Dubai Indian/Reunion +Link Pacific/Port_Moresby Pacific/Chuuk +Link Pacific/Tarawa Pacific/Funafuti +Link Pacific/Tarawa Pacific/Majuro +Link Pacific/Pago_Pago Pacific/Midway +Link Pacific/Guadalcanal Pacific/Pohnpei +Link Pacific/Guam Pacific/Saipan +Link Pacific/Tarawa Pacific/Wake +Link Pacific/Tarawa Pacific/Wallis + + +# Non-zone.tab locations with timestamps since 1970 that duplicate +# those of an existing location + +# Link TARGET LINK-NAME +Link Africa/Abidjan Africa/Timbuktu +Link America/Argentina/Catamarca America/Argentina/ComodRivadavia +Link America/Adak America/Atka +Link America/Panama America/Coral_Harbour +Link America/Tijuana America/Ensenada +Link America/Indiana/Indianapolis America/Fort_Wayne +Link America/Toronto America/Montreal +Link America/Toronto America/Nipigon +Link America/Iqaluit America/Pangnirtung +Link America/Rio_Branco America/Porto_Acre +Link America/Winnipeg America/Rainy_River +Link America/Argentina/Cordoba America/Rosario +Link America/Tijuana America/Santa_Isabel +Link America/Denver America/Shiprock +Link America/Toronto America/Thunder_Bay +Link Pacific/Auckland Antarctica/South_Pole +Link Asia/Shanghai Asia/Chongqing +Link Asia/Shanghai Asia/Harbin +Link Asia/Urumqi Asia/Kashgar +Link Asia/Jerusalem Asia/Tel_Aviv +Link Europe/Berlin Atlantic/Jan_Mayen +Link Australia/Sydney Australia/Canberra +Link Australia/Hobart Australia/Currie +Link Europe/London Europe/Belfast +Link Europe/Chisinau Europe/Tiraspol +Link Europe/Kyiv Europe/Uzhgorod +Link Europe/Kyiv Europe/Zaporozhye +Link Pacific/Kanton Pacific/Enderbury +Link Pacific/Honolulu Pacific/Johnston +Link Pacific/Port_Moresby Pacific/Yap + + +# Alternate names for the same location + +# Link TARGET LINK-NAME #= TARGET1 +Link Africa/Nairobi Africa/Asmera #= Africa/Asmara +Link America/Nuuk America/Godthab +Link Asia/Ashgabat Asia/Ashkhabad +Link Asia/Kolkata Asia/Calcutta +Link Asia/Shanghai Asia/Chungking #= Asia/Chongqing +Link Asia/Dhaka Asia/Dacca +# Istanbul is in both continents. +Link Europe/Istanbul Asia/Istanbul +Link Asia/Kathmandu Asia/Katmandu +Link Asia/Macau Asia/Macao +Link Asia/Yangon Asia/Rangoon +Link Asia/Ho_Chi_Minh Asia/Saigon +Link Asia/Thimphu Asia/Thimbu +Link Asia/Makassar Asia/Ujung_Pandang +Link Asia/Ulaanbaatar Asia/Ulan_Bator +Link Atlantic/Faroe Atlantic/Faeroe +Link Europe/Kyiv Europe/Kiev +# Classically, Cyprus is in Asia; e.g. see Herodotus, Histories, I.72. +# However, for various reasons many users expect to find it under Europe. +Link Asia/Nicosia Europe/Nicosia +Link Pacific/Guadalcanal Pacific/Ponape #= Pacific/Pohnpei +Link Pacific/Port_Moresby Pacific/Truk #= Pacific/Chuuk diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/etcetera openjdk-17-17.0.6+10/make/data/tzdata/etcetera --- openjdk-17-17.0.5+8/make/data/tzdata/etcetera 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/etcetera 2023-01-10 13:21:55.000000000 +0000 @@ -39,26 +39,23 @@ # Do not use a POSIX TZ setting like TZ='GMT+4', which is four hours # behind GMT but uses the completely misleading abbreviation "GMT". -Zone Etc/GMT 0 - GMT - # The following zone is used by tzcode functions like gmtime, # which load the "UTC" file to handle seconds properly. Zone Etc/UTC 0 - UTC +# Functions like gmtime load the "GMT" file to handle leap seconds properly. +# Vanguard section, which works with most .zi parsers. +#Zone GMT 0 - GMT +# Rearguard section, for TZUpdater 2.3.2 and earlier. +Zone Etc/GMT 0 - GMT + # The following link uses older naming conventions, # but it belongs here, not in the file 'backward', # as it is needed for tzcode releases through 2022a, # where functions like gmtime load "GMT" instead of the "Etc/UTC". # We want this to work even on installations that omit 'backward'. Link Etc/GMT GMT - -Link Etc/UTC Etc/Universal -Link Etc/UTC Etc/Zulu - -Link Etc/GMT Etc/Greenwich -Link Etc/GMT Etc/GMT-0 -Link Etc/GMT Etc/GMT+0 -Link Etc/GMT Etc/GMT0 +# End of rearguard section. # Be consistent with POSIX TZ settings in the Zone names, # even though this is the opposite of what many people expect. diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/europe openjdk-17-17.0.6+10/make/data/tzdata/europe --- openjdk-17-17.0.5+8/make/data/tzdata/europe 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/europe 2023-01-10 13:21:55.000000000 +0000 @@ -527,9 +527,6 @@ 1:00 - BST 1971 Oct 31 2:00u 0:00 GB-Eire %s 1996 0:00 EU GMT/BST -Link Europe/London Europe/Jersey -Link Europe/London Europe/Guernsey -Link Europe/London Europe/Isle_of_Man # From Paul Eggert (2018-02-15): # In January 2018 we discovered that the negative SAVE values in the @@ -902,6 +899,8 @@ 3:00 - +03 # Belgium +# Luxembourg +# Netherlands # # From Michael Deckers (2019-08-25): # The exposition in the web page @@ -984,11 +983,6 @@ 1:00 C-Eur CE%sT 1944 Sep 3 1:00 Belgium CE%sT 1977 1:00 EU CE%sT -Link Europe/Brussels Europe/Amsterdam -Link Europe/Brussels Europe/Luxembourg - -# Bosnia and Herzegovina -# See Europe/Belgrade. # Bulgaria # @@ -1015,13 +1009,11 @@ 2:00 E-Eur EE%sT 1997 2:00 EU EE%sT -# Croatia -# See Europe/Belgrade. - # Cyprus # Please see the 'asia' file for Asia/Nicosia. -# Czech Republic / Czechia +# Czech Republic (Czechia) +# Slovakia # # From Paul Eggert (2018-04-15): # The source for Czech data is: Kdy začíná a končí letní čas. 2018-04-15. @@ -1048,15 +1040,14 @@ # End of rearguard section. 1:00 Czech CE%sT 1979 1:00 EU CE%sT -Link Europe/Prague Europe/Bratislava - - -# Denmark, Faroe Islands, and Greenland -# For Denmark see Europe/Berlin. +# Faroe Is +# Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn 0:00 - WET 1981 0:00 EU WE%sT + +# Greenland # # From Paul Eggert (2004-10-31): # During World War II, Germany maintained secret manned weather stations in @@ -1135,7 +1126,30 @@ # "National Park" by Executive Order: # http://naalakkersuisut.gl/~/media/Nanoq/Files/Attached%20Files/Engelske-tekster/Legislation/Executive%20Order%20National%20Park.rtf # It is their only National Park. + +# From Jonas Nyrup (2022-11-24): +# On last Saturday in October 2023 when DST ends America/Nuuk will switch +# from -03/-02 to -02/-01 +# https://sermitsiaq.ag/forslagtidsforskel-danmark-mindskes-sommertid-beholdes +# ... +# https://sermitsiaq.ag/groenland-skifte-tidszone-trods-bekymringer # +# From Jürgen Appel (2022-11-25): +# https://ina.gl/samlinger/oversigt-over-samlinger/samling/dagsordener/dagsorden.aspx?lang=da&day=24-11-2022 +# If I understand this correctly, from the next planned switch to +# summer time, Greenland will permanently stay at that time, i.e. no +# switch back to winter time in 2023 will occur. +# +# From Paul Eggert (2022-11-28): +# The official document in Danish +# https://naalakkersuisut.gl/-/media/naalakkersuisut/filer/kundgoerelser/2022/11/2511/31_da_inatsisartutlov-om-tidens-bestemmelse.pdf?la=da&hash=A33597D8A38CC7038465241119EF34F3 +# says standard time for Greenland is -02, that Naalakkersuisut can lay down +# rules for DST and can require some areas to use a different time zone, +# and that this all takes effect 2023-03-25 22:00. The abovementioned +# "bekymringer" URL says the intent is no transition March 25, that +# Greenland will not go back to winter time in fall 2023, and that +# only America/Nuuk is affected (though further changes may occur). + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D Rule Thule 1991 1992 - Sep lastSun 2:00 0 S @@ -1158,7 +1172,8 @@ -1:00 EU -01/+00 Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb -3:00 - -03 1980 Apr 6 2:00 - -3:00 EU -03/-02 + -3:00 EU -03/-02 2023 Mar 25 22:00 + -2:00 - -02 Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik -4:00 Thule A%sT @@ -1282,11 +1297,8 @@ 2:00 Finland EE%sT 1983 2:00 EU EE%sT -# Åland Is -Link Europe/Helsinki Europe/Mariehamn - - # France +# Monaco # From Ciro Discepolo (2000-12-20): # @@ -1423,9 +1435,11 @@ 0:00 France WE%sT 1945 Sep 16 3:00 1:00 France CE%sT 1977 1:00 EU CE%sT -Link Europe/Paris Europe/Monaco +# Denmark # Germany +# Norway +# Sweden # From Markus Kuhn (1998-09-29): # The German time zone web site by the Physikalisch-Technische @@ -1443,6 +1457,53 @@ # However, Moscow did not observe daylight saving in 1945, so # this was equivalent to UT +03, not +04. +# Svalbard & Jan Mayen + +# From Steffen Thorsen (2001-05-01): +# Although I could not find it explicitly, it seems that Jan Mayen and +# Svalbard have been using the same time as Norway at least since the +# time they were declared as parts of Norway. Svalbard was declared +# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan +# Mayen by law of 1930-02-27 no 2, section 2. (From +# and +# ). The law/regulation +# for normal/standard time in Norway is from 1894-06-29 no 1 (came +# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a +# part of this law since 1925/1930. (From +# ) I have not been +# able to find if Jan Mayen used a different time zone (e.g. -0100) +# before 1930. Jan Mayen has only been "inhabited" since 1921 by +# Norwegian meteorologists and maybe used the same time as Norway ever +# since 1921. Svalbard (Arctic/Longyearbyen) has been inhabited since +# before 1895, and therefore probably changed the local time somewhere +# between 1895 and 1925 (inclusive). + +# From Paul Eggert (2013-09-04): +# +# Actually, Jan Mayen was never occupied by Germany during World War II, +# so it must have diverged from Oslo time during the war, as Oslo was +# keeping Berlin time. +# +# says that the meteorologists +# burned down their station in 1940 and left the island, but returned in +# 1941 with a small Norwegian garrison and continued operations despite +# frequent air attacks from Germans. In 1943 the Americans established a +# radiolocating station on the island, called "Atlantic City". Possibly +# the UT offset changed during the war, but I think it unlikely that +# Jan Mayen used German daylight-saving rules. +# +# Svalbard is more complicated, as it was raided in August 1941 by an +# Allied party that evacuated the civilian population to England (says +# ). The Svalbard FAQ +# says that the Germans were +# expelled on 1942-05-14. However, small parties of Germans did return, +# and according to Wilhelm Dege's book "War North of 80" (1954) +# http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html +# the German armed forces at the Svalbard weather station code-named +# Haudegen did not surrender to the Allies until September 1945. +# +# All these events predate our cutoff date of 1970, so use Europe/Berlin +# for these regions. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Germany 1946 only - Apr 14 2:00s 1:00 S @@ -1467,11 +1528,6 @@ 1:00 SovietZone CE%sT 1946 1:00 Germany CE%sT 1980 1:00 EU CE%sT -Link Europe/Berlin Arctic/Longyearbyen -Link Europe/Berlin Europe/Copenhagen -Link Europe/Berlin Europe/Oslo -Link Europe/Berlin Europe/Stockholm - # Georgia # Please see the "asia" file for Asia/Tbilisi. @@ -1590,10 +1646,9 @@ 1:00 Hungary CE%sT 1984 1:00 EU CE%sT -# Iceland -# See Africa/Abidjan. - # Italy +# San Marino +# Vatican City # # From Paul Eggert (2001-03-06): # Sicily and Sardinia each had their own time zones from 1866 to 1893, @@ -1712,13 +1767,6 @@ 1:00 C-Eur CE%sT 1944 Jun 4 1:00 Italy CE%sT 1980 1:00 EU CE%sT -Link Europe/Rome Europe/Vatican -Link Europe/Rome Europe/San_Marino - - -# Kosovo -# See Europe/Belgrade. - # Latvia @@ -1802,10 +1850,6 @@ 2:00 - EET 2001 Jan 2 2:00 EU EE%sT -# Liechtenstein -# See Europe/Zurich. - - # Lithuania # From Paul Eggert (2016-03-18): @@ -1858,12 +1902,6 @@ 2:00 - EET 2003 Jan 1 2:00 EU EE%sT -# Luxembourg -# See Europe/Brussels. - -# North Macedonia -# See Europe/Belgrade. - # Malta # # From Paul Eggert (2016-10-21): @@ -1959,67 +1997,6 @@ # See Romania commentary for the guessed 1997 transition to EU rules. 2:00 Moldova EE%sT -# Monaco -# See Europe/Paris. - -# Montenegro -# See Europe/Belgrade. - -# Netherlands -# See Europe/Brussels. - -# Norway -# See Europe/Berlin. - -# Svalbard & Jan Mayen - -# From Steffen Thorsen (2001-05-01): -# Although I could not find it explicitly, it seems that Jan Mayen and -# Svalbard have been using the same time as Norway at least since the -# time they were declared as parts of Norway. Svalbard was declared -# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan -# Mayen by law of 1930-02-27 no 2, section 2. (From -# and -# ). The law/regulation -# for normal/standard time in Norway is from 1894-06-29 no 1 (came -# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a -# part of this law since 1925/1930. (From -# ) I have not been -# able to find if Jan Mayen used a different time zone (e.g. -0100) -# before 1930. Jan Mayen has only been "inhabited" since 1921 by -# Norwegian meteorologists and maybe used the same time as Norway ever -# since 1921. Svalbard (Arctic/Longyearbyen) has been inhabited since -# before 1895, and therefore probably changed the local time somewhere -# between 1895 and 1925 (inclusive). - -# From Paul Eggert (2013-09-04): -# -# Actually, Jan Mayen was never occupied by Germany during World War II, -# so it must have diverged from Oslo time during the war, as Oslo was -# keeping Berlin time. -# -# says that the meteorologists -# burned down their station in 1940 and left the island, but returned in -# 1941 with a small Norwegian garrison and continued operations despite -# frequent air attacks from Germans. In 1943 the Americans established a -# radiolocating station on the island, called "Atlantic City". Possibly -# the UT offset changed during the war, but I think it unlikely that -# Jan Mayen used German daylight-saving rules. -# -# Svalbard is more complicated, as it was raided in August 1941 by an -# Allied party that evacuated the civilian population to England (says -# ). The Svalbard FAQ -# says that the Germans were -# expelled on 1942-05-14. However, small parties of Germans did return, -# and according to Wilhelm Dege's book "War North of 80" (1954) -# http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html -# the German armed forces at the Svalbard weather station code-named -# Haudegen did not surrender to the Allies until September 1945. -# -# All these events predate our cutoff date of 1970, so use Europe/Berlin -# for these regions. - - # Poland # The 1919 dates and times can be found in Tygodnik Urzędowy nr 1 (1919-03-20), @@ -2638,10 +2615,14 @@ # From Alexander Krivenyshev (2014-03-17): # time change at 2:00 (2am) on March 30, 2014 # https://vz.ru/news/2014/3/17/677464.html -# From Paul Eggert (2014-03-30): -# Simferopol and Sevastopol reportedly changed their central town clocks -# late the previous day, but this appears to have been ceremonial -# and the discrepancies are small enough to not worry about. +# From Tim Parenti (2022-07-01), per Paul Eggert (2014-03-30): +# The clocks at the railway station in Simferopol were put forward from 22:00 +# to 24:00 the previous day in a "symbolic ceremony"; however, per +# contemporaneous news reports, "ordinary Crimeans [made] the daylight savings +# time switch at 2am" on Sunday. +# https://www.business-standard.com/article/pti-stories/crimea-to-set-clocks-to-russia-time-114033000014_1.html +# https://www.reuters.com/article/us-ukraine-crisis-crimea-time/crimea-switches-to-moscow-time-amid-incorporation-frenzy-idUKBREA2S0LT20140329 +# https://www.bbc.com/news/av/world-europe-26806583 2:00 EU EE%sT 2014 Mar 30 2:00 4:00 - MSK 2014 Oct 26 2:00s 3:00 - MSK @@ -3297,11 +3278,13 @@ 11:00 Russia +11/+12 2011 Mar 27 2:00s 12:00 - +12 - -# San Marino -# See Europe/Rome. - +# Bosnia & Herzegovina +# Croatia +# Kosovo +# Montenegro +# North Macedonia # Serbia +# Slovenia # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Europe/Belgrade 1:22:00 - LMT 1884 1:00 - CET 1941 Apr 18 23:00 @@ -3313,17 +3296,6 @@ # Shanks & Pottenger don't give as much detail, so go with Koželj. 1:00 - CET 1982 Nov 27 1:00 EU CE%sT -Link Europe/Belgrade Europe/Ljubljana # Slovenia -Link Europe/Belgrade Europe/Podgorica # Montenegro -Link Europe/Belgrade Europe/Sarajevo # Bosnia and Herzegovina -Link Europe/Belgrade Europe/Skopje # North Macedonia -Link Europe/Belgrade Europe/Zagreb # Croatia - -# Slovakia -# See Europe/Prague. - -# Slovenia -# See Europe/Belgrade. # Spain # @@ -3413,7 +3385,7 @@ 0:00 Spain WE%sT 1940 Mar 16 23:00 1:00 Spain CE%sT 1979 1:00 EU CE%sT -Zone Africa/Ceuta -0:21:16 - LMT 1900 Dec 31 23:38:44 +Zone Africa/Ceuta -0:21:16 - LMT 1901 Jan 1 0:00u 0:00 - WET 1918 May 6 23:00 0:00 1:00 WEST 1918 Oct 7 23:00 0:00 - WET 1924 @@ -3430,10 +3402,11 @@ # IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u. # Ignore this for now, as the Canaries are part of the EU. -# Sweden -# See Europe/Berlin. +# Germany (Busingen enclave) +# Liechtenstein # Switzerland +# # From Howse: # By the end of the 18th century clocks and watches became commonplace # and their performance improved enormously. Communities began to keep @@ -3546,9 +3519,6 @@ 0:29:46 - BMT 1894 Jun # Bern Mean Time 1:00 Swiss CE%sT 1981 1:00 EU CE%sT -Link Europe/Zurich Europe/Busingen -Link Europe/Zurich Europe/Vaduz - # Turkey @@ -3753,7 +3723,6 @@ 2:00 1:00 EEST 2015 Nov 8 1:00u 2:00 EU EE%sT 2016 Sep 7 3:00 - +03 -Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. # Ukraine # @@ -3774,8 +3743,8 @@ # US colleague David Cochrane) are still trying to get more # information upon these local deviations from Kiev rules. # -# From Paul Eggert (2022-02-08): -# For now, assume that Ukraine's other three zones followed the same rules, +# From Paul Eggert (2022-08-27): +# For now, assume that Ukraine's zones all followed the same rules, # except that Crimea switched to Moscow time in 1994 as described elsewhere. # From Igor Karpov, who works for the Ukrainian Ministry of Justice, @@ -3845,21 +3814,7 @@ # * Ukrainian Government's Resolution of 20.03.1992, No. 139. # http://www.uazakon.com/documents/date_8u/pg_grcasa.htm -# From Paul Eggert (2022-04-12): -# As is usual in tzdb, Ukrainian zones use the most common English spellings. -# In particular, tzdb's name Europe/Kyiv uses the most common spelling in -# English for Ukraine's capital. Although tzdb's former name was Europe/Kiev, -# "Kyiv" is now more common due to widespread reporting of the current conflict. -# Conversely, tzdb continues to use the names Europe/Uzhgorod and -# Europe/Zaporozhye; this is similar to tzdb's use of Europe/Prague, which is -# certainly wrong as a transliteration of the Czech "Praha". -# English-language spelling of Ukrainian names is in flux, and -# some day "Uzhhorod" or "Zaporizhzhia" may become substantially more -# common in English; in the meantime, do not change these -# English spellings as that means less disruption for our users. - # Zone NAME STDOFF RULES FORMAT [UNTIL] -# This represents most of Ukraine. See above for the spelling of "Kyiv". Zone Europe/Kyiv 2:02:04 - LMT 1880 2:02:04 - KMT 1924 May 2 # Kyiv Mean Time 2:00 - EET 1930 Jun 21 @@ -3869,37 +3824,6 @@ 2:00 1:00 EEST 1991 Sep 29 3:00 2:00 C-Eur EE%sT 1996 May 13 2:00 EU EE%sT -# Transcarpathia used CET 1990/1991. -# "Uzhhorod" is the transliteration of the Rusyn/Ukrainian pronunciation, but -# "Uzhgorod" is more common in English. -Zone Europe/Uzhgorod 1:29:12 - LMT 1890 Oct - 1:00 - CET 1940 - 1:00 C-Eur CE%sT 1944 Oct - 1:00 1:00 CEST 1944 Oct 26 - 1:00 - CET 1945 Jun 29 - 3:00 Russia MSK/MSD 1990 - 3:00 - MSK 1990 Jul 1 2:00 - 1:00 - CET 1991 Mar 31 3:00 - 2:00 - EET 1992 Mar 20 - 2:00 C-Eur EE%sT 1996 May 13 - 2:00 EU EE%sT -# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991. -# "Zaporizhzhia" is the transliteration of the Ukrainian name, but -# "Zaporozh'ye" is more common in English. Use the common English -# spelling, except omit the apostrophe as it is not allowed in -# portable Posix file names. -Zone Europe/Zaporozhye 2:20:40 - LMT 1880 - 2:20 - +0220 1924 May 2 - 2:00 - EET 1930 Jun 21 - 3:00 - MSK 1941 Aug 25 - 1:00 C-Eur CE%sT 1943 Oct 25 - 3:00 Russia MSK/MSD 1991 Mar 31 2:00 - 2:00 E-Eur EE%sT 1992 Mar 20 - 2:00 C-Eur EE%sT 1996 May 13 - 2:00 EU EE%sT - -# Vatican City -# See Europe/Rome. ############################################################################### diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/iso3166.tab openjdk-17-17.0.6+10/make/data/tzdata/iso3166.tab --- openjdk-17-17.0.5+8/make/data/tzdata/iso3166.tab 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/iso3166.tab 2023-01-10 13:21:55.000000000 +0000 @@ -26,13 +26,13 @@ # This file is in the public domain, so clarified as of # 2009-05-17 by Arthur David Olson. # -# From Paul Eggert (2015-05-02): +# From Paul Eggert (2022-11-18): # This file contains a table of two-letter country codes. Columns are # separated by a single tab. Lines beginning with '#' are comments. # All text uses UTF-8 encoding. The columns of the table are as follows: # # 1. ISO 3166-1 alpha-2 country code, current as of -# ISO 3166-1 N976 (2018-11-06). See: Updates on ISO 3166-1 +# ISO 3166-1 N1087 (2022-09-02). See: Updates on ISO 3166-1 # https://isotc.iso.org/livelink/livelink/Open/16944257 # 2. The usual English name for the coded region, # chosen so that alphabetic sorting of subsets produces helpful lists. @@ -261,7 +261,7 @@ SZ Eswatini (Swaziland) TC Turks & Caicos Is TD Chad -TF French Southern & Antarctic Lands +TF French Southern Territories TG Togo TH Thailand TJ Tajikistan diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/northamerica openjdk-17-17.0.6+10/make/data/tzdata/northamerica --- openjdk-17-17.0.5+8/make/data/tzdata/northamerica 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/northamerica 2023-01-10 13:21:55.000000000 +0000 @@ -462,7 +462,7 @@ Rule Chicago 1922 1954 - Sep lastSun 2:00 0 S Rule Chicago 1955 1966 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 12:09:24 +Zone America/Chicago -5:50:36 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1920 -6:00 Chicago C%sT 1936 Mar 1 2:00 -5:00 - EST 1936 Nov 15 2:00 @@ -471,7 +471,7 @@ -6:00 Chicago C%sT 1967 -6:00 US C%sT # Oliver County, ND switched from mountain to central time on 1992-10-25. -Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 12:14:48 +Zone America/North_Dakota/Center -6:45:12 - LMT 1883 Nov 18 19:00u -7:00 US M%sT 1992 Oct 25 2:00 -6:00 US C%sT # Morton County, ND, switched from mountain to central time on @@ -481,7 +481,7 @@ # Jones, Mellette, and Todd Counties in South Dakota; # but in practice these other counties were already observing central time. # See . -Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21 +Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 19:00u -7:00 US M%sT 2003 Oct 26 2:00 -6:00 US C%sT @@ -498,7 +498,7 @@ # largest city in Mercer County). Google Maps places Beulah's city hall # at 47° 15' 51" N, 101° 46' 40" W, which yields an offset of 6h47'07". -Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 12:12:53 +Zone America/North_Dakota/Beulah -6:47:07 - LMT 1883 Nov 18 19:00u -7:00 US M%sT 2010 Nov 7 2:00 -6:00 US C%sT @@ -530,7 +530,7 @@ Rule Denver 1965 1966 - Apr lastSun 2:00 1:00 D Rule Denver 1965 1966 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04 +Zone America/Denver -6:59:56 - LMT 1883 Nov 18 19:00u -7:00 US M%sT 1920 -7:00 Denver M%sT 1942 -7:00 US M%sT 1946 @@ -583,7 +583,7 @@ Rule CA 1950 1961 - Sep lastSun 2:00 0 S Rule CA 1962 1966 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 12:07:02 +Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u -8:00 US P%sT 1946 -8:00 CA P%sT 1967 -8:00 US P%sT @@ -845,14 +845,13 @@ # Go with the Arizona State Library instead. # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 11:31:42 +Zone America/Phoenix -7:28:18 - LMT 1883 Nov 18 19:00u -7:00 US M%sT 1944 Jan 1 0:01 -7:00 - MST 1944 Apr 1 0:01 -7:00 US M%sT 1944 Oct 1 0:01 -7:00 - MST 1967 -7:00 US M%sT 1968 Mar 21 -7:00 - MST -Link America/Phoenix America/Creston # From Arthur David Olson (1988-02-13): # A writer from the Inter Tribal Council of Arizona, Inc., @@ -873,7 +872,7 @@ # switched four weeks late in 1974. # # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Boise -7:44:49 - LMT 1883 Nov 18 12:15:11 +Zone America/Boise -7:44:49 - LMT 1883 Nov 18 20:00u -8:00 US P%sT 1923 May 13 2:00 -7:00 US M%sT 1974 -7:00 - MST 1974 Feb 3 2:00 @@ -945,7 +944,7 @@ Rule Indianapolis 1941 1954 - Sep lastSun 2:00 0 S Rule Indianapolis 1946 1954 - Apr lastSun 2:00 1:00 D # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22 +Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1920 -6:00 Indianapolis C%sT 1942 -6:00 US C%sT 1946 @@ -965,7 +964,7 @@ Rule Marengo 1954 1960 - Apr lastSun 2:00 1:00 D Rule Marengo 1954 1960 - Sep lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 12:14:37 +Zone America/Indiana/Marengo -5:45:23 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1951 -6:00 Marengo C%sT 1961 Apr 30 2:00 -5:00 - EST 1969 @@ -989,7 +988,7 @@ Rule Vincennes 1961 only - Sep lastSun 2:00 0 S Rule Vincennes 1962 1963 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 12:09:53 +Zone America/Indiana/Vincennes -5:50:07 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1946 -6:00 Vincennes C%sT 1964 Apr 26 2:00 -5:00 - EST 1969 @@ -1009,7 +1008,7 @@ Rule Perry 1956 1963 - Apr lastSun 2:00 1:00 D Rule Perry 1961 1963 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 12:12:57 +Zone America/Indiana/Tell_City -5:47:03 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1946 -6:00 Perry C%sT 1964 Apr 26 2:00 -5:00 - EST 1967 Oct 29 2:00 @@ -1026,7 +1025,7 @@ Rule Pike 1956 1964 - Apr lastSun 2:00 1:00 D Rule Pike 1961 1964 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 12:10:53 +Zone America/Indiana/Petersburg -5:49:07 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1955 -6:00 Pike C%sT 1965 Apr 25 2:00 -5:00 - EST 1966 Oct 30 2:00 @@ -1048,7 +1047,7 @@ Rule Starke 1957 1958 - Sep lastSun 2:00 0 S Rule Starke 1959 1961 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 12:13:30 +Zone America/Indiana/Knox -5:46:30 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1947 -6:00 Starke C%sT 1962 Apr 29 2:00 -5:00 - EST 1963 Oct 27 2:00 @@ -1064,7 +1063,7 @@ Rule Pulaski 1955 1956 - Oct lastSun 2:00 0 S Rule Pulaski 1957 1960 - Sep lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 12:13:35 +Zone America/Indiana/Winamac -5:46:25 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1946 -6:00 Pulaski C%sT 1961 Apr 30 2:00 -5:00 - EST 1969 @@ -1075,7 +1074,7 @@ # # Switzerland County, Indiana, did not observe DST from 1973 through 2005. # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 12:19:44 +Zone America/Indiana/Vevay -5:40:16 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1954 Apr 25 2:00 -5:00 - EST 1969 -5:00 US E%sT 1973 @@ -1111,7 +1110,7 @@ Rule Louisville 1950 1955 - Sep lastSun 2:00 0 S Rule Louisville 1956 1961 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 12:16:58 +Zone America/Kentucky/Louisville -5:43:02 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1921 -6:00 Louisville C%sT 1942 -6:00 US C%sT 1946 @@ -1145,7 +1144,7 @@ # Federal Register 65, 160 (2000-08-17), pp 50154-50158. # https://www.gpo.gov/fdsys/pkg/FR-2000-08-17/html/00-20854.htm # -Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 12:20:36 +Zone America/Kentucky/Monticello -5:39:24 - LMT 1883 Nov 18 18:00u -6:00 US C%sT 1946 -6:00 - CST 1968 -6:00 US C%sT 2000 Oct 29 2:00 @@ -1626,23 +1625,6 @@ # Ontario -# From Paul Eggert (2006-07-09): -# Shanks & Pottenger write that since 1970 most of Ontario has been like -# Toronto. -# Thunder Bay skipped DST in 1973. -# Many smaller locales did not observe peacetime DST until 1974; -# Nipigon (EST) and Rainy River (CST) are the largest that we know of. -# Far west Ontario is like Winnipeg; far east Quebec is like Halifax. - -# From Jeffery Nichols (2020-02-06): -# According to the [Shanks] atlas, those western Ontario zones are huge, -# covering most of Ontario northwest of Sault Ste Marie and Timmins. -# The zones seem to include towns bigger than the ones they're named after, -# like Dryden in America/Rainy_River and Wawa (and maybe Attawapiskat) in -# America/Nipigon. I assume it's too much trouble to change the name of the -# zone (like when you found out that America/Glace_Bay includes Sydney, Nova -# Scotia).... - # From Mark Brader (2003-07-26): # [According to the Toronto Star] Orillia, Ontario, adopted DST # effective Saturday, 1912-06-22, 22:00; the article mentions that @@ -1663,17 +1645,6 @@ # From Mark Brader (2010-03-06): # -# Currently the database has: -# -# # Ontario -# -# # From Paul Eggert (2006-07-09): -# # Shanks & Pottenger write that since 1970 most of Ontario has been like -# # Toronto. -# # Thunder Bay skipped DST in 1973. -# # Many smaller locales did not observe peacetime DST until 1974; -# # Nipigon (EST) and Rainy River (CST) are the largest that we know of. -# # In the (Toronto) Globe and Mail for Saturday, 1955-09-24, in the bottom # right corner of page 1, it says that Toronto will return to standard # time at 2 am Sunday morning (which agrees with the database), and that: @@ -1681,10 +1652,8 @@ # The one-hour setback will go into effect throughout most of Ontario, # except in areas like Windsor which remains on standard time all year. # -# Windsor is, of course, a lot larger than Nipigon. -# -# I only came across this incidentally. I don't know if Windsor began -# observing DST when Detroit did, or in 1974, or on some other date. +# ... I don't know if Windsor began observing DST when Detroit did, +# or in 1974, or on some other date. # # By the way, the article continues by noting that: # @@ -1766,23 +1735,7 @@ # Toronto Star, which said that DST was ending 1971-10-31 as usual. Rule Toronto 1957 1973 - Oct lastSun 2:00 0 S -# From Paul Eggert (2003-07-27): -# Willett (1914-03) writes (p. 17) "In the Cities of Fort William, and -# Port Arthur, Ontario, the principle of the Bill has been in -# operation for the past three years, and in the City of Moose Jaw, -# Saskatchewan, for one year." - -# From David Bryan via Tory Tronrud, Director/Curator, -# Thunder Bay Museum (2003-11-12): -# There is some suggestion, however, that, by-law or not, daylight -# savings time was being practiced in Fort William and Port Arthur -# before 1909.... [I]n 1910, the line between the Eastern and Central -# Time Zones was permanently moved about two hundred miles west to -# include the Thunder Bay area.... When Canada adopted daylight -# savings time in 1916, Fort William and Port Arthur, having done so -# already, did not change their clocks.... During the Second World -# War,... [t]he cities agreed to implement DST during the summer -# months for the remainder of the war years. +# The Bahamas match Toronto since 1970. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Toronto -5:17:32 - LMT 1895 @@ -1791,22 +1744,6 @@ -5:00 Canada E%sT 1946 -5:00 Toronto E%sT 1974 -5:00 Canada E%sT -Link America/Toronto America/Nassau -Zone America/Thunder_Bay -5:57:00 - LMT 1895 - -6:00 - CST 1910 - -5:00 - EST 1942 - -5:00 Canada E%sT 1970 - -5:00 Toronto E%sT 1973 - -5:00 - EST 1974 - -5:00 Canada E%sT -Zone America/Nipigon -5:53:04 - LMT 1895 - -5:00 Canada E%sT 1940 Sep 29 - -5:00 1:00 EDT 1942 Feb 9 2:00s - -5:00 Canada E%sT -Zone America/Rainy_River -6:18:16 - LMT 1895 - -6:00 Canada C%sT 1940 Sep 29 - -6:00 1:00 CDT 1942 Feb 9 2:00s - -6:00 Canada C%sT # For Atikokan see America/Panama. @@ -2055,6 +1992,37 @@ # Northwest Territories, Nunavut, Yukon +# From Chris Walton (2022-11-06): +# Whitehorse Star - Thursday April 22, 1965 - page 1 +# title: DST Starts Monday ... +# https://www.newspapers.com/image/578587481/ +# The title of this first article is wrong and/or misleading. +# Also, the start time shown in the article is vague; it simply says "after +# midnight" when it probably should have stated 2:00a.m.... +# +# Whitehorse Star - Monday October 25, 1965 - page 15 ... +# https://www.newspapers.com/image/578589147/ +# The 1965 Yukon Council minutes can be found here: +# http://assets.yukonarchives.ca/PER_YG_06_1965_C20_S02_v1.pdf +# ... I do not currently believe that NWT touched any of its clocks in 1965.... +# +# Whitehorse Star - Thursday Feb 24,1966 - page 2 +# title: It's Time for YDT ... +# https://www.newspapers.com/image/578575979/ ... +# America/Whitehorse as a permanent change from UTC-9(YST) to +# UTC-8(PST) at 00:00 on Sunday February 27, 1966.... +# +# Whitehorse Star - Friday April 28,1972 - page 6 +# title: Daylight Saving Time for N.W.T.... +# https://www.newspapers.com/image/578701610/ ... +# Nunavut and NWT zones ... DST starting in 1972.... Start and End ... +# should be the same as the rest of Canada +# +# +# From Paul Eggert (2022-11-06): +# For now, assume Yukon's 1965-04-22 spring forward was 00:00 -> 02:00, as this +# seems likely than 02:00 -> 04:00 and matches "after midnight". + # From Paul Eggert (2006-03-22): # Dawson switched to PST in 1973. Inuvik switched to MST in 1979. # Mathew Englander (1996-10-07) gives the following refs: @@ -2169,6 +2137,13 @@ # * Interpretation Act, RSY 2002, c 125 # https://www.canlii.org/en/yk/laws/stat/rsy-2002-c-125/latest/rsy-2002-c-125.html +# From Chris Walton (2022-11-06): +# The 5th edition of the Atlas of Canada contains a time zone map that +# shows both legislated and observed time zone boundaries. +# All communities on Baffin Island are shown to be observing Eastern time. +# The date on the map is 1984. +# https://ftp.maps.canada.ca/pub/nrcan_rncan/raster/atlas_5_ed/eng/other/referencemaps/mcr4056.pdf + # From Rives McDow (1999-09-04): # Nunavut ... moved ... to incorporate the whole territory into one time zone. # Nunavut moves to single time zone Oct. 31 @@ -2181,40 +2156,7 @@ # From Paul Eggert (1999-09-20): # Basic Facts: The New Territory # http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html -# (1999) reports that Pangnirtung operates on eastern time, -# and that Coral Harbour does not observe DST. We don't know when -# Pangnirtung switched to eastern time; we'll guess 1995. - -# From Rives McDow (1999-11-08): -# On October 31, when the rest of Nunavut went to Central time, -# Pangnirtung wobbled. Here is the result of their wobble: -# -# The following businesses and organizations in Pangnirtung use Central Time: -# -# First Air, Power Corp, Nunavut Construction, Health Center, RCMP, -# Eastern Arctic National Parks, A & D Specialist -# -# The following businesses and organizations in Pangnirtung use Eastern Time: -# -# Hamlet office, All other businesses, Both schools, Airport operator -# -# This has made for an interesting situation there, which warranted the news. -# No one there that I spoke with seems concerned, or has plans to -# change the local methods of keeping time, as it evidently does not -# really interfere with any activities or make things difficult locally. -# They plan to celebrate New Year's turn-over twice, one hour apart, -# so it appears that the situation will last at least that long. -# The Nunavut Intergovernmental Affairs hopes that they will "come to -# their senses", but the locals evidently don't see any problem with -# the current state of affairs. - -# From Michaela Rodrigue, writing in the -# Nunatsiaq News (1999-11-19): -# http://www.nunatsiaqonline.ca/archives/nunavut991130/nvt91119_17.html -# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones, -# central - or Nunavut time - for government offices, and eastern time -# for municipal offices and schools.... Igloolik [was similar but then] -# made the switch to central time on Saturday, Nov. 6. +# (1999) reports that ... Coral Harbour does not observe DST. # From Paul Eggert (2000-10-02): # Matthews and Vincent (1998) say the following, but we lack histories @@ -2373,18 +2315,12 @@ Rule NT_YK 1942 only - Feb 9 2:00 1:00 W # War Rule NT_YK 1945 only - Aug 14 23:00u 1:00 P # Peace Rule NT_YK 1945 only - Sep 30 2:00 0 S -Rule NT_YK 1965 only - Apr lastSun 0:00 2:00 DD -Rule NT_YK 1965 only - Oct lastSun 2:00 0 S -Rule NT_YK 1980 1986 - Apr lastSun 2:00 1:00 D -Rule NT_YK 1980 2006 - Oct lastSun 2:00 0 S +Rule NT_YK 1972 1986 - Apr lastSun 2:00 1:00 D +Rule NT_YK 1972 2006 - Oct lastSun 2:00 0 S Rule NT_YK 1987 2006 - Apr Sun>=1 2:00 1:00 D +Rule Yukon 1965 only - Apr lastSun 0:00 2:00 DD +Rule Yukon 1965 only - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] -# aka Panniqtuuq -Zone America/Pangnirtung 0 - -00 1921 # trading post est. - -4:00 NT_YK A%sT 1995 Apr Sun>=1 2:00 - -5:00 Canada E%sT 1999 Oct 31 2:00 - -6:00 Canada C%sT 2000 Oct 29 2:00 - -5:00 Canada E%sT # formerly Frobisher Bay Zone America/Iqaluit 0 - -00 1942 Aug # Frobisher Bay est. -5:00 NT_YK E%sT 1999 Oct 31 2:00 @@ -2417,13 +2353,15 @@ -7:00 NT_YK M%sT 1980 -7:00 Canada M%sT Zone America/Whitehorse -9:00:12 - LMT 1900 Aug 20 - -9:00 NT_YK Y%sT 1967 May 28 0:00 - -8:00 NT_YK P%sT 1980 + -9:00 NT_YK Y%sT 1965 + -9:00 Yukon Y%sT 1966 Feb 27 0:00 + -8:00 - PST 1980 -8:00 Canada P%sT 2020 Nov 1 -7:00 - MST Zone America/Dawson -9:17:40 - LMT 1900 Aug 20 - -9:00 NT_YK Y%sT 1973 Oct 28 0:00 - -8:00 NT_YK P%sT 1980 + -9:00 NT_YK Y%sT 1965 + -9:00 Yukon Y%sT 1973 Oct 28 0:00 + -8:00 - PST 1980 -8:00 Canada P%sT 2020 Nov 1 -7:00 - MST @@ -2639,7 +2577,23 @@ # 5- The islands, reefs and keys shall take their timezone from the # longitude they are located at. +# From Paul Eggert (2022-10-28): +# The new Mexican law was published today: +# https://www.dof.gob.mx/nota_detalle.php?codigo=5670045&fecha=28/10/2022 +# This abolishes DST except where US DST rules are observed, +# and in addition changes all of Chihuahua to -06 with no DST. + +# From Heitor David Pinto (2022-11-28): +# Now the northern municipalities want to have the same time zone as the +# respective neighboring cities in the US, for example Juárez in UTC-7 with +# DST, matching El Paso, and Ojinaga in UTC-6 with DST, matching Presidio.... +# the president authorized the publication of the decree for November 29, +# so the time change would occur on November 30 at 0:00. +# http://puentelibre.mx/noticia/ciudad_juarez_cambio_horario_noviembre_2022/ + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S +Rule Mexico 1931 only - May 1 23:00 1:00 D +Rule Mexico 1931 only - Oct 1 0:00 0 S Rule Mexico 1939 only - Feb 5 0:00 1:00 D Rule Mexico 1939 only - Jun 25 0:00 0 S Rule Mexico 1940 only - Dec 9 0:00 1:00 D @@ -2652,89 +2606,108 @@ Rule Mexico 1996 2000 - Oct lastSun 2:00 0 S Rule Mexico 2001 only - May Sun>=1 2:00 1:00 D Rule Mexico 2001 only - Sep lastSun 2:00 0 S -Rule Mexico 2002 max - Apr Sun>=1 2:00 1:00 D -Rule Mexico 2002 max - Oct lastSun 2:00 0 S +Rule Mexico 2002 2022 - Apr Sun>=1 2:00 1:00 D +Rule Mexico 2002 2022 - Oct lastSun 2:00 0 S # Zone NAME STDOFF RULES FORMAT [UNTIL] # Quintana Roo; represented by Cancún -Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 0:12:56 +Zone America/Cancun -5:47:04 - LMT 1922 Jan 1 6:00u -6:00 - CST 1981 Dec 23 -5:00 Mexico E%sT 1998 Aug 2 2:00 -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 +Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u -6:00 - CST 1981 Dec 23 -5:00 - EST 1982 Dec 2 -6:00 Mexico C%sT # Coahuila, Nuevo León, Tamaulipas (near US border) # This includes the following municipalities: -# in Coahuila: Ocampo, Acuña, Zaragoza, Jiménez, Piedras Negras, Nava, -# Guerrero, Hidalgo. -# in Nuevo León: Anáhuac, Los Aldama. +# in Coahuila: Acuña, Allende, Guerrero, Hidalgo, Jiménez, Morelos, Nava, +# Ocampo, Piedras Negras, Villa Unión, Zaragoza +# in Nuevo León: Anáhuac # in Tamaulipas: Nuevo Laredo, Guerrero, Mier, Miguel Alemán, Camargo, # Gustavo Díaz Ordaz, Reynosa, Río Bravo, Valle Hermoso, Matamoros. -# See: Inicia mañana Horario de Verano en zona fronteriza, El Universal, -# 2016-03-12 -# http://www.eluniversal.com.mx/articulo/estados/2016/03/12/inicia-manana-horario-de-verano-en-zona-fronteriza -Zone America/Matamoros -6:40:00 - LMT 1921 Dec 31 23:20:00 +# https://www.dof.gob.mx/nota_detalle.php?codigo=5670045&fecha=28/10/2022 +Zone America/Matamoros -6:30:00 - LMT 1922 Jan 1 6:00u -6:00 - CST 1988 -6:00 US C%sT 1989 -6:00 Mexico C%sT 2010 -6:00 US C%sT # Durango; Coahuila, Nuevo León, Tamaulipas (away from US border) -Zone America/Monterrey -6:41:16 - LMT 1921 Dec 31 23:18:44 +Zone America/Monterrey -6:41:16 - LMT 1922 Jan 1 6:00u -6:00 - CST 1988 -6:00 US C%sT 1989 -6:00 Mexico C%sT # Central Mexico -Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 0:23:24 +Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 Mexico C%sT 2001 Sep 30 2:00 -6:00 - CST 2002 Feb 20 -6:00 Mexico C%sT -# Chihuahua (near US border) +# Chihuahua (near US border - western side) # This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe, -# Práxedis G Guerrero, Coyame del Sotol, Ojinaga, and Manuel Benavides. -# (See the 2016-03-12 El Universal source mentioned above.) -Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 0:02:20 +# and Práxedis G Guerrero. +# http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf +Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1996 -6:00 Mexico C%sT 1998 -6:00 - CST 1998 Apr Sun>=1 3:00 -7:00 Mexico M%sT 2010 + -7:00 US M%sT 2022 Oct 30 2:00 + -6:00 - CST 2022 Nov 30 0:00 -7:00 US M%sT +# Chihuahua (near US border - eastern side) +# The municipalities of Coyame del Sotol, Ojinaga, and Manuel Benavides. +# http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf +Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 Mexico M%sT 1932 Apr 1 + -6:00 - CST 1996 + -6:00 Mexico C%sT 1998 + -6:00 - CST 1998 Apr Sun>=1 3:00 + -7:00 Mexico M%sT 2010 + -7:00 US M%sT 2022 Oct 30 2:00 + -6:00 - CST 2022 Nov 30 0:00 + -6:00 US C%sT # Chihuahua (away from US border) -Zone America/Chihuahua -7:04:20 - LMT 1921 Dec 31 23:55:40 +Zone America/Chihuahua -7:04:20 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1996 -6:00 Mexico C%sT 1998 -6:00 - CST 1998 Apr Sun>=1 3:00 - -7:00 Mexico M%sT + -7:00 Mexico M%sT 2022 Oct 30 2:00 + -6:00 - CST # Sonora -Zone America/Hermosillo -7:23:52 - LMT 1921 Dec 31 23:36:08 +Zone America/Hermosillo -7:23:52 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1942 Apr 24 -7:00 - MST 1949 Jan 14 -8:00 - PST 1970 -7:00 Mexico M%sT 1999 -7:00 - MST +# Baja California Sur, Nayarit (except Bahía de Banderas), Sinaloa +Zone America/Mazatlan -7:05:40 - LMT 1922 Jan 1 7:00u + -7:00 - MST 1927 Jun 10 23:00 + -6:00 - CST 1930 Nov 15 + -7:00 Mexico M%sT 1932 Apr 1 + -6:00 - CST 1942 Apr 24 + -7:00 - MST 1949 Jan 14 + -8:00 - PST 1970 + -7:00 Mexico M%sT + +# Bahía de Banderas + # From Alexander Krivenyshev (2010-04-21): # According to news, Bahía de Banderas (Mexican state of Nayarit) # changed time zone UTC-7 to new time zone UTC-6 on April 4, 2010 (to @@ -2762,25 +2735,10 @@ # From Arthur David Olson (2010-05-01): # Use "Bahia_Banderas" to keep the name to fourteen characters. -# Mazatlán -Zone America/Mazatlan -7:05:40 - LMT 1921 Dec 31 23:54:20 - -7:00 - MST 1927 Jun 10 23:00 - -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 - -6:00 - CST 1942 Apr 24 - -7:00 - MST 1949 Jan 14 - -8:00 - PST 1970 - -7:00 Mexico M%sT - -# Bahía de Banderas -Zone America/Bahia_Banderas -7:01:00 - LMT 1921 Dec 31 23:59:00 +Zone America/Bahia_Banderas -7:01:00 - LMT 1922 Jan 1 7:00u -7:00 - MST 1927 Jun 10 23:00 -6:00 - CST 1930 Nov 15 - -7:00 - MST 1931 May 1 23:00 - -6:00 - CST 1931 Oct - -7:00 - MST 1932 Apr 1 + -7:00 Mexico M%sT 1932 Apr 1 -6:00 - CST 1942 Apr 24 -7:00 - MST 1949 Jan 14 -8:00 - PST 1970 @@ -2788,7 +2746,7 @@ -6:00 Mexico C%sT # Baja California -Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 0:11:56 +Zone America/Tijuana -7:48:04 - LMT 1922 Jan 1 7:00u -7:00 - MST 1924 -8:00 - PST 1927 Jun 10 23:00 -7:00 - MST 1930 Nov 15 @@ -2825,20 +2783,16 @@ # http://dof.gob.mx/nota_detalle.php?codigo=5127480&fecha=06/01/2010 # It has been moved to the 'backward' file. # +# From Paul Eggert (2022-10-28): +# Today's new law states that the entire state of Baja California +# follows US DST rules, which agrees with simplifications noted above. +# # # Revillagigedo Is # no information ############################################################################### -# Anguilla -# Antigua and Barbuda -# See America/Puerto_Rico. - -# The Bahamas -# See America/Toronto. - - # Barbados # For 1899 Milne gives -3:58:29.2. @@ -3051,12 +3005,6 @@ -4:00 Canada A%sT 1976 -4:00 US A%sT -# Caribbean Netherlands -# See America/Puerto_Rico. - -# Cayman Is -# See America/Panama. - # Costa Rica # Milne gives -5:36:13.3 as San José mean time. @@ -3282,9 +3230,6 @@ -5:29:36 - HMT 1925 Jul 19 12:00 # Havana MT -5:00 Cuba C%sT -# Dominica -# See America/Puerto_Rico. - # Dominican Republic # From Steffen Thorsen (2000-10-30): @@ -3331,12 +3276,6 @@ Zone America/El_Salvador -5:56:48 - LMT 1921 # San Salvador -6:00 Salv C%sT -# Grenada -# Guadeloupe -# St Barthélemy -# St Martin (French part) -# See America/Puerto_Rico. - # Guatemala # # From Gwillim Law (2006-04-22), after a heads-up from Oscar van Vlijmen: @@ -3522,9 +3461,6 @@ -4:00 1:00 ADT 1980 Sep 28 -4:00 - AST -# Montserrat -# See America/Puerto_Rico. - # Nicaragua # # This uses Shanks & Pottenger for times before 2005. @@ -3590,44 +3526,39 @@ -5:00 - EST 1997 -6:00 Nic C%sT +# Cayman Is # Panama +# +# Atikokan and Coral Harbour, Canada, match Panama since 1970. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Panama -5:18:08 - LMT 1890 -5:19:36 - CMT 1908 Apr 22 # Colón Mean Time -5:00 - EST -Link America/Panama America/Atikokan -Link America/Panama America/Cayman +# Anguilla +# Antigua & Barbuda +# Aruba +# Caribbean Netherlands +# Curaçao +# Dominica +# Grenada +# Guadeloupe +# Montserrat # Puerto Rico +# St Barthélemy +# St Kitts-Nevis +# Sint Maarten / St Martin +# St Lucia +# St Vincent & the Grenadines +# Trinidad & Tobago +# Virgin Is (UK & US) +# # There are too many San Juans elsewhere, so we'll use 'Puerto_Rico'. # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12:00 # San Juan -4:00 - AST 1942 May 3 -4:00 US A%sT 1946 -4:00 - AST -Link America/Puerto_Rico America/Anguilla -Link America/Puerto_Rico America/Antigua -Link America/Puerto_Rico America/Aruba -Link America/Puerto_Rico America/Curacao -Link America/Puerto_Rico America/Blanc-Sablon # Quebec (Lower North Shore) -Link America/Puerto_Rico America/Dominica -Link America/Puerto_Rico America/Grenada -Link America/Puerto_Rico America/Guadeloupe -Link America/Puerto_Rico America/Kralendijk # Caribbean Netherlands -Link America/Puerto_Rico America/Lower_Princes # Sint Maarten -Link America/Puerto_Rico America/Marigot # St Martin (French part) -Link America/Puerto_Rico America/Montserrat -Link America/Puerto_Rico America/Port_of_Spain # Trinidad & Tobago -Link America/Puerto_Rico America/St_Barthelemy # St Barthélemy -Link America/Puerto_Rico America/St_Kitts # St Kitts & Nevis -Link America/Puerto_Rico America/St_Lucia -Link America/Puerto_Rico America/St_Thomas # Virgin Islands (US) -Link America/Puerto_Rico America/St_Vincent -Link America/Puerto_Rico America/Tortola # Virgin Islands (UK) - -# St Kitts-Nevis -# St Lucia -# See America/Puerto_Rico. # St Pierre and Miquelon # There are too many St Pierres elsewhere, so we'll use 'Miquelon'. @@ -3637,12 +3568,6 @@ -3:00 - -03 1987 -3:00 Canada -03/-02 -# St Vincent and the Grenadines -# See America/Puerto_Rico. - -# Sint Maarten -# See America/Puerto_Rico. - # Turks and Caicos # # From Chris Dunn in @@ -3712,11 +3637,6 @@ -4:00 - AST 2018 Mar 11 3:00 -5:00 US E%sT -# British Virgin Is -# US Virgin Is -# See America/Puerto_Rico. - - # Local Variables: # coding: utf-8 # End: diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/southamerica openjdk-17-17.0.6+10/make/data/tzdata/southamerica --- openjdk-17-17.0.5+8/make/data/tzdata/southamerica 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/southamerica 2023-01-10 13:21:55.000000000 +0000 @@ -608,9 +608,6 @@ -3:00 Arg -03/-02 2008 Oct 18 -3:00 - -03 -# Aruba -# See America/Puerto_Rico. - # Bolivia # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone America/La_Paz -4:32:36 - LMT 1890 @@ -1332,8 +1329,14 @@ # for America/Santiago will start on midnight of September 11th; # and will end on April 1st, 2023. Magallanes region (America/Punta_Arenas) # will keep UTC -3 "indefinitely"... This is because on September 4th -# we will have a voting whether to approve a new Constitution.... -# https://www.interior.gob.cl/noticias/2022/08/09/comunicado-el-proximo-sabado-10-de-septiembre-los-relojes-se-deben-adelantar-una-hora/ +# we will have a voting whether to approve a new Constitution. +# +# From Eduardo Romero Urra (2022-08-17): +# https://www.diariooficial.interior.gob.cl/publicaciones/2022/08/13/43327/01/2172567.pdf +# +# From Paul Eggert (2022-08-17): +# Although the presidential decree stops at fall 2026, assume that +# similar DST rules will continue thereafter. # Rule NAME FROM TO - IN ON AT SAVE LETTER/S Rule Chile 1927 1931 - Sep 1 0:00 1:00 - @@ -1438,9 +1441,14 @@ # Milne gives 4:56:16.4 for Bogotá time in 1899. He writes, # "A variation of fifteen minutes in the public clocks of Bogota is not rare." +# From Alois Treindl (2022-11-10): +# End of time change in Colombia 1993 ... should be 6 February 24h ... +# DECRETO 267 DE 1993 +# https://www.suin-juriscol.gov.co/viewDocument.asp?ruta=Decretos/1061335 + # Rule NAME FROM TO - IN ON AT SAVE LETTER/S -Rule CO 1992 only - May 3 0:00 1:00 - -Rule CO 1993 only - Apr 4 0:00 0 - +Rule CO 1992 only - May 3 0:00 1:00 - +Rule CO 1993 only - Feb 6 24:00 0 - # Zone NAME STDOFF RULES FORMAT [UNTIL] #STDOFF -4:56:16.4 Zone America/Bogota -4:56:16 - LMT 1884 Mar 13 @@ -1449,15 +1457,6 @@ # Malpelo, Providencia, San Andres # no information; probably like America/Bogota -# Curaçao -# See America/Puerto_Rico. -# -# From Arthur David Olson (2011-06-15): -# use links for places with new iso3166 codes. -# The name "Lower Prince's Quarter" is both longer than fourteen characters -# and contains an apostrophe; use "Lower_Princes".... -# From Paul Eggert (2021-09-29): -# These backward-compatibility links now are in the 'northamerica' file. # Ecuador # @@ -1773,9 +1772,6 @@ -3:30 - -0330 1984 Oct -3:00 - -03 -# Trinidad and Tobago -# See America/Puerto_Rico. - # Uruguay # From Paul Eggert (1993-11-18): # Uruguay wins the prize for the strangest peacetime manipulation of the rules. diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/VERSION openjdk-17-17.0.6+10/make/data/tzdata/VERSION --- openjdk-17-17.0.5+8/make/data/tzdata/VERSION 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/VERSION 2023-01-10 13:21:55.000000000 +0000 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2022c +tzdata2022g diff -Nru openjdk-17-17.0.5+8/make/data/tzdata/zone.tab openjdk-17-17.0.6+10/make/data/tzdata/zone.tab --- openjdk-17-17.0.5+8/make/data/tzdata/zone.tab 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/data/tzdata/zone.tab 2023-01-10 13:21:55.000000000 +0000 @@ -137,13 +137,9 @@ CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) CA +4339-07923 America/Toronto Eastern - ON, QC (most areas) -CA +4901-08816 America/Nipigon Eastern - ON, QC (no DST 1967-73) -CA +4823-08915 America/Thunder_Bay Eastern - ON (Thunder Bay) -CA +6344-06828 America/Iqaluit Eastern - NU (most east areas) -CA +6608-06544 America/Pangnirtung Eastern - NU (Pangnirtung) +CA +6344-06828 America/Iqaluit Eastern - NU (most areas) CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H) CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba -CA +4843-09434 America/Rainy_River Central - ON (Rainy R, Ft Frances) CA +744144-0944945 America/Resolute Central - NU (Resolute) CA +624900-0920459 America/Rankin_Inlet Central - NU (central) CA +5024-10439 America/Regina CST - SK (most areas) @@ -303,17 +299,18 @@ MU -2010+05730 Indian/Mauritius MV +0410+07330 Indian/Maldives MW -1547+03500 Africa/Blantyre -MX +1924-09909 America/Mexico_City Central Time -MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo -MX +2058-08937 America/Merida Central Time - Campeche, Yucatan -MX +2540-10019 America/Monterrey Central Time - Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas) -MX +2550-09730 America/Matamoros Central Time US - Coahuila, Nuevo Leon, Tamaulipas (US border) -MX +2313-10625 America/Mazatlan Mountain Time - Baja California Sur, Nayarit, Sinaloa -MX +2838-10605 America/Chihuahua Mountain Time - Chihuahua (most areas) -MX +2934-10425 America/Ojinaga Mountain Time US - Chihuahua (US border) -MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora -MX +3232-11701 America/Tijuana Pacific Time US - Baja California -MX +2048-10515 America/Bahia_Banderas Central Time - Bahia de Banderas +MX +1924-09909 America/Mexico_City Central Mexico +MX +2105-08646 America/Cancun Quintana Roo +MX +2058-08937 America/Merida Campeche, Yucatan +MX +2540-10019 America/Monterrey Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas) +MX +2550-09730 America/Matamoros Coahuila, Nuevo Leon, Tamaulipas (US border) +MX +2838-10605 America/Chihuahua Chihuahua (most areas) +MX +3144-10629 America/Ciudad_Juarez Chihuahua (US border - west) +MX +2934-10425 America/Ojinaga Chihuahua (US border - east) +MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinaloa +MX +2048-10515 America/Bahia_Banderas Bahia de Banderas +MX +2904-11058 America/Hermosillo Sonora +MX +3232-11701 America/Tijuana Baja California MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula) MY +0133+11020 Asia/Kuching Sabah, Sarawak MZ -2558+03235 Africa/Maputo @@ -424,8 +421,6 @@ TW +2503+12130 Asia/Taipei TZ -0648+03917 Africa/Dar_es_Salaam UA +5026+03031 Europe/Kyiv Ukraine (most areas) -UA +4837+02218 Europe/Uzhgorod Transcarpathia -UA +4750+03510 Europe/Zaporozhye Zaporozhye and east Lugansk UG +0019+03225 Africa/Kampala UM +2813-17722 Pacific/Midway Midway Islands UM +1917+16637 Pacific/Wake Wake Island diff -Nru openjdk-17-17.0.5+8/make/devkit/createJMHBundle.sh openjdk-17-17.0.6+10/make/devkit/createJMHBundle.sh --- openjdk-17-17.0.5+8/make/devkit/createJMHBundle.sh 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/devkit/createJMHBundle.sh 2023-01-10 13:21:55.000000000 +0000 @@ -26,7 +26,7 @@ # Create a bundle in the build directory, containing what's needed to # build and run JMH microbenchmarks from the OpenJDK build. -JMH_VERSION=1.34 +JMH_VERSION=1.35 COMMONS_MATH3_VERSION=3.2 JOPT_SIMPLE_VERSION=4.6 diff -Nru openjdk-17-17.0.5+8/make/modules/java.desktop/lib/Awt2dLibraries.gmk openjdk-17-17.0.6+10/make/modules/java.desktop/lib/Awt2dLibraries.gmk --- openjdk-17-17.0.5+8/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2023-01-10 13:21:55.000000000 +0000 @@ -26,6 +26,7 @@ WIN_AWT_LIB := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt/awt.lib LIBAWT_DEFAULT_HEADER_DIRS := \ + common/awt/utility \ libawt/awt/image \ libawt/awt/image/cvutils \ libawt/java2d \ @@ -368,7 +369,6 @@ common/awt/debug \ common/font \ common/java2d/opengl \ - include \ # LIBAWT_HEADLESS_CFLAGS := $(CUPS_CFLAGS) $(FONTCONFIG_CFLAGS) $(X_CFLAGS) \ @@ -474,11 +474,11 @@ LIBFONTMANAGER_EXTRA_HEADER_DIRS := \ libharfbuzz \ common/awt \ + common/awt/utility \ common/font \ libawt/java2d \ libawt/java2d/pipe \ libawt/java2d/loops \ - include \ # LIBFONTMANAGER_CFLAGS += $(LIBFREETYPE_CFLAGS) @@ -563,6 +563,7 @@ LIBJAWT_EXTRA_HEADER_DIRS := \ include \ common/awt/debug \ + common/awt/utility \ libawt/awt/image/cvutils \ libawt/java2d \ libawt/java2d/windows \ @@ -658,7 +659,7 @@ common/awt/systemscale \ # - LIBSPLASHSCREEN_HEADER_DIRS += include + LIBSPLASHSCREEN_HEADER_DIRS += common/awt/utility ifeq ($(USE_EXTERNAL_LIBGIF), false) LIBSPLASHSCREEN_HEADER_DIRS += libsplashscreen/giflib diff -Nru openjdk-17-17.0.5+8/make/modules/java.security.jgss/Lib.gmk openjdk-17-17.0.6+10/make/modules/java.security.jgss/Lib.gmk --- openjdk-17-17.0.5+8/make/modules/java.security.jgss/Lib.gmk 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/modules/java.security.jgss/Lib.gmk 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2022, 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 @@ -40,6 +40,19 @@ TARGETS += $(BUILD_LIBJ2GSS) +ifeq ($(call isTargetOs, windows), true) + $(eval $(call SetupJdkLibrary, BUILD_LIBSSPI_BRIDGE, \ + NAME := sspi_bridge, \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -I$(TOPDIR)/src/java.security.jgss/share/native/libj2gss, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + )) + + TARGETS += $(BUILD_LIBSSPI_BRIDGE) +endif + ################################################################################ ifneq ($(BUILD_CRYPTO), false) @@ -57,17 +70,6 @@ )) TARGETS += $(BUILD_LIBW2K_LSA_AUTH) - - $(eval $(call SetupJdkLibrary, BUILD_LIBSSPI_BRIDGE, \ - NAME := sspi_bridge, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -I$(TOPDIR)/src/java.security.jgss/share/native/libj2gss, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - )) - - TARGETS += $(BUILD_LIBSSPI_BRIDGE) endif ifeq ($(call isTargetOs, macosx), true) diff -Nru openjdk-17-17.0.5+8/make/scripts/compare.sh openjdk-17-17.0.6+10/make/scripts/compare.sh --- openjdk-17-17.0.5+8/make/scripts/compare.sh 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/make/scripts/compare.sh 2023-01-10 13:21:55.000000000 +0000 @@ -42,6 +42,7 @@ LDD_CMD="$OTOOL -L" DIS_CMD="$OTOOL -v -V -t" STAT_PRINT_SIZE="-f %z" + STRIP="$STRIP -no_code_signature_warning" elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then FULLDUMP_CMD="$DUMPBIN -all" LDD_CMD="$DUMPBIN -dependents" @@ -674,14 +675,22 @@ ORIG_THIS_FILE="$THIS_FILE" ORIG_OTHER_FILE="$OTHER_FILE" - if [ "$STRIP_ALL" = "true" ] || [[ "$STRIP_BEFORE_COMPARE" = *"$BIN_FILE"* ]]; then + if [ "$STRIP_ALL" = "true" ] || [[ "$STRIP_BEFORE_COMPARE" = *"$BIN_FILE"* ]] \ + || [ "$OPENJDK_TARGET_OS" = "macosx" ]; then THIS_STRIPPED_FILE=$FILE_WORK_DIR/this/$NAME OTHER_STRIPPED_FILE=$FILE_WORK_DIR/other/$NAME $MKDIR -p $FILE_WORK_DIR/this $FILE_WORK_DIR/other $CP $THIS_FILE $THIS_STRIPPED_FILE $CP $OTHER_FILE $OTHER_STRIPPED_FILE - $STRIP $THIS_STRIPPED_FILE - $STRIP $OTHER_STRIPPED_FILE + if [ "$STRIP_ALL" = "true" ] || [[ "$STRIP_BEFORE_COMPARE" = *"$BIN_FILE"* ]]; then + $STRIP $THIS_STRIPPED_FILE + $STRIP $OTHER_STRIPPED_FILE + fi + # On macosx, always remove any signature before comparing + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then + $CODESIGN --remove-signature $THIS_STRIPPED_FILE + $CODESIGN --remove-signature $OTHER_STRIPPED_FILE + fi THIS_FILE="$THIS_STRIPPED_FILE" OTHER_FILE="$OTHER_STRIPPED_FILE" fi diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64.ad openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64.ad --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64.ad 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64.ad 2023-01-10 13:21:55.000000000 +0000 @@ -1279,12 +1279,12 @@ static int emit_deopt_handler(CodeBuffer& cbuf); static uint size_exception_handler() { - return MacroAssembler::far_branch_size(); + return MacroAssembler::far_codestub_branch_size(); } static uint size_deopt_handler() { // count one adr and one far branch instruction - return 4 * NativeInstruction::instruction_size; + return NativeInstruction::instruction_size + MacroAssembler::far_codestub_branch_size(); } }; @@ -2358,7 +2358,7 @@ __ adr(lr, __ pc()); __ far_jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); - assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); + assert(__ offset() - offset == (int) size_deopt_handler(), "overflow"); __ end_a_stub(); return offset; } @@ -3105,16 +3105,30 @@ rscratch1, stlrb); %} + enc_class aarch64_enc_stlrb0(memory mem) %{ + MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, + rscratch1, stlrb); + %} + enc_class aarch64_enc_stlrh(iRegI src, memory mem) %{ MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, rscratch1, stlrh); %} + enc_class aarch64_enc_stlrh0(memory mem) %{ + MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, + rscratch1, stlrh); + %} + enc_class aarch64_enc_stlrw(iRegI src, memory mem) %{ MOV_VOLATILE(as_Register($src$$reg), $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, rscratch1, stlrw); %} + enc_class aarch64_enc_stlrw0(memory mem) %{ + MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, + rscratch1, stlrw); + %} enc_class aarch64_enc_ldarsbw(iRegI dst, memory mem) %{ Register dst_reg = as_Register($dst$$reg); @@ -3205,6 +3219,11 @@ rscratch1, stlr); %} + enc_class aarch64_enc_stlr0(memory mem) %{ + MOV_VOLATILE(zr, $mem$$base, $mem$$index, $mem$$scale, $mem$$disp, + rscratch1, stlr); + %} + enc_class aarch64_enc_fstlrs(vRegF src, memory mem) %{ { C2_MacroAssembler _masm(&cbuf); @@ -3913,19 +3932,15 @@ __ bind(object_has_monitor); STATIC_ASSERT(markWord::monitor_value <= INT_MAX); __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor - __ ldr(rscratch1, Address(tmp, ObjectMonitor::owner_offset_in_bytes())); __ ldr(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); Label notRecursive; - __ cmp(rscratch1, rthread); - __ br(Assembler::NE, cont); - __ cbz(disp_hdr, notRecursive); // Recursive lock __ sub(disp_hdr, disp_hdr, 1u); __ str(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes())); - // flag == EQ was set in the ownership check above + __ cmp(disp_hdr, disp_hdr); // Sets flags for result __ b(cont); __ bind(notRecursive); @@ -4295,6 +4310,16 @@ interface(CONST_INTER); %} +operand immI_positive() +%{ + predicate(n->get_int() > 0); + match(ConI); + + op_cost(0); + format %{ %} + interface(CONST_INTER); +%} + operand immL_255() %{ predicate(n->get_long() == 255L); @@ -8109,6 +8134,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmB0_volatile(immI0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem (StoreB mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlrb zr, $mem\t# byte" %} + + ins_encode(aarch64_enc_stlrb0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Char/Short instruct storeC_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) %{ @@ -8122,6 +8159,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmC0_volatile(immI0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem (StoreC mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlrh zr, $mem\t# short" %} + + ins_encode(aarch64_enc_stlrh0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Integer instruct storeI_volatile(iRegIorL2I src, /* sync_memory*/indirect mem) @@ -8136,6 +8185,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmI0_volatile(immI0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem(StoreI mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlrw zr, $mem\t# int" %} + + ins_encode(aarch64_enc_stlrw0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Long (64 bit signed) instruct storeL_volatile(iRegL src, /* sync_memory*/indirect mem) %{ @@ -8149,6 +8210,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmL0_volatile(immL0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem (StoreL mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlr zr, $mem\t# int" %} + + ins_encode(aarch64_enc_stlr0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Pointer instruct storeP_volatile(iRegP src, /* sync_memory*/indirect mem) %{ @@ -8162,6 +8235,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmP0_volatile(immP0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem (StoreP mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlr zr, $mem\t# ptr" %} + + ins_encode(aarch64_enc_stlr0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Compressed Pointer instruct storeN_volatile(iRegN src, /* sync_memory*/indirect mem) %{ @@ -8175,6 +8260,18 @@ ins_pipe(pipe_class_memory); %} +instruct storeimmN0_volatile(immN0 zero, /* sync_memory*/indirect mem) +%{ + match(Set mem (StoreN mem zero)); + + ins_cost(VOLATILE_REF_COST); + format %{ "stlrw zr, $mem\t# compressed ptr" %} + + ins_encode(aarch64_enc_stlrw0(mem)); + + ins_pipe(pipe_class_memory); +%} + // Store Float instruct storeF_volatile(vRegF src, /* sync_memory*/indirect mem) %{ @@ -11320,6 +11417,108 @@ // This pattern is automatically generated from aarch64_ad.m4 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegI_reg_URShift_reg(iRegINoSp dst, + immI0 zero, iRegIorL2I src1, immI src2) %{ + match(Set dst (SubI zero (URShiftI src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "negw $dst, $src1, LSR $src2" %} + + ins_encode %{ + __ negw(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::LSR, $src2$$constant & 0x1f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegI_reg_RShift_reg(iRegINoSp dst, + immI0 zero, iRegIorL2I src1, immI src2) %{ + match(Set dst (SubI zero (RShiftI src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "negw $dst, $src1, ASR $src2" %} + + ins_encode %{ + __ negw(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::ASR, $src2$$constant & 0x1f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegI_reg_LShift_reg(iRegINoSp dst, + immI0 zero, iRegIorL2I src1, immI src2) %{ + match(Set dst (SubI zero (LShiftI src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "negw $dst, $src1, LSL $src2" %} + + ins_encode %{ + __ negw(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::LSL, $src2$$constant & 0x1f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegL_reg_URShift_reg(iRegLNoSp dst, + immL0 zero, iRegL src1, immI src2) %{ + match(Set dst (SubL zero (URShiftL src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "neg $dst, $src1, LSR $src2" %} + + ins_encode %{ + __ neg(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::LSR, $src2$$constant & 0x3f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegL_reg_RShift_reg(iRegLNoSp dst, + immL0 zero, iRegL src1, immI src2) %{ + match(Set dst (SubL zero (RShiftL src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "neg $dst, $src1, ASR $src2" %} + + ins_encode %{ + __ neg(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::ASR, $src2$$constant & 0x3f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct NegL_reg_LShift_reg(iRegLNoSp dst, + immL0 zero, iRegL src1, immI src2) %{ + match(Set dst (SubL zero (LShiftL src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "neg $dst, $src1, LSL $src2" %} + + ins_encode %{ + __ neg(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::LSL, $src2$$constant & 0x3f); + %} + + ins_pipe(ialu_reg_shift); +%} + +// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE instruct AndI_reg_not_reg(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2, immI_M1 m1) %{ match(Set dst (AndI src1 (XorI src2 m1))); @@ -14997,18 +15196,22 @@ ins_pipe(pipe_class_memory); %} -instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr) +instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, iRegL_R11 temp, Universe dummy, rFlagsReg cr) %{ predicate((uint64_t)n->in(2)->get_long() < (uint64_t)(BlockZeroingLowLimit >> LogBytesPerWord)); match(Set dummy (ClearArray cnt base)); - effect(USE_KILL base); + effect(TEMP temp, USE_KILL base, KILL cr); ins_cost(4 * INSN_COST); format %{ "ClearArray $cnt, $base" %} ins_encode %{ - __ zero_words($base$$Register, (uint64_t)$cnt$$constant); + address tpc = __ zero_words($base$$Register, (uint64_t)$cnt$$constant); + if (tpc == NULL) { + ciEnv::current()->record_failure("CodeCache is full"); + return; + } %} ins_pipe(pipe_class_memory); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_ad.m4 openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_ad.m4 --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_ad.m4 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_ad.m4 2023-01-10 13:21:55.000000000 +0000 @@ -52,6 +52,24 @@ ins_pipe(ialu_reg_reg_shift); %} ')dnl +define(`NEG_SHIFT_INSN', +`// This pattern is automatically generated from aarch64_ad.m4 +// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE +instruct Neg$1_reg_$2_reg(iReg$1NoSp dst, + imm$1`0' zero, iReg$1`'ORL2I($1) src1, immI src2) %{ + match(Set dst (Sub$1 zero ($2$1 src1 src2))); + + ins_cost(1.9 * INSN_COST); + format %{ "ifelse($1, I, negw, neg) $dst, $src1, $3 $src2" %} + + ins_encode %{ + __ ifelse($1, I, negw, neg)(as_Register($dst$$reg), as_Register($src1$$reg), + Assembler::$3, $src2$$constant & ifelse($1,I,0x1f,0x3f)); + %} + + ins_pipe(ialu_reg_shift); +%} +')dnl define(`BASE_INVERTED_INSN', `// This pattern is automatically generated from aarch64_ad.m4 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE @@ -126,6 +144,11 @@ `BASE_SHIFT_INSN(I, $1, ifelse($2,andr,andw,$2w), $3, $4) BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl dnl +define(`BOTH_NEG_SHIFT_INSNS', +`NEG_SHIFT_INSN($1, URShift, LSR) +NEG_SHIFT_INSN($1, RShift, ASR) +NEG_SHIFT_INSN($1, LShift, LSL)')dnl +dnl define(`BOTH_INVERTED_INSNS', `BASE_INVERTED_INSN(I, $1, $2w, $3, $4) BASE_INVERTED_INSN(L, $1, $2, $3, $4)')dnl @@ -151,6 +174,8 @@ dnl NOT_INSN(L, eon) NOT_INSN(I, eonw) +BOTH_NEG_SHIFT_INSNS(I) +BOTH_NEG_SHIFT_INSNS(L) BOTH_INVERTED_INSNS(And, bic) BOTH_INVERTED_INSNS(Or, orn) BOTH_INVERTED_INSNS(Xor, eon) diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_neon.ad openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_neon.ad --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_neon.ad 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_neon.ad 2023-01-10 13:21:55.000000000 +0000 @@ -3103,16 +3103,14 @@ ins_pipe(vdup_reg_reg128); %} -instruct replicate2L_zero(vecX dst, immI0 zero) +instruct replicate2L_imm(vecX dst, immL con) %{ predicate(UseSVE == 0 && n->as_Vector()->length() == 2); - match(Set dst (ReplicateI zero)); + match(Set dst (ReplicateL con)); ins_cost(INSN_COST); - format %{ "movi $dst, $zero\t# vector (4I)" %} + format %{ "movi $dst, $con\t# vector (2L)" %} ins_encode %{ - __ eor(as_FloatRegister($dst$$reg), __ T16B, - as_FloatRegister($dst$$reg), - as_FloatRegister($dst$$reg)); + __ mov(as_FloatRegister($dst$$reg), __ T2D, $con$$constant); %} ins_pipe(vmovi_reg_imm128); %} @@ -3124,8 +3122,7 @@ ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2F)" %} ins_encode %{ - __ dup(as_FloatRegister($dst$$reg), __ T2S, - as_FloatRegister($src$$reg)); + __ dup(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_freg64); %} @@ -3137,8 +3134,7 @@ ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (4F)" %} ins_encode %{ - __ dup(as_FloatRegister($dst$$reg), __ T4S, - as_FloatRegister($src$$reg)); + __ dup(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_freg128); %} @@ -3150,8 +3146,7 @@ ins_cost(INSN_COST); format %{ "dup $dst, $src\t# vector (2D)" %} ins_encode %{ - __ dup(as_FloatRegister($dst$$reg), __ T2D, - as_FloatRegister($src$$reg)); + __ dup(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg)); %} ins_pipe(vdup_reg_dreg128); %} @@ -4428,7 +4423,7 @@ ins_pipe(vshift128_imm); %} -instruct vsra8B_imm(vecD dst, vecD src, immI shift) %{ +instruct vsra8B_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (RShiftVB src (RShiftCntV shift))); @@ -4443,7 +4438,7 @@ ins_pipe(vshift64_imm); %} -instruct vsra16B_imm(vecX dst, vecX src, immI shift) %{ +instruct vsra16B_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (RShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4457,7 +4452,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrl8B_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrl8B_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4 || n->as_Vector()->length() == 8); match(Set dst (URShiftVB src (RShiftCntV shift))); @@ -4477,7 +4472,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrl16B_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrl16B_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (URShiftVB src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4632,7 +4627,7 @@ ins_pipe(vshift128_imm); %} -instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ +instruct vsra4S_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (RShiftVS src (RShiftCntV shift))); @@ -4647,7 +4642,7 @@ ins_pipe(vshift64_imm); %} -instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ +instruct vsra8S_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4661,7 +4656,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrl4S_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrl4S_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); match(Set dst (URShiftVS src (RShiftCntV shift))); @@ -4681,7 +4676,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrl8S_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrl8S_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (URShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4820,7 +4815,7 @@ ins_pipe(vshift128_imm); %} -instruct vsra2I_imm(vecD dst, vecD src, immI shift) %{ +instruct vsra2I_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4833,7 +4828,7 @@ ins_pipe(vshift64_imm); %} -instruct vsra4I_imm(vecX dst, vecX src, immI shift) %{ +instruct vsra4I_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (RShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4846,7 +4841,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrl2I_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrl2I_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4859,7 +4854,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrl4I_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrl4I_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (URShiftVI src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4932,7 +4927,7 @@ ins_pipe(vshift128_imm); %} -instruct vsra2L_imm(vecX dst, vecX src, immI shift) %{ +instruct vsra2L_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (RShiftVL src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4945,7 +4940,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrl2L_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrl2L_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (URShiftVL src (RShiftCntV shift))); ins_cost(INSN_COST); @@ -4958,7 +4953,7 @@ ins_pipe(vshift128_imm); %} -instruct vsraa8B_imm(vecD dst, vecD src, immI shift) %{ +instruct vsraa8B_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVB dst (RShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -4972,7 +4967,7 @@ ins_pipe(vshift64_imm); %} -instruct vsraa16B_imm(vecX dst, vecX src, immI shift) %{ +instruct vsraa16B_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AddVB dst (RShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -4986,7 +4981,7 @@ ins_pipe(vshift128_imm); %} -instruct vsraa4S_imm(vecD dst, vecD src, immI shift) %{ +instruct vsraa4S_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVS dst (RShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5000,7 +4995,7 @@ ins_pipe(vshift64_imm); %} -instruct vsraa8S_imm(vecX dst, vecX src, immI shift) %{ +instruct vsraa8S_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS dst (RShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5014,7 +5009,7 @@ ins_pipe(vshift128_imm); %} -instruct vsraa2I_imm(vecD dst, vecD src, immI shift) %{ +instruct vsraa2I_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI dst (RShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5027,7 +5022,7 @@ ins_pipe(vshift64_imm); %} -instruct vsraa4I_imm(vecX dst, vecX src, immI shift) %{ +instruct vsraa4I_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI dst (RShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5040,7 +5035,7 @@ ins_pipe(vshift128_imm); %} -instruct vsraa2L_imm(vecX dst, vecX src, immI shift) %{ +instruct vsraa2L_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVL dst (RShiftVL src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5053,7 +5048,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrla8B_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrla8B_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVB dst (URShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5068,7 +5063,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrla16B_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrla16B_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 16); match(Set dst (AddVB dst (URShiftVB src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5083,7 +5078,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrla4S_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrla4S_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVS dst (URShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5098,7 +5093,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrla8S_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrla8S_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 8); match(Set dst (AddVS dst (URShiftVS src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5113,7 +5108,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrla2I_imm(vecD dst, vecD src, immI shift) %{ +instruct vsrla2I_imm(vecD dst, vecD src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVI dst (URShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5126,7 +5121,7 @@ ins_pipe(vshift64_imm); %} -instruct vsrla4I_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrla4I_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 4); match(Set dst (AddVI dst (URShiftVI src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -5139,7 +5134,7 @@ ins_pipe(vshift128_imm); %} -instruct vsrla2L_imm(vecX dst, vecX src, immI shift) %{ +instruct vsrla2L_imm(vecX dst, vecX src, immI_positive shift) %{ predicate(n->as_Vector()->length() == 2); match(Set dst (AddVL dst (URShiftVL src (RShiftCntV shift)))); ins_cost(INSN_COST); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/aarch64_neon_ad.m4 2023-01-10 13:21:55.000000000 +0000 @@ -1463,55 +1463,54 @@ VFABD(fabd, fabd, 4, F, X, S, 128) VFABD(fabd, fabd, 2, D, X, D, 128) dnl -define(`VREPLICATE', ` -instruct replicate$3$4$5`'(vec$6 dst, $7 ifelse($7, immI0, zero, $7, immI, con, src)) +define(`VREPLICATE_REG', ` +instruct replicate$2$3`'(vec$4 dst, $5 src) %{ - predicate(ifelse($8, UseSVE == 0 && , $8, - $8, , , $8` - ')n->as_Vector()->length() == $3); - match(Set dst (Replicate`'ifelse($7, immI0, I, $4) ifelse($7, immI0, zero, $7, immI, con, $7, zero, I, src))); + predicate(ifelse($7, UseSVE == 0 && , $7, + $7, , , $7` + ')n->as_Vector()->length() == $2); + match(Set dst (Replicate$3 src)); ins_cost(INSN_COST); - format %{ "$1 $dst, $ifelse($7, immI0, zero, $7, immI, con, src)`\t# vector ('ifelse($4$7, SimmI, $3H, $2, eor, 4I, $3$4)`)"' %} + format %{ "dup $dst, $src\t# vector ($2$3)" %} ins_encode %{ - __ $2(as_FloatRegister($dst$$reg), __ ifelse( - $2, eor, T16B, T$3`'$9),ifelse( - `$4 $7', `B immI', ` '$con$$constant & 0xff, - `$4 $7', `S immI', ` '$con$$constant & 0xffff, - `$4 $7', `I immI', ` '$con$$constant, - `$2', eor,` - as_FloatRegister($dst$$reg), - as_FloatRegister($dst$$reg)', - `$7', vRegF,` - as_FloatRegister($src$$reg)', - `$7', vRegD,` - as_FloatRegister($src$$reg)', - ` 'as_Register($src$$reg))); - %} - ins_pipe(ifelse($7, immI0, v$1_reg_imm, - $7, immI, v$1_reg_imm, - $7, iRegIorL2I, v$1_reg_reg, - $7, zero, vmovi_reg_imm, - $7, iRegL, vdup_reg_reg, - $4, F, vdup_reg_freg, vdup_reg_dreg)`'ifelse($6, X, 128, 64)); -%}')dnl -dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 -VREPLICATE(dup, dup, 8, B, , D, iRegIorL2I, n->as_Vector()->length() == 4 ||, B) -VREPLICATE(dup, dup, 16, B, , X, iRegIorL2I, UseSVE == 0 && , B) -VREPLICATE(movi, mov, 8, B, _imm, D, immI, n->as_Vector()->length() == 4 ||, B) -VREPLICATE(movi, mov, 16, B, _imm, X, immI, UseSVE == 0 && , B) -VREPLICATE(dup, dup, 4, S, , D, iRegIorL2I, n->as_Vector()->length() == 2 ||, H) -VREPLICATE(dup, dup, 8, S, , X, iRegIorL2I, UseSVE == 0 && , H) -VREPLICATE(movi, mov, 4, S, _imm, D, immI, n->as_Vector()->length() == 2 ||, H) -VREPLICATE(movi, mov, 8, S, _imm, X, immI, UseSVE == 0 && , H) -VREPLICATE(dup, dup, 2, I, , D, iRegIorL2I, , S) -VREPLICATE(dup, dup, 4, I, , X, iRegIorL2I, UseSVE == 0 && , S) -VREPLICATE(movi, mov, 2, I, _imm, D, immI, , S) -VREPLICATE(movi, mov, 4, I, _imm, X, immI, UseSVE == 0 && , S) -VREPLICATE(dup, dup, 2, L, , X, iRegL, UseSVE == 0 && , D) -VREPLICATE(movi, eor, 2, L, _zero, X, immI0, UseSVE == 0 && , D) -VREPLICATE(dup, dup, 2, F, , D, vRegF, , S) -VREPLICATE(dup, dup, 4, F, , X, vRegF, UseSVE == 0 && , S) -VREPLICATE(dup, dup, 2, D, , X, vRegD, UseSVE == 0 && , D) + __ dup(as_FloatRegister($dst$$reg), __ T$2$1, $6($src$$reg)); + %} + ins_pipe(ifelse($5, iRegIorL2I, vdup_reg_reg, + $5, iRegL, vdup_reg_reg, + $3, F, vdup_reg_freg, vdup_reg_dreg)`'ifelse($4, X, 128, 64)); +%}')dnl +define(`VREPLICATE_IMM', ` +instruct replicate$2$3_imm`'(vec$4 dst, $5 con) +%{ + predicate(ifelse($7, UseSVE == 0 && , $7, + $7, , , $7` + ')n->as_Vector()->length() == $2); + match(Set dst (Replicate$3 con)); + ins_cost(INSN_COST); + format %{ "movi $dst, $con\t`#' vector ($2`'ifelse($3, S, H, $3))" %} + ins_encode %{ + __ mov(as_FloatRegister($dst$$reg), __ T$2`'iTYPE2SIMD($3), $con$$constant`'$6); + %} + ins_pipe(vmovi_reg_imm`'ifelse($4, X, 128, 64)); +%}')dnl +dnl $1 $2 $3 $4 $5 $6 $7 +VREPLICATE_REG(B, 8, B, D, iRegIorL2I, as_Register, n->as_Vector()->length() == 4 ||) +VREPLICATE_REG(B, 16, B, X, iRegIorL2I, as_Register, UseSVE == 0 && ) +VREPLICATE_IMM(B, 8, B, D, immI, ` & 0xff', n->as_Vector()->length() == 4 ||) +VREPLICATE_IMM(B, 16, B, X, immI, ` & 0xff', UseSVE == 0 && ) +VREPLICATE_REG(H, 4, S, D, iRegIorL2I, as_Register, n->as_Vector()->length() == 2 ||) +VREPLICATE_REG(H, 8, S, X, iRegIorL2I, as_Register, UseSVE == 0 && ) +VREPLICATE_IMM(H, 4, S, D, immI, ` & 0xffff', n->as_Vector()->length() == 2 ||) +VREPLICATE_IMM(H, 8, S, X, immI, ` & 0xffff', UseSVE == 0 && ) +VREPLICATE_REG(S, 2, I, D, iRegIorL2I, as_Register, ) +VREPLICATE_REG(S, 4, I, X, iRegIorL2I, as_Register, UseSVE == 0 && ) +VREPLICATE_IMM(S, 2, I, D, immI, , ) +VREPLICATE_IMM(S, 4, I, X, immI, , UseSVE == 0 && ) +VREPLICATE_REG(D, 2, L, X, iRegL, as_Register, UseSVE == 0 && ) +VREPLICATE_IMM(D, 2, L, X, immL, , UseSVE == 0 && ) +VREPLICATE_REG(S, 2, F, D, vRegF, as_FloatRegister, ) +VREPLICATE_REG(S, 4, F, X, vRegF, as_FloatRegister, UseSVE == 0 && ) +VREPLICATE_REG(D, 2, D, X, vRegD, as_FloatRegister, UseSVE == 0 && ) dnl // ====================REDUCTION ARITHMETIC==================================== @@ -1992,7 +1991,7 @@ ins_pipe(vshift`'ifelse($6, D, 64, 128)_imm); %}')dnl define(`VSRA_IMM', ` -instruct vsra$3$4_imm`'(vec$6 dst, vec$6 src, immI shift) %{ +instruct vsra$3$4_imm`'(vec$6 dst, vec$6 src, immI_positive shift) %{ predicate(ifelse($3$4, 8B, n->as_Vector()->length() == 4 ||` ', $3$4, 4S, n->as_Vector()->length() == 2 ||` @@ -2017,7 +2016,7 @@ %}')dnl dnl define(`VSRL_IMM', ` -instruct vsrl$3$4_imm`'(vec$6 dst, vec$6 src, immI shift) %{ +instruct vsrl$3$4_imm`'(vec$6 dst, vec$6 src, immI_positive shift) %{ predicate(ifelse($3$4, 8B, n->as_Vector()->length() == 4 ||` ', $3$4, 4S, n->as_Vector()->length() == 2 ||` @@ -2052,7 +2051,7 @@ %}')dnl dnl define(`VSRLA_IMM', ` -instruct vsrla$3$4_imm`'(vec$6 dst, vec$6 src, immI shift) %{ +instruct vsrla$3$4_imm`'(vec$6 dst, vec$6 src, immI_positive shift) %{ predicate(n->as_Vector()->length() == $3); match(Set dst (AddV$4 dst (URShiftV$4 src (RShiftCntV shift)))); ins_cost(INSN_COST); @@ -2076,7 +2075,7 @@ %}')dnl dnl define(`VSRAA_IMM', ` -instruct vsraa$3$4_imm`'(vec$6 dst, vec$6 src, immI shift) %{ +instruct vsraa$3$4_imm`'(vec$6 dst, vec$6 src, immI_positive shift) %{ predicate(n->as_Vector()->length() == $3); match(Set dst (AddV$4 dst (RShiftV$4 src (RShiftCntV shift)))); ins_cost(INSN_COST); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020 Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -313,6 +313,53 @@ return encode_logical_immediate(is32, imm) != 0xffffffff; } +// Check immediate encoding for movi. +// Return the shift amount which can be {0, 8, 16, 24} for B/H/S types. As the D type +// movi does not have shift variant, in this case the return value is the immediate +// after encoding. +// Return -1 if the input imm64 can not be encoded. +int Assembler::operand_valid_for_movi_immediate(uint64_t imm64, SIMD_Arrangement T) { + if (T == T1D || T == T2D) { + // To encode into movi, the 64-bit imm must be in the form of + // 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh' + // and encoded in "a:b:c:d:e:f:g:h". + uint64_t tmp = imm64; + uint64_t one_byte = 0; + for (int i = 0; i < 8; i++) { + one_byte = tmp & 0xffULL; + if (one_byte != 0xffULL && one_byte != 0) { + return -1; // can not be encoded + } + tmp = tmp >> 8; + } + + imm64 &= 0x0101010101010101ULL; + imm64 |= (imm64 >> 7); + imm64 |= (imm64 >> 14); + imm64 |= (imm64 >> 28); + + return imm64 & 0xff; + } + + uint32_t imm32 = imm64 & 0xffffffffULL; + if (T == T8B || T == T16B) { // 8-bit variant + if (0 == (imm32 & ~0xff)) return 0; + } else if(T == T4H || T == T8H) { // 16-bit variant + if (0 == (imm32 & ~0xff)) return 0; + if (0 == (imm32 & ~0xff00)) return 8; + } else if (T == T2S || T == T4S) { // 32-bit variant + if (0 == (imm32 & ~0xff)) return 0; + if (0 == (imm32 & ~0xff00)) return 8; + if (0 == (imm32 & ~0xff0000)) return 16; + if (0 == (imm32 & ~0xff000000)) return 24; + } else { + assert(false, "unsupported"); + ShouldNotReachHere(); + } + + return -1; +} + static uint64_t doubleTo64Bits(jdouble d) { union { jdouble double_value; diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -476,16 +476,17 @@ assert(size == 0, "bad size"); size = 0b100; } + assert(offset_ok_for_immed(_offset, size), + "must be, was: " INT64_FORMAT ", %d", _offset, size); unsigned mask = (1 << size) - 1; - if (_offset < 0 || _offset & mask) - { - i->f(0b00, 25, 24); - i->f(0, 21), i->f(0b00, 11, 10); - i->sf(_offset, 20, 12); - } else { - i->f(0b01, 25, 24); - i->f(_offset >> size, 21, 10); - } + if (_offset < 0 || _offset & mask) { + i->f(0b00, 25, 24); + i->f(0, 21), i->f(0b00, 11, 10); + i->sf(_offset, 20, 12); + } else { + i->f(0b01, 25, 24); + i->f(_offset >> size, 21, 10); + } } break; @@ -3254,6 +3255,7 @@ static bool operand_valid_for_logical_immediate(bool is32, uint64_t imm); static bool operand_valid_for_add_sub_immediate(int64_t imm); static bool operand_valid_for_float_immediate(double imm); + static int operand_valid_for_movi_immediate(uint64_t imm64, SIMD_Arrangement T); void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0); void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.inline.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.inline.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/assembler_aarch64.inline.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/assembler_aarch64.inline.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -30,8 +30,14 @@ #include "asm/codeBuffer.hpp" #include "code/codeCache.hpp" - +// Check if an offset is within the encoding range for LDR/STR instructions +// with an immediate offset, either using unscaled signed 9-bits or, scaled +// unsigned 12-bits. We favour the scaled unsigned encoding for all aligned +// offsets (only using the signed 9-bit encoding for negative and unaligned +// offsets). As a precondition, 0 <= shift <= 4 is the log2(size), for the +// supported data widths, {1, 2, 4, 8, 16} bytes. inline bool Address::offset_ok_for_immed(int64_t offset, uint shift) { + precond(shift < 5); uint mask = (1 << shift) - 1; if (offset < 0 || (offset & mask) != 0) { // Unscaled signed offset, encoded in a signed imm9 field. diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -187,14 +187,13 @@ default: ShouldNotReachHere(); } - } else { - intptr_t addr_offset = intptr_t(addr->disp()); - if (Address::offset_ok_for_immed(addr_offset, addr->scale())) - return Address(base, addr_offset, Address::lsl(addr->scale())); - else { - __ mov(tmp, addr_offset); - return Address(base, tmp, Address::lsl(addr->scale())); - } + } else { + assert(addr->scale() == 0, + "expected for immediate operand, was: %d", addr->scale()); + ptrdiff_t offset = ptrdiff_t(addr->disp()); + // NOTE: Does not handle any 16 byte vector access. + const uint type_size = type2aelembytes(addr->type(), true); + return __ legitimize_address(Address(base, offset), type_size, tmp); } return Address(); } @@ -283,10 +282,9 @@ __ bind(L); } #endif - __ ldr(r19, Address(OSR_buf, slot_offset + 0)); + __ ldp(r19, r20, Address(OSR_buf, slot_offset)); __ str(r19, frame_map()->address_for_monitor_lock(i)); - __ ldr(r19, Address(OSR_buf, slot_offset + 1*BytesPerWord)); - __ str(r19, frame_map()->address_for_monitor_object(i)); + __ str(r20, frame_map()->address_for_monitor_object(i)); } } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -148,7 +148,7 @@ if (index->is_constant()) { LIR_Const *constant = index->as_constant_ptr(); if (constant->type() == T_INT) { - large_disp += index->as_jint() << shift; + large_disp += ((intx)index->as_jint()) << shift; } else { assert(constant->type() == T_LONG, "should be"); jlong c = index->as_jlong() << shift; @@ -194,7 +194,7 @@ if (large_disp == 0 && index->is_register()) { return new LIR_Address(base, index, type); } else { - assert(Address::offset_ok_for_immed(large_disp, 0), "must be"); + assert(Address::offset_ok_for_immed(large_disp, shift), "failed for large_disp: " INTPTR_FORMAT " and shift %d", large_disp, shift); return new LIR_Address(base, large_disp, type); } } @@ -204,24 +204,7 @@ int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type); int elem_size = type2aelembytes(type); int shift = exact_log2(elem_size); - - LIR_Address* addr; - if (index_opr->is_constant()) { - addr = new LIR_Address(array_opr, - offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); - } else { - if (offset_in_bytes) { - LIR_Opr tmp = new_pointer_register(); - __ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp); - array_opr = tmp; - offset_in_bytes = 0; - } - addr = new LIR_Address(array_opr, - index_opr, - LIR_Address::scale(type), - offset_in_bytes, type); - } - return addr; + return generate_address(array_opr, index_opr, shift, offset_in_bytes, type); } LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { @@ -1132,8 +1115,8 @@ CodeEmitInfo* info = state_for(x, x->state()); LIR_Opr reg = result_register_for(x->type()); new_instance(reg, x->klass(), x->is_unresolved(), - FrameMap::r2_oop_opr, - FrameMap::r5_oop_opr, + FrameMap::r10_oop_opr, + FrameMap::r11_oop_opr, FrameMap::r4_oop_opr, LIR_OprFact::illegalOpr, FrameMap::r3_metadata_opr, info); @@ -1148,8 +1131,8 @@ length.load_item_force(FrameMap::r19_opr); LIR_Opr reg = result_register_for(x->type()); - LIR_Opr tmp1 = FrameMap::r2_oop_opr; - LIR_Opr tmp2 = FrameMap::r4_oop_opr; + LIR_Opr tmp1 = FrameMap::r10_oop_opr; + LIR_Opr tmp2 = FrameMap::r11_oop_opr; LIR_Opr tmp3 = FrameMap::r5_oop_opr; LIR_Opr tmp4 = reg; LIR_Opr klass_reg = FrameMap::r3_metadata_opr; @@ -1177,8 +1160,8 @@ CodeEmitInfo* info = state_for(x, x->state()); LIR_Opr reg = result_register_for(x->type()); - LIR_Opr tmp1 = FrameMap::r2_oop_opr; - LIR_Opr tmp2 = FrameMap::r4_oop_opr; + LIR_Opr tmp1 = FrameMap::r10_oop_opr; + LIR_Opr tmp2 = FrameMap::r11_oop_opr; LIR_Opr tmp3 = FrameMap::r5_oop_opr; LIR_Opr tmp4 = reg; LIR_Opr klass_reg = FrameMap::r3_metadata_opr; diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -203,20 +203,24 @@ } // preserves obj, destroys len_in_bytes -void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) { +// +// Scratch registers: t1 = r10, t2 = r11 +// +void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1, Register t2) { assert(hdr_size_in_bytes >= 0, "header size must be positive or 0"); + assert(t1 == r10 && t2 == r11, "must be"); + Label done; // len_in_bytes is positive and ptr sized subs(len_in_bytes, len_in_bytes, hdr_size_in_bytes); br(Assembler::EQ, done); - // Preserve obj - if (hdr_size_in_bytes) - add(obj, obj, hdr_size_in_bytes); - zero_memory(obj, len_in_bytes, t1); - if (hdr_size_in_bytes) - sub(obj, obj, hdr_size_in_bytes); + // zero_words() takes ptr in r10 and count in words in r11 + mov(rscratch1, len_in_bytes); + lea(t1, Address(obj, hdr_size_in_bytes)); + lsr(t2, rscratch1, LogBytesPerWord); + zero_words(t1, t2); bind(done); } @@ -231,6 +235,7 @@ initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB); } +// Scratch registers: t1 = r10, t2 = r11 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, bool is_tlab_allocated) { assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, "con_size_in_bytes is not multiple of alignment"); @@ -241,45 +246,13 @@ if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) { // clear rest of allocated space const Register index = t2; - const int threshold = 16 * BytesPerWord; // approximate break even point for code size (see comments below) if (var_size_in_bytes != noreg) { mov(index, var_size_in_bytes); - initialize_body(obj, index, hdr_size_in_bytes, t1); - } else if (con_size_in_bytes <= threshold) { - // use explicit null stores - int i = hdr_size_in_bytes; - if (i < con_size_in_bytes && (con_size_in_bytes % (2 * BytesPerWord))) { - str(zr, Address(obj, i)); - i += BytesPerWord; - } - for (; i < con_size_in_bytes; i += 2 * BytesPerWord) - stp(zr, zr, Address(obj, i)); + initialize_body(obj, index, hdr_size_in_bytes, t1, t2); } else if (con_size_in_bytes > hdr_size_in_bytes) { - block_comment("zero memory"); - // use loop to null out the fields - - int words = (con_size_in_bytes - hdr_size_in_bytes) / BytesPerWord; - mov(index, words / 8); - - const int unroll = 8; // Number of str(zr) instructions we'll unroll - int remainder = words % unroll; - lea(rscratch1, Address(obj, hdr_size_in_bytes + remainder * BytesPerWord)); - - Label entry_point, loop; - b(entry_point); - - bind(loop); - sub(index, index, 1); - for (int i = -unroll; i < 0; i++) { - if (-i == remainder) - bind(entry_point); - str(zr, Address(rscratch1, i * wordSize)); - } - if (remainder == 0) - bind(entry_point); - add(rscratch1, rscratch1, unroll * wordSize); - cbnz(index, loop); - + con_size_in_bytes -= hdr_size_in_bytes; + lea(t1, Address(obj, hdr_size_in_bytes)); + zero_words(t1, con_size_in_bytes / BytesPerWord); } } @@ -314,8 +287,7 @@ initialize_header(obj, klass, len, t1, t2); // clear rest of allocated space - const Register len_zero = len; - initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero); + initialize_body(obj, arr_size, header_size * BytesPerWord, t1, t2); membar(StoreStore); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -48,7 +48,7 @@ ); void initialize_header(Register obj, Register klass, Register len, Register t1, Register t2); - void initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1); + void initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1, Register t2); void float_cmp(bool is_float, int unordered_result, FloatRegister f0, FloatRegister f1, diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -656,9 +656,9 @@ if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && !UseTLAB && Universe::heap()->supports_inline_contig_alloc()) { Label slow_path; - Register obj_size = r2; - Register t1 = r19; - Register t2 = r4; + Register obj_size = r19; + Register t1 = r10; + Register t2 = r11; assert_different_registers(klass, obj, obj_size, t1, t2); __ stp(r19, zr, Address(__ pre(sp, -2 * wordSize))); @@ -769,9 +769,9 @@ // allocations. // Otherwise, just go to the slow path. if (!UseTLAB && Universe::heap()->supports_inline_contig_alloc()) { - Register arr_size = r4; - Register t1 = r2; - Register t2 = r5; + Register arr_size = r5; + Register t1 = r10; + Register t2 = r11; Label slow_path; assert_different_registers(length, klass, obj, arr_size, t1, t2); @@ -801,7 +801,7 @@ __ andr(t1, t1, Klass::_lh_header_size_mask); __ sub(arr_size, arr_size, t1); // body length __ add(t1, t1, obj); // body start - __ initialize_body(t1, arr_size, 0, t2); + __ initialize_body(t1, arr_size, 0, t1, t2); __ membar(Assembler::StoreStore); __ verify_oop(obj); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/globals_aarch64.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/globals_aarch64.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/globals_aarch64.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/globals_aarch64.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -106,7 +106,7 @@ "Use DC ZVA for block zeroing") \ product(intx, BlockZeroingLowLimit, 256, \ "Minimum size in bytes when block zeroing will be used") \ - range(1, max_jint) \ + range(wordSize, max_jint) \ product(bool, TraceTraps, false, "Trace all traps the signal handler")\ product(int, SoftwarePrefetchHintDistance, -1, \ "Use prfm hint with specified distance in compiled code." \ diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -52,9 +52,15 @@ address start = __ pc(); Label l; __ ldr(rscratch2, l); - __ far_jump(ExternalAddress(entry_point)); - __ align(wordSize); + int jump_code_size = __ far_jump(ExternalAddress(entry_point)); + // IC stub code size is not expected to vary depending on target address. + // We use NOPs to make the [ldr + far_jump + nops + int64] stub size equal to ic_stub_code_size. + for (int size = NativeInstruction::instruction_size + jump_code_size + 8; + size < ic_stub_code_size(); size += NativeInstruction::instruction_size) { + __ nop(); + } __ bind(l); + assert((uintptr_t)__ pc() % wordSize == 0, ""); __ emit_int64((int64_t)cached_value); // Only need to invalidate the 1st two instructions - not the whole ic stub ICache::invalidate_range(code_begin, InlineCacheBuffer::ic_stub_code_size()); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ #include "jvm.h" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" +#include "ci/ciEnv.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/cardTableBarrierSet.hpp" @@ -37,6 +38,7 @@ #include "gc/shared/tlab_globals.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "interpreter/interpreter.hpp" +#include "compiler/compileTask.hpp" #include "compiler/disassembler.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -382,14 +384,27 @@ } } +static inline bool target_needs_far_branch(address addr) { + // codecache size <= 128M + if (!MacroAssembler::far_branches()) { + return false; + } + // codecache size > 240M + if (MacroAssembler::codestub_branch_needs_far_jump()) { + return true; + } + // codecache size: 128M..240M + return !CodeCache::is_non_nmethod(addr); +} + void MacroAssembler::far_call(Address entry, CodeBuffer *cbuf, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != NULL, "destination of far call not found in code cache"); - if (far_branches()) { + if (target_needs_far_branch(entry.target())) { uint64_t offset; // We can use ADRP here because we know that the total size of - // the code cache cannot exceed 2Gb. + // the code cache cannot exceed 2Gb (ADRP limit is 4GB). adrp(tmp, entry, offset); add(tmp, tmp, offset); if (cbuf) cbuf->set_insts_mark(); @@ -400,14 +415,15 @@ } } -void MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) { +int MacroAssembler::far_jump(Address entry, CodeBuffer *cbuf, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != NULL, "destination of far call not found in code cache"); - if (far_branches()) { + address start = pc(); + if (target_needs_far_branch(entry.target())) { uint64_t offset; // We can use ADRP here because we know that the total size of - // the code cache cannot exceed 2Gb. + // the code cache cannot exceed 2Gb (ADRP limit is 4GB). adrp(tmp, entry, offset); add(tmp, tmp, offset); if (cbuf) cbuf->set_insts_mark(); @@ -416,6 +432,7 @@ if (cbuf) cbuf->set_insts_mark(); b(entry); } + return pc() - start; } void MacroAssembler::reserved_stack_check() { @@ -1229,7 +1246,7 @@ if (!IS_A_TEMP(r2)) pushed_registers += r2; if (!IS_A_TEMP(r5)) pushed_registers += r5; - if (super_klass != r0 || UseCompressedOops) { + if (super_klass != r0) { if (!IS_A_TEMP(r0)) pushed_registers += r0; } @@ -1509,48 +1526,43 @@ } // Macro to mov replicated immediate to vector register. -// Vd will get the following values for different arrangements in T -// imm32 == hex 000000gh T8B: Vd = ghghghghghghghgh -// imm32 == hex 000000gh T16B: Vd = ghghghghghghghghghghghghghghghgh -// imm32 == hex 0000efgh T4H: Vd = efghefghefghefgh -// imm32 == hex 0000efgh T8H: Vd = efghefghefghefghefghefghefghefgh -// imm32 == hex abcdefgh T2S: Vd = abcdefghabcdefgh -// imm32 == hex abcdefgh T4S: Vd = abcdefghabcdefghabcdefghabcdefgh -// T1D/T2D: invalid -void MacroAssembler::mov(FloatRegister Vd, SIMD_Arrangement T, uint32_t imm32) { - assert(T != T1D && T != T2D, "invalid arrangement"); - if (T == T8B || T == T16B) { - assert((imm32 & ~0xff) == 0, "extraneous bits in unsigned imm32 (T8B/T16B)"); - movi(Vd, T, imm32 & 0xff, 0); +// imm64: only the lower 8/16/32 bits are considered for B/H/S type. That is, +// the upper 56/48/32 bits must be zeros for B/H/S type. +// Vd will get the following values for different arrangements in T +// imm64 == hex 000000gh T8B: Vd = ghghghghghghghgh +// imm64 == hex 000000gh T16B: Vd = ghghghghghghghghghghghghghghghgh +// imm64 == hex 0000efgh T4H: Vd = efghefghefghefgh +// imm64 == hex 0000efgh T8H: Vd = efghefghefghefghefghefghefghefgh +// imm64 == hex abcdefgh T2S: Vd = abcdefghabcdefgh +// imm64 == hex abcdefgh T4S: Vd = abcdefghabcdefghabcdefghabcdefgh +// imm64 == hex abcdefgh T1D: Vd = 00000000abcdefgh +// imm64 == hex abcdefgh T2D: Vd = 00000000abcdefgh00000000abcdefgh +// Clobbers rscratch1 +void MacroAssembler::mov(FloatRegister Vd, SIMD_Arrangement T, uint64_t imm64) { + assert(T != T1Q, "unsupported"); + if (T == T1D || T == T2D) { + int imm = operand_valid_for_movi_immediate(imm64, T); + if (-1 != imm) { + movi(Vd, T, imm); + } else { + mov(rscratch1, imm64); + dup(Vd, T, rscratch1); + } return; } - uint32_t nimm32 = ~imm32; - if (T == T4H || T == T8H) { - assert((imm32 & ~0xffff) == 0, "extraneous bits in unsigned imm32 (T4H/T8H)"); - imm32 &= 0xffff; - nimm32 &= 0xffff; - } - uint32_t x = imm32; - int movi_cnt = 0; - int movn_cnt = 0; - while (x) { if (x & 0xff) movi_cnt++; x >>= 8; } - x = nimm32; - while (x) { if (x & 0xff) movn_cnt++; x >>= 8; } - if (movn_cnt < movi_cnt) imm32 = nimm32; - unsigned lsl = 0; - while (imm32 && (imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; } - if (movn_cnt < movi_cnt) - mvni(Vd, T, imm32 & 0xff, lsl); - else - movi(Vd, T, imm32 & 0xff, lsl); - imm32 >>= 8; lsl += 8; - while (imm32) { - while ((imm32 & 0xff) == 0) { lsl += 8; imm32 >>= 8; } - if (movn_cnt < movi_cnt) - bici(Vd, T, imm32 & 0xff, lsl); - else - orri(Vd, T, imm32 & 0xff, lsl); - lsl += 8; imm32 >>= 8; + +#ifdef ASSERT + if (T == T8B || T == T16B) assert((imm64 & ~0xff) == 0, "extraneous bits (T8B/T16B)"); + if (T == T4H || T == T8H) assert((imm64 & ~0xffff) == 0, "extraneous bits (T4H/T8H)"); + if (T == T2S || T == T4S) assert((imm64 & ~0xffffffff) == 0, "extraneous bits (T2S/T4S)"); +#endif + int shift = operand_valid_for_movi_immediate(imm64, T); + uint32_t imm32 = imm64 & 0xffffffffULL; + if (shift >= 0) { + movi(Vd, T, (imm32 >> shift) & 0xff, shift); + } else { + movw(rscratch1, imm32); + dup(Vd, T, rscratch1); } } @@ -4283,68 +4295,6 @@ bs->eden_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case); } -// Zero words; len is in bytes -// Destroys all registers except addr -// len must be a nonzero multiple of wordSize -void MacroAssembler::zero_memory(Register addr, Register len, Register t1) { - assert_different_registers(addr, len, t1, rscratch1, rscratch2); - -#ifdef ASSERT - { Label L; - tst(len, BytesPerWord - 1); - br(Assembler::EQ, L); - stop("len is not a multiple of BytesPerWord"); - bind(L); - } -#endif - -#ifndef PRODUCT - block_comment("zero memory"); -#endif - - Label loop; - Label entry; - -// Algorithm: -// -// scratch1 = cnt & 7; -// cnt -= scratch1; -// p += scratch1; -// switch (scratch1) { -// do { -// cnt -= 8; -// p[-8] = 0; -// case 7: -// p[-7] = 0; -// case 6: -// p[-6] = 0; -// // ... -// case 1: -// p[-1] = 0; -// case 0: -// p += 8; -// } while (cnt); -// } - - const int unroll = 8; // Number of str(zr) instructions we'll unroll - - lsr(len, len, LogBytesPerWord); - andr(rscratch1, len, unroll - 1); // tmp1 = cnt % unroll - sub(len, len, rscratch1); // cnt -= unroll - // t1 always points to the end of the region we're about to zero - add(t1, addr, rscratch1, Assembler::LSL, LogBytesPerWord); - adr(rscratch2, entry); - sub(rscratch2, rscratch2, rscratch1, Assembler::LSL, 2); - br(rscratch2); - bind(loop); - sub(len, len, unroll); - for (int i = -unroll; i < 0; i++) - Assembler::str(zr, Address(t1, i * wordSize)); - bind(entry); - add(t1, t1, unroll * wordSize); - cbnz(len, loop); -} - void MacroAssembler::verify_tlab() { #ifdef ASSERT if (UseTLAB && VerifyOops) { @@ -4863,10 +4813,11 @@ // handle anything smaller than this ourselves in zero_words(). const int MacroAssembler::zero_words_block_size = 8; -// zero_words() is used by C2 ClearArray patterns. It is as small as -// possible, handling small word counts locally and delegating -// anything larger to the zero_blocks stub. It is expanded many times -// in compiled code, so it is important to keep it short. +// zero_words() is used by C2 ClearArray patterns and by +// C1_MacroAssembler. It is as small as possible, handling small word +// counts locally and delegating anything larger to the zero_blocks +// stub. It is expanded many times in compiled code, so it is +// important to keep it short. // ptr: Address of a buffer to be zeroed. // cnt: Count in HeapWords. @@ -4875,32 +4826,45 @@ address MacroAssembler::zero_words(Register ptr, Register cnt) { assert(is_power_of_2(zero_words_block_size), "adjust this"); - assert(ptr == r10 && cnt == r11, "mismatch in register usage"); BLOCK_COMMENT("zero_words {"); - cmp(cnt, (u1)zero_words_block_size); + assert(ptr == r10 && cnt == r11, "mismatch in register usage"); + RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::aarch64::zero_blocks()); + assert(zero_blocks.target() != NULL, "zero_blocks stub has not been generated"); + + subs(rscratch1, cnt, zero_words_block_size); Label around; br(LO, around); { RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::aarch64::zero_blocks()); assert(zero_blocks.target() != NULL, "zero_blocks stub has not been generated"); - if (StubRoutines::aarch64::complete()) { + // Make sure this is a C2 compilation. C1 allocates space only for + // trampoline stubs generated by Call LIR ops, and in any case it + // makes sense for a C1 compilation task to proceed as quickly as + // possible. + CompileTask* task; + if (StubRoutines::aarch64::complete() + && Thread::current()->is_Compiler_thread() + && (task = ciEnv::current()->task()) + && is_c2_compile(task->comp_level())) { address tpc = trampoline_call(zero_blocks); if (tpc == NULL) { DEBUG_ONLY(reset_labels(around)); - postcond(pc() == badAddress); return NULL; } } else { - bl(zero_blocks); + far_call(zero_blocks); } } bind(around); + + // We have a few words left to do. zero_blocks has adjusted r10 and r11 + // for us. for (int i = zero_words_block_size >> 1; i > 1; i >>= 1) { Label l; tbz(cnt, exact_log2(i), l); for (int j = 0; j < i; j += 2) { - stp(zr, zr, post(ptr, 16)); + stp(zr, zr, post(ptr, 2 * BytesPerWord)); } bind(l); } @@ -4910,46 +4874,59 @@ str(zr, Address(ptr)); bind(l); } + BLOCK_COMMENT("} zero_words"); - postcond(pc() != badAddress); return pc(); } // base: Address of a buffer to be zeroed, 8 bytes aligned. // cnt: Immediate count in HeapWords. -#define SmallArraySize (18 * BytesPerLong) -void MacroAssembler::zero_words(Register base, uint64_t cnt) +// +// r10, r11, rscratch1, and rscratch2 are clobbered. +address MacroAssembler::zero_words(Register base, uint64_t cnt) { - BLOCK_COMMENT("zero_words {"); - int i = cnt & 1; // store any odd word to start - if (i) str(zr, Address(base)); - - if (cnt <= SmallArraySize / BytesPerLong) { + assert(wordSize <= BlockZeroingLowLimit, + "increase BlockZeroingLowLimit"); + address result = nullptr; + if (cnt <= (uint64_t)BlockZeroingLowLimit / BytesPerWord) { +#ifndef PRODUCT + { + char buf[64]; + snprintf(buf, sizeof buf, "zero_words (count = %" PRIu64 ") {", cnt); + BLOCK_COMMENT(buf); + } +#endif + if (cnt >= 16) { + uint64_t loops = cnt/16; + if (loops > 1) { + mov(rscratch2, loops - 1); + } + { + Label loop; + bind(loop); + for (int i = 0; i < 16; i += 2) { + stp(zr, zr, Address(base, i * BytesPerWord)); + } + add(base, base, 16 * BytesPerWord); + if (loops > 1) { + subs(rscratch2, rscratch2, 1); + br(GE, loop); + } + } + } + cnt %= 16; + int i = cnt & 1; // store any odd word to start + if (i) str(zr, Address(base)); for (; i < (int)cnt; i += 2) { stp(zr, zr, Address(base, i * wordSize)); } + BLOCK_COMMENT("} zero_words"); + result = pc(); } else { - const int unroll = 4; // Number of stp(zr, zr) instructions we'll unroll - int remainder = cnt % (2 * unroll); - for (; i < remainder; i += 2) { - stp(zr, zr, Address(base, i * wordSize)); - } - Label loop; - Register cnt_reg = rscratch1; - Register loop_base = rscratch2; - cnt = cnt - remainder; - mov(cnt_reg, cnt); - // adjust base and prebias by -2 * wordSize so we can pre-increment - add(loop_base, base, (remainder - 2) * wordSize); - bind(loop); - sub(cnt_reg, cnt_reg, 2 * unroll); - for (i = 1; i < unroll; i++) { - stp(zr, zr, Address(loop_base, 2 * i * wordSize)); - } - stp(zr, zr, Address(pre(loop_base, 2 * unroll * wordSize))); - cbnz(cnt_reg, loop); + mov(r10, base); mov(r11, cnt); + result = zero_words(r10, r11); } - BLOCK_COMMENT("} zero_words"); + return result; } // Zero blocks of memory by using DC ZVA. diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -525,7 +525,7 @@ void movptr(Register r, uintptr_t imm64); - void mov(FloatRegister Vd, SIMD_Arrangement T, uint32_t imm32); + void mov(FloatRegister Vd, SIMD_Arrangement T, uint64_t imm64); void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) { orr(Vd, T, Vn, Vn); @@ -907,7 +907,6 @@ Register t2, // temp register Label& slow_case // continuation point if fast allocation fails ); - void zero_memory(Register addr, Register len, Register t1); void verify_tlab(); // interface method calling @@ -1087,13 +1086,18 @@ return ReservedCodeCacheSize > branch_range; } + // Check if branches to the the non nmethod section require a far jump + static bool codestub_branch_needs_far_jump() { + return CodeCache::max_distance_to_non_nmethod() > branch_range; + } + // Jumps that can reach anywhere in the code cache. // Trashes tmp. void far_call(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1); - void far_jump(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1); + int far_jump(Address entry, CodeBuffer *cbuf = NULL, Register tmp = rscratch1); - static int far_branch_size() { - if (far_branches()) { + static int far_codestub_branch_size() { + if (codestub_branch_needs_far_jump()) { return 3 * 4; // adrp, add, br } else { return 4; @@ -1258,7 +1262,7 @@ int elem_size); void fill_words(Register base, Register cnt, Register value); - void zero_words(Register base, uint64_t cnt); + address zero_words(Register base, uint64_t cnt); address zero_words(Register ptr, Register cnt); void zero_dcache_blocks(Register base, Register cnt); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -4752,7 +4752,7 @@ __ enter(); - Label RET_TRUE, RET_TRUE_NO_POP, RET_FALSE, ALIGNED, LOOP16, CHECK_16, DONE, + Label RET_TRUE, RET_TRUE_NO_POP, RET_FALSE, ALIGNED, LOOP16, CHECK_16, LARGE_LOOP, POST_LOOP16, LEN_OVER_15, LEN_OVER_8, POST_LOOP16_LOAD_TAIL; __ cmp(len, (u1)15); @@ -4894,10 +4894,6 @@ __ mov(result, 1); __ ret(lr); - __ bind(DONE); - __ pop(spilled_regs, sp); - __ leave(); - __ ret(lr); return entry; } @@ -6129,6 +6125,7 @@ * c_rarg3 - dest_start * c_rarg4 - dest_offset * c_rarg5 - isURL + * c_rarg6 - isMIME * */ address generate_base64_decodeBlock() { @@ -6211,12 +6208,13 @@ StubCodeMark mark(this, "StubRoutines", "decodeBlock"); address start = __ pc(); - Register src = c_rarg0; // source array - Register soff = c_rarg1; // source start offset - Register send = c_rarg2; // source end offset - Register dst = c_rarg3; // dest array - Register doff = c_rarg4; // position for writing to dest array - Register isURL = c_rarg5; // Base64 or URL character set + Register src = c_rarg0; // source array + Register soff = c_rarg1; // source start offset + Register send = c_rarg2; // source end offset + Register dst = c_rarg3; // dest array + Register doff = c_rarg4; // position for writing to dest array + Register isURL = c_rarg5; // Base64 or URL character set + Register isMIME = c_rarg6; // Decoding MIME block - unused in this implementation Register length = send; // reuse send as length of source data to process diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -266,7 +266,7 @@ UseAES = true; } if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) { - FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true); } } else { if (UseAES) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1483,6 +1483,9 @@ __ mov_double(result->as_double_reg(), c->as_jdouble(), acond); #endif // __SOFTFP__ break; + case T_METADATA: + __ mov_metadata(result->as_register(), c->as_metadata(), acond); + break; default: ShouldNotReachHere(); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/arm/stubGenerator_arm.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/arm/stubGenerator_arm.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/arm/stubGenerator_arm.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/arm/stubGenerator_arm.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -635,17 +635,17 @@ Register result_hi = R1; Register src = R0; - if (!os::is_MP()) { - __ ldmia(src, RegisterSet(result_lo, result_hi)); - __ bx(LR); - } else if (VM_Version::supports_ldrexd()) { + if (VM_Version::supports_ldrexd()) { __ ldrexd(result_lo, Address(src)); __ clrex(); // FIXME: safe to remove? - __ bx(LR); + } else if (!os::is_MP()) { + // Last-ditch attempt: we are allegedly running on uni-processor. + // Load the thing non-atomically and hope for the best. + __ ldmia(src, RegisterSet(result_lo, result_hi)); } else { __ stop("Atomic load(jlong) unsupported on this platform"); - __ bx(LR); } + __ bx(LR); return start; } @@ -662,10 +662,7 @@ Register scratch_hi = R3; /* After load from stack */ Register result = R3; - if (!os::is_MP()) { - __ stmia(dest, RegisterSet(newval_lo, newval_hi)); - __ bx(LR); - } else if (VM_Version::supports_ldrexd()) { + if (VM_Version::supports_ldrexd()) { __ mov(Rtemp, dest); // get dest to Rtemp Label retry; __ bind(retry); @@ -673,11 +670,14 @@ __ strexd(result, R0, Address(Rtemp)); __ rsbs(result, result, 1); __ b(retry, eq); - __ bx(LR); + } else if (!os::is_MP()) { + // Last-ditch attempt: we are allegedly running on uni-processor. + // Store the thing non-atomically and hope for the best. + __ stmia(dest, RegisterSet(newval_lo, newval_hi)); } else { __ stop("Atomic store(jlong) unsupported on this platform"); - __ bx(LR); } + __ bx(LR); return start; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/arm/templateTable_arm.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/arm/templateTable_arm.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/arm/templateTable_arm.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/arm/templateTable_arm.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -490,29 +490,30 @@ __ add(Rtemp, Rtags, tags_offset); __ ldrb(Rtemp, Address(Rtemp, Rindex)); - Label Condy, exit; -#ifdef __ABI_HARD__ - Label NotDouble; + Label Done, NotLong, NotDouble; __ cmp(Rtemp, JVM_CONSTANT_Double); __ b(NotDouble, ne); +#ifdef __SOFTFP__ + __ ldr(R0_tos_lo, Address(Rbase, base_offset + 0 * wordSize)); + __ ldr(R1_tos_hi, Address(Rbase, base_offset + 1 * wordSize)); +#else // !__SOFTFP__ __ ldr_double(D0_tos, Address(Rbase, base_offset)); - +#endif // __SOFTFP__ __ push(dtos); - __ b(exit); + __ b(Done); __ bind(NotDouble); -#endif __ cmp(Rtemp, JVM_CONSTANT_Long); - __ b(Condy, ne); + __ b(NotLong, ne); __ ldr(R0_tos_lo, Address(Rbase, base_offset + 0 * wordSize)); __ ldr(R1_tos_hi, Address(Rbase, base_offset + 1 * wordSize)); __ push(ltos); - __ b(exit); + __ b(Done); + __ bind(NotLong); - __ bind(Condy); - condy_helper(exit); + condy_helper(Done); - __ bind(exit); + __ bind(Done); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/ppc/ppc.ad openjdk-17-17.0.6+10/src/hotspot/cpu/ppc/ppc.ad --- openjdk-17-17.0.5+8/src/hotspot/cpu/ppc/ppc.ad 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/ppc/ppc.ad 2023-01-10 13:21:55.000000000 +0000 @@ -6834,6 +6834,9 @@ n2->_opnds[2] = op_dst; n2->_bottom_type = _bottom_type; + assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); + ra_->set_oop(n2, true); + ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -3757,6 +3757,7 @@ Register d = R6_ARG4; // destination address Register dp = R7_ARG5; // destination offset Register isURL = R8_ARG6; // boolean, if non-zero indicates use of RFC 4648 base64url encoding + Register isMIME = R9_ARG7; // boolean, if non-zero indicates use of RFC 2045 MIME encoding - not used // Local variables Register const_ptr = R9; // used for loading constants diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/s390/assembler_s390.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/s390/assembler_s390.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/s390/assembler_s390.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/s390/assembler_s390.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -139,7 +139,7 @@ return inverse_cc; } -#ifdef ASSERT +#ifndef PRODUCT void Assembler::print_dbg_msg(outputStream* out, unsigned long inst, const char* msg, int ilen) { out->flush(); switch (ilen) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/s390/interp_masm_s390.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/s390/interp_masm_s390.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/s390/interp_masm_s390.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/s390/interp_masm_s390.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -166,7 +166,7 @@ // Accessors to the template interpreter state. - void asm_assert_ijava_state_magic(Register tmp) PRODUCT_RETURN; + void asm_assert_ijava_state_magic(Register tmp) NOT_DEBUG_RETURN; void save_bcp(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/assembler_x86.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/assembler_x86.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/assembler_x86.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/assembler_x86.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -3758,6 +3758,15 @@ emit_int16((unsigned char)0x8D, (0xC0 | encode)); } +void Assembler::vpermb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { + assert(VM_Version::supports_avx512_vbmi(), ""); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8((unsigned char)0x8D); + emit_operand(dst, src); +} + void Assembler::vpermw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(vector_len == AVX_128bit ? VM_Version::supports_avx512vlbw() : vector_len == AVX_256bit ? VM_Version::supports_avx512vlbw() : @@ -3830,6 +3839,22 @@ emit_int16(0x76, (0xC0 | encode)); } +void Assembler::evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512_vbmi(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x7D, (0xC0 | encode)); +} + +void Assembler::evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512_vbmi(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), ctl->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0x83, (unsigned char)(0xC0 | encode)); +} + void Assembler::pause() { emit_int16((unsigned char)0xF3, (unsigned char)0x90); } @@ -4128,6 +4153,15 @@ emit_int16((unsigned char)0xD7, (0xC0 | encode)); } +void Assembler::vpmaskmovd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { + assert((VM_Version::supports_avx2() && vector_len == AVX_256bit), ""); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ true); + vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8((unsigned char)0x8C); + emit_operand(dst, src); +} + void Assembler::pextrd(Register dst, XMMRegister src, int imm8) { assert(VM_Version::supports_sse4_1(), ""); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_dq, /* no_mask_reg */ true, /* uses_vl */ false); @@ -4549,6 +4583,15 @@ emit_int16((unsigned char)0xF5, (0xC0 | encode)); } +void Assembler::vpmaddubsw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len) { +assert(vector_len == AVX_128bit? VM_Version::supports_avx() : + vector_len == AVX_256bit? VM_Version::supports_avx2() : + vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, ""); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int encode = simd_prefix_and_encode(dst, src1, src2, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16(0x04, (0xC0 | encode)); +} + void Assembler::evpdpwssd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(VM_Version::supports_evex(), ""); assert(VM_Version::supports_avx512_vnni(), "must support vnni"); @@ -4857,6 +4900,15 @@ emit_int16(0x17, (0xC0 | encode)); } +void Assembler::evptestmb(KRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512vlbw(), ""); + // Encoding: EVEX.NDS.XXX.66.0F.W0 DB /r + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0x26, (0xC0 | encode)); +} + void Assembler::punpcklbw(XMMRegister dst, Address src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); @@ -6539,6 +6591,13 @@ emit_int8((0xC0 | encode)); } +void Assembler::vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(UseAVX > 0, "requires some form of AVX"); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int16((unsigned char)0xD8, (0xC0 | encode)); +} + void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(UseAVX > 0, "requires some form of AVX"); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); @@ -6630,6 +6689,15 @@ emit_int16((unsigned char)0xF4, (0xC0 | encode)); } +void Assembler::vpmulhuw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert((vector_len == AVX_128bit && VM_Version::supports_avx()) || + (vector_len == AVX_256bit && VM_Version::supports_avx2()) || + (vector_len == AVX_512bit && VM_Version::supports_avx512bw()), ""); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int16((unsigned char)0xE4, (0xC0 | encode)); +} + void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(UseAVX > 0, "requires some form of AVX"); InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); @@ -9410,6 +9478,13 @@ emit_int16((unsigned char)0xF7, (0xC0 | encode)); } +void Assembler::shrxl(Register dst, Register src1, Register src2) { + assert(VM_Version::supports_bmi2(), ""); + InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_F2, VEX_OPCODE_0F_38, &attributes); + emit_int16((unsigned char)0xF7, (0xC0 | encode)); +} + void Assembler::shrxq(Register dst, Register src1, Register src2) { assert(VM_Version::supports_bmi2(), ""); InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/assembler_x86.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/assembler_x86.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/assembler_x86.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/assembler_x86.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1690,6 +1690,7 @@ void vpermq(XMMRegister dst, XMMRegister src, int imm8); void vpermq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpermb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void vpermb(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpermw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpermd(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpermd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); @@ -1699,6 +1700,8 @@ void vpermilpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len); void vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len); void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len); void pause(); @@ -1747,6 +1750,7 @@ void pmovmskb(Register dst, XMMRegister src); void vpmovmskb(Register dst, XMMRegister src, int vec_enc); + void vpmaskmovd(XMMRegister dst, XMMRegister nds, Address src, int vector_len); // SSE 4.1 extract void pextrd(Register dst, XMMRegister src, int imm8); @@ -1812,6 +1816,8 @@ // Multiply add void pmaddwd(XMMRegister dst, XMMRegister src); void vpmaddwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + void vpmaddubsw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len); + // Multiply add accumulate void evpdpwssd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); @@ -1879,6 +1885,8 @@ void vptest(XMMRegister dst, XMMRegister src); void vptest(XMMRegister dst, Address src); + void evptestmb(KRegister dst, XMMRegister nds, XMMRegister src, int vector_len); + // Vector compare void vptest(XMMRegister dst, XMMRegister src, int vector_len); @@ -2140,6 +2148,7 @@ void shlxl(Register dst, Register src1, Register src2); void shlxq(Register dst, Register src1, Register src2); + void shrxl(Register dst, Register src1, Register src2); void shrxq(Register dst, Register src1, Register src2); void bzhiq(Register dst, Register src1, Register src2); @@ -2244,6 +2253,7 @@ void psubw(XMMRegister dst, XMMRegister src); void psubd(XMMRegister dst, XMMRegister src); void psubq(XMMRegister dst, XMMRegister src); + void vpsubusb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); void vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); @@ -2264,6 +2274,7 @@ void vpmullw(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpmulld(XMMRegister dst, XMMRegister nds, Address src, int vector_len); void vpmullq(XMMRegister dst, XMMRegister nds, Address src, int vector_len); + void vpmulhuw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len); // Minimum of packed integers void pminsb(XMMRegister dst, XMMRegister src); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86_adler.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86_adler.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86_adler.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86_adler.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -80,7 +80,7 @@ cmpptr(data, end); jcc(Assembler::aboveEqual, SKIP_LOOP_1A); - align(32); + align32(); bind(SLOOP1A); vbroadcastf128(ydata, Address(data, 0), Assembler::AVX_256bit); addptr(data, CHUNKSIZE); @@ -178,7 +178,7 @@ movdl(rax, xb); addl(b_d, rax); - align(32); + align32(); bind(FINAL_LOOP); movzbl(rax, Address(data, 0)); //movzx eax, byte[data] addl(a_d, rax); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86_aes.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -808,11 +808,14 @@ addptr(pos, 1); addptr(used, 1); decrement(len_reg); - jmp(PRELOOP_START); + jcc(Assembler::notEqual, PRELOOP_START); bind(EXIT_PRELOOP); movl(Address(used_addr, 0), used); + cmpl(len_reg, 0); + jcc(Assembler::equal, EXIT); + // Calculate number of rounds i.e. 10, 12, 14, based on key length(128, 192, 256). movl(rounds, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1171,7 +1171,20 @@ } } +// See 8273459. Function for ensuring 64-byte alignment, intended for stubs only. +// Stub code is generated once and never copied. +// NMethods can't use this because they get copied and we can't force alignment > 32 bytes. +void MacroAssembler::align64() { + align(64, (unsigned long long) pc()); +} + +void MacroAssembler::align32() { + align(32, (unsigned long long) pc()); +} + void MacroAssembler::align(int modulus) { + // 8273459: Ensure alignment is possible with current segment alignment + assert(modulus <= CodeEntryAlignment, "Alignment must be <= CodeEntryAlignment"); align(modulus, offset()); } @@ -4051,7 +4064,7 @@ // Get super_klass value into rax (even if it was in rdi or rcx). bool pushed_rax = false, pushed_rcx = false, pushed_rdi = false; - if (super_klass != rax || UseCompressedOops) { + if (super_klass != rax) { if (!IS_A_TEMP(rax)) { push(rax); pushed_rax = true; } mov(rax, super_klass); } @@ -7114,7 +7127,7 @@ // 128 bits per each of 4 parallel streams. movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr() + 32)); - align(32); + align32(); BIND(L_fold_512b_loop); fold_128bit_crc32(xmm1, xmm0, xmm5, buf, 0); fold_128bit_crc32(xmm2, xmm0, xmm5, buf, 16); @@ -7204,7 +7217,7 @@ // Helper function for AVX 512 CRC32 // Compute CRC32 for < 256B buffers -void MacroAssembler::kernel_crc32_avx512_256B(Register crc, Register buf, Register len, Register key, Register pos, +void MacroAssembler::kernel_crc32_avx512_256B(Register crc, Register buf, Register len, Register table, Register pos, Register tmp1, Register tmp2, Label& L_barrett, Label& L_16B_reduction_loop, Label& L_get_last_two_xmms, Label& L_128_done, Label& L_cleanup) { @@ -7217,7 +7230,7 @@ jcc(Assembler::less, L_less_than_32); // if there is, load the constants - movdqu(xmm10, Address(key, 1 * 16)); //rk1 and rk2 in xmm10 + movdqu(xmm10, Address(table, 1 * 16)); //rk1 and rk2 in xmm10 movdl(xmm0, crc); // get the initial crc value movdqu(xmm7, Address(buf, pos, Address::times_1, 0 * 16)); //load the plaintext pxor(xmm7, xmm0); @@ -7244,7 +7257,7 @@ pxor(xmm7, xmm0); //xor the initial crc value addl(pos, 16); subl(len, 16); - movdqu(xmm10, Address(key, 1 * 16)); // rk1 and rk2 in xmm10 + movdqu(xmm10, Address(table, 1 * 16)); // rk1 and rk2 in xmm10 jmp(L_get_last_two_xmms); bind(L_less_than_16_left); @@ -7364,12 +7377,17 @@ * param crc register containing existing CRC (32-bit) * param buf register pointing to input byte buffer (byte*) * param len register containing number of bytes +* param table address of crc or crc32c table * param tmp1 scratch register * param tmp2 scratch register * return rax result register +* +* This routine is identical for crc32c with the exception of the precomputed constant +* table which will be passed as the table argument. The calculation steps are +* the same for both variants. */ -void MacroAssembler::kernel_crc32_avx512(Register crc, Register buf, Register len, Register key, Register tmp1, Register tmp2) { - assert_different_registers(crc, buf, len, key, tmp1, tmp2, rax); +void MacroAssembler::kernel_crc32_avx512(Register crc, Register buf, Register len, Register table, Register tmp1, Register tmp2) { + assert_different_registers(crc, buf, len, table, tmp1, tmp2, rax, r12); Label L_tail, L_tail_restore, L_tail_loop, L_exit, L_align_loop, L_aligned; Label L_fold_tail, L_fold_128b, L_fold_512b, L_fold_512b_loop, L_fold_tail_loop; @@ -7384,8 +7402,6 @@ // For EVEX with VL and BW, provide a standard mask, VL = 128 will guide the merge // context for the registers used, where all instructions below are using 128-bit mode // On EVEX without VL and BW, these instructions will all be AVX. - lea(key, ExternalAddress(StubRoutines::x86::crc_table_avx512_addr())); - notl(crc); movl(pos, 0); // check if smaller than 256B @@ -7399,7 +7415,7 @@ evmovdquq(xmm0, Address(buf, pos, Address::times_1, 0 * 64), Assembler::AVX_512bit); evmovdquq(xmm4, Address(buf, pos, Address::times_1, 1 * 64), Assembler::AVX_512bit); evpxorq(xmm0, xmm0, xmm10, Assembler::AVX_512bit); - evbroadcasti32x4(xmm10, Address(key, 2 * 16), Assembler::AVX_512bit); //zmm10 has rk3 and rk4 + evbroadcasti32x4(xmm10, Address(table, 2 * 16), Assembler::AVX_512bit); //zmm10 has rk3 and rk4 subl(len, 256); cmpl(len, 256); @@ -7407,7 +7423,7 @@ evmovdquq(xmm7, Address(buf, pos, Address::times_1, 2 * 64), Assembler::AVX_512bit); evmovdquq(xmm8, Address(buf, pos, Address::times_1, 3 * 64), Assembler::AVX_512bit); - evbroadcasti32x4(xmm16, Address(key, 0 * 16), Assembler::AVX_512bit); //zmm16 has rk-1 and rk-2 + evbroadcasti32x4(xmm16, Address(table, 0 * 16), Assembler::AVX_512bit); //zmm16 has rk-1 and rk-2 subl(len, 256); bind(L_fold_256_B_loop); @@ -7453,8 +7469,8 @@ // at this point, the buffer pointer is pointing at the last y Bytes of the buffer, where 0 <= y < 128 // the 128B of folded data is in 8 of the xmm registers : xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 bind(L_fold_128_B_register); - evmovdquq(xmm16, Address(key, 5 * 16), Assembler::AVX_512bit); // multiply by rk9-rk16 - evmovdquq(xmm11, Address(key, 9 * 16), Assembler::AVX_512bit); // multiply by rk17-rk20, rk1,rk2, 0,0 + evmovdquq(xmm16, Address(table, 5 * 16), Assembler::AVX_512bit); // multiply by rk9-rk16 + evmovdquq(xmm11, Address(table, 9 * 16), Assembler::AVX_512bit); // multiply by rk17-rk20, rk1,rk2, 0,0 evpclmulqdq(xmm1, xmm0, xmm16, 0x01, Assembler::AVX_512bit); evpclmulqdq(xmm2, xmm0, xmm16, 0x10, Assembler::AVX_512bit); // save last that has no multiplicand @@ -7463,7 +7479,7 @@ evpclmulqdq(xmm5, xmm4, xmm11, 0x01, Assembler::AVX_512bit); evpclmulqdq(xmm6, xmm4, xmm11, 0x10, Assembler::AVX_512bit); // Needed later in reduction loop - movdqu(xmm10, Address(key, 1 * 16)); + movdqu(xmm10, Address(table, 1 * 16)); vpternlogq(xmm1, 0x96, xmm2, xmm5, Assembler::AVX_512bit); // xor ABC vpternlogq(xmm1, 0x96, xmm6, xmm7, Assembler::AVX_512bit); // xor ABC @@ -7479,7 +7495,7 @@ jcc(Assembler::less, L_final_reduction_for_128); bind(L_16B_reduction_loop); - vpclmulqdq(xmm8, xmm7, xmm10, 0x1); + vpclmulqdq(xmm8, xmm7, xmm10, 0x01); vpclmulqdq(xmm7, xmm7, xmm10, 0x10); vpxor(xmm7, xmm7, xmm8, Assembler::AVX_128bit); movdqu(xmm0, Address(buf, pos, Address::times_1, 0 * 16)); @@ -7510,14 +7526,14 @@ vpshufb(xmm2, xmm2, xmm0, Assembler::AVX_128bit); blendvpb(xmm2, xmm2, xmm1, xmm0, Assembler::AVX_128bit); - vpclmulqdq(xmm8, xmm7, xmm10, 0x1); + vpclmulqdq(xmm8, xmm7, xmm10, 0x01); vpclmulqdq(xmm7, xmm7, xmm10, 0x10); vpxor(xmm7, xmm7, xmm8, Assembler::AVX_128bit); vpxor(xmm7, xmm7, xmm2, Assembler::AVX_128bit); bind(L_128_done); // compute crc of a 128-bit value - movdqu(xmm10, Address(key, 3 * 16)); + movdqu(xmm10, Address(table, 3 * 16)); movdqu(xmm0, xmm7); // 64b fold @@ -7533,14 +7549,14 @@ jmp(L_barrett); bind(L_less_than_256); - kernel_crc32_avx512_256B(crc, buf, len, key, pos, tmp1, tmp2, L_barrett, L_16B_reduction_loop, L_get_last_two_xmms, L_128_done, L_cleanup); + kernel_crc32_avx512_256B(crc, buf, len, table, pos, tmp1, tmp2, L_barrett, L_16B_reduction_loop, L_get_last_two_xmms, L_128_done, L_cleanup); //barrett reduction bind(L_barrett); vpand(xmm7, xmm7, ExternalAddress(StubRoutines::x86::crc_by128_masks_avx512_addr() + 1 * 16), Assembler::AVX_128bit, tmp2); movdqu(xmm1, xmm7); movdqu(xmm2, xmm7); - movdqu(xmm10, Address(key, 4 * 16)); + movdqu(xmm10, Address(table, 4 * 16)); pclmulqdq(xmm7, xmm10, 0x0); pxor(xmm7, xmm2); @@ -7552,7 +7568,6 @@ pextrd(crc, xmm7, 2); bind(L_cleanup); - notl(crc); // ~c addptr(rsp, 16 * 2 + 8); pop(r12); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/macroAssembler_x86.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -194,6 +194,8 @@ void incrementq(AddressLiteral dst); // Alignment + void align32(); + void align64(); void align(int modulus); void align(int modulus, int target); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/matcher_x86.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/matcher_x86.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/matcher_x86.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/matcher_x86.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -178,11 +178,7 @@ // Some microarchitectures have mask registers used on vectors static const bool has_predicated_vectors(void) { - bool ret_value = false; - if (UseAVX > 2) { - ret_value = VM_Version::supports_avx512vl(); - } - return ret_value; + return VM_Version::supports_evex(); } // true means we have fast l2f convers diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -2998,7 +2998,7 @@ } address generate_upper_word_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "upper_word_mask"); address start = __ pc(); __ emit_data(0x00000000, relocInfo::none, 0); @@ -3009,7 +3009,7 @@ } address generate_shuffle_byte_flip_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "shuffle_byte_flip_mask"); address start = __ pc(); __ emit_data(0x0c0d0e0f, relocInfo::none, 0); @@ -3068,7 +3068,7 @@ } address generate_pshuffle_byte_flip_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask"); address start = __ pc(); __ emit_data(0x00010203, relocInfo::none, 0); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1484,7 +1484,7 @@ __ subq(temp1, loop_size[shift]); // Main loop with aligned copy block size of 192 bytes at 32 byte granularity. - __ align(32); + __ align32(); __ BIND(L_main_loop); __ copy64_avx(to, from, temp4, xmm1, false, shift, 0); __ copy64_avx(to, from, temp4, xmm1, false, shift, 64); @@ -1551,7 +1551,7 @@ // Main loop with aligned copy block size of 192 bytes at // 64 byte copy granularity. - __ align(32); + __ align32(); __ BIND(L_main_loop_64bytes); __ copy64_avx(to, from, temp4, xmm1, false, shift, 0 , true); __ copy64_avx(to, from, temp4, xmm1, false, shift, 64, true); @@ -1691,7 +1691,7 @@ __ BIND(L_main_pre_loop); // Main loop with aligned copy block size of 192 bytes at 32 byte granularity. - __ align(32); + __ align32(); __ BIND(L_main_loop); __ copy64_avx(to, from, temp1, xmm1, true, shift, -64); __ copy64_avx(to, from, temp1, xmm1, true, shift, -128); @@ -1724,7 +1724,7 @@ // Main loop with aligned copy block size of 192 bytes at // 64 byte copy granularity. - __ align(32); + __ align32(); __ BIND(L_main_loop_64bytes); __ copy64_avx(to, from, temp1, xmm1, true, shift, -64 , true); __ copy64_avx(to, from, temp1, xmm1, true, shift, -128, true); @@ -4194,7 +4194,7 @@ } address generate_upper_word_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "upper_word_mask"); address start = __ pc(); __ emit_data64(0x0000000000000000, relocInfo::none); @@ -4203,7 +4203,7 @@ } address generate_shuffle_byte_flip_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "shuffle_byte_flip_mask"); address start = __ pc(); __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none); @@ -4248,7 +4248,7 @@ } address generate_pshuffle_byte_flip_mask() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask"); address start = __ pc(); __ emit_data64(0x0405060700010203, relocInfo::none); @@ -4274,7 +4274,7 @@ //Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. address generate_pshuffle_byte_flip_mask_sha512() { - __ align(32); + __ align32(); StubCodeMark mark(this, "StubRoutines", "pshuffle_byte_flip_mask_sha512"); address start = __ pc(); if (VM_Version::supports_avx2()) { @@ -4370,7 +4370,7 @@ // This mask is used for incrementing counter value(linc0, linc4, etc.) address counter_mask_addr() { - __ align(64); + __ align64(); StubCodeMark mark(this, "StubRoutines", "counter_mask_addr"); address start = __ pc(); __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none);//lbswapmask @@ -5287,164 +5287,691 @@ return start; } - //base64 character set - address base64_charset_addr() { + address base64_shuffle_addr() + { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "shuffle_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x0405030401020001, relocInfo::none); + __ emit_data64(0x0a0b090a07080607, relocInfo::none); + __ emit_data64(0x10110f100d0e0c0d, relocInfo::none); + __ emit_data64(0x1617151613141213, relocInfo::none); + __ emit_data64(0x1c1d1b1c191a1819, relocInfo::none); + __ emit_data64(0x222321221f201e1f, relocInfo::none); + __ emit_data64(0x2829272825262425, relocInfo::none); + __ emit_data64(0x2e2f2d2e2b2c2a2b, relocInfo::none); + return start; + } + + address base64_avx2_shuffle_addr() + { + __ align32(); + StubCodeMark mark(this, "StubRoutines", "avx2_shuffle_base64"); + address start = __ pc(); + __ emit_data64(0x0809070805060405, relocInfo::none); + __ emit_data64(0x0e0f0d0e0b0c0a0b, relocInfo::none); + __ emit_data64(0x0405030401020001, relocInfo::none); + __ emit_data64(0x0a0b090a07080607, relocInfo::none); + return start; + } + + address base64_avx2_input_mask_addr() + { + __ align32(); + StubCodeMark mark(this, "StubRoutines", "avx2_input_mask_base64"); + address start = __ pc(); + __ emit_data64(0x8000000000000000, relocInfo::none); + __ emit_data64(0x8000000080000000, relocInfo::none); + __ emit_data64(0x8000000080000000, relocInfo::none); + __ emit_data64(0x8000000080000000, relocInfo::none); + return start; + } + + address base64_avx2_lut_addr() + { + __ align32(); + StubCodeMark mark(this, "StubRoutines", "avx2_lut_base64"); + address start = __ pc(); + __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); + __ emit_data64(0x0000f0edfcfcfcfc, relocInfo::none); + __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); + __ emit_data64(0x0000f0edfcfcfcfc, relocInfo::none); + + // URL LUT + __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); + __ emit_data64(0x000020effcfcfcfc, relocInfo::none); + __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); + __ emit_data64(0x000020effcfcfcfc, relocInfo::none); + return start; + } + + address base64_encoding_table_addr() + { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "encoding_table_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x4847464544434241, relocInfo::none); + __ emit_data64(0x504f4e4d4c4b4a49, relocInfo::none); + __ emit_data64(0x5857565554535251, relocInfo::none); + __ emit_data64(0x6665646362615a59, relocInfo::none); + __ emit_data64(0x6e6d6c6b6a696867, relocInfo::none); + __ emit_data64(0x767574737271706f, relocInfo::none); + __ emit_data64(0x333231307a797877, relocInfo::none); + __ emit_data64(0x2f2b393837363534, relocInfo::none); + + // URL table + __ emit_data64(0x4847464544434241, relocInfo::none); + __ emit_data64(0x504f4e4d4c4b4a49, relocInfo::none); + __ emit_data64(0x5857565554535251, relocInfo::none); + __ emit_data64(0x6665646362615a59, relocInfo::none); + __ emit_data64(0x6e6d6c6b6a696867, relocInfo::none); + __ emit_data64(0x767574737271706f, relocInfo::none); + __ emit_data64(0x333231307a797877, relocInfo::none); + __ emit_data64(0x5f2d393837363534, relocInfo::none); + return start; + } + + // Code for generating Base64 encoding. + // Intrinsic function prototype in Base64.java: + // private void encodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, + // boolean isURL) { + address generate_base64_encodeBlock() + { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "base64_charset"); + StubCodeMark mark(this, "StubRoutines", "implEncode"); address start = __ pc(); - __ emit_data64(0x0000004200000041, relocInfo::none); - __ emit_data64(0x0000004400000043, relocInfo::none); - __ emit_data64(0x0000004600000045, relocInfo::none); - __ emit_data64(0x0000004800000047, relocInfo::none); - __ emit_data64(0x0000004a00000049, relocInfo::none); - __ emit_data64(0x0000004c0000004b, relocInfo::none); - __ emit_data64(0x0000004e0000004d, relocInfo::none); - __ emit_data64(0x000000500000004f, relocInfo::none); - __ emit_data64(0x0000005200000051, relocInfo::none); - __ emit_data64(0x0000005400000053, relocInfo::none); - __ emit_data64(0x0000005600000055, relocInfo::none); - __ emit_data64(0x0000005800000057, relocInfo::none); - __ emit_data64(0x0000005a00000059, relocInfo::none); - __ emit_data64(0x0000006200000061, relocInfo::none); - __ emit_data64(0x0000006400000063, relocInfo::none); - __ emit_data64(0x0000006600000065, relocInfo::none); - __ emit_data64(0x0000006800000067, relocInfo::none); - __ emit_data64(0x0000006a00000069, relocInfo::none); - __ emit_data64(0x0000006c0000006b, relocInfo::none); - __ emit_data64(0x0000006e0000006d, relocInfo::none); - __ emit_data64(0x000000700000006f, relocInfo::none); - __ emit_data64(0x0000007200000071, relocInfo::none); - __ emit_data64(0x0000007400000073, relocInfo::none); - __ emit_data64(0x0000007600000075, relocInfo::none); - __ emit_data64(0x0000007800000077, relocInfo::none); - __ emit_data64(0x0000007a00000079, relocInfo::none); - __ emit_data64(0x0000003100000030, relocInfo::none); - __ emit_data64(0x0000003300000032, relocInfo::none); - __ emit_data64(0x0000003500000034, relocInfo::none); - __ emit_data64(0x0000003700000036, relocInfo::none); - __ emit_data64(0x0000003900000038, relocInfo::none); - __ emit_data64(0x0000002f0000002b, relocInfo::none); - return start; - } + __ enter(); - //base64 url character set - address base64url_charset_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "base64url_charset"); - address start = __ pc(); - __ emit_data64(0x0000004200000041, relocInfo::none); - __ emit_data64(0x0000004400000043, relocInfo::none); - __ emit_data64(0x0000004600000045, relocInfo::none); - __ emit_data64(0x0000004800000047, relocInfo::none); - __ emit_data64(0x0000004a00000049, relocInfo::none); - __ emit_data64(0x0000004c0000004b, relocInfo::none); - __ emit_data64(0x0000004e0000004d, relocInfo::none); - __ emit_data64(0x000000500000004f, relocInfo::none); - __ emit_data64(0x0000005200000051, relocInfo::none); - __ emit_data64(0x0000005400000053, relocInfo::none); - __ emit_data64(0x0000005600000055, relocInfo::none); - __ emit_data64(0x0000005800000057, relocInfo::none); - __ emit_data64(0x0000005a00000059, relocInfo::none); - __ emit_data64(0x0000006200000061, relocInfo::none); - __ emit_data64(0x0000006400000063, relocInfo::none); - __ emit_data64(0x0000006600000065, relocInfo::none); - __ emit_data64(0x0000006800000067, relocInfo::none); - __ emit_data64(0x0000006a00000069, relocInfo::none); - __ emit_data64(0x0000006c0000006b, relocInfo::none); - __ emit_data64(0x0000006e0000006d, relocInfo::none); - __ emit_data64(0x000000700000006f, relocInfo::none); - __ emit_data64(0x0000007200000071, relocInfo::none); - __ emit_data64(0x0000007400000073, relocInfo::none); - __ emit_data64(0x0000007600000075, relocInfo::none); - __ emit_data64(0x0000007800000077, relocInfo::none); - __ emit_data64(0x0000007a00000079, relocInfo::none); - __ emit_data64(0x0000003100000030, relocInfo::none); - __ emit_data64(0x0000003300000032, relocInfo::none); - __ emit_data64(0x0000003500000034, relocInfo::none); - __ emit_data64(0x0000003700000036, relocInfo::none); - __ emit_data64(0x0000003900000038, relocInfo::none); - __ emit_data64(0x0000005f0000002d, relocInfo::none); + // Save callee-saved registers before using them + __ push(r12); + __ push(r13); + __ push(r14); + __ push(r15); - return start; - } + // arguments + const Register source = c_rarg0; // Source Array + const Register start_offset = c_rarg1; // start offset + const Register end_offset = c_rarg2; // end offset + const Register dest = c_rarg3; // destination array - address base64_bswap_mask_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "bswap_mask_base64"); - address start = __ pc(); - __ emit_data64(0x0504038002010080, relocInfo::none); - __ emit_data64(0x0b0a098008070680, relocInfo::none); - __ emit_data64(0x0908078006050480, relocInfo::none); - __ emit_data64(0x0f0e0d800c0b0a80, relocInfo::none); - __ emit_data64(0x0605048003020180, relocInfo::none); - __ emit_data64(0x0c0b0a8009080780, relocInfo::none); - __ emit_data64(0x0504038002010080, relocInfo::none); - __ emit_data64(0x0b0a098008070680, relocInfo::none); +#ifndef _WIN64 + const Register dp = c_rarg4; // Position for writing to dest array + const Register isURL = c_rarg5; // Base64 or URL character set +#else + const Address dp_mem(rbp, 6 * wordSize); // length is on stack on Win64 + const Address isURL_mem(rbp, 7 * wordSize); + const Register isURL = r10; // pick the volatile windows register + const Register dp = r12; + __ movl(dp, dp_mem); + __ movl(isURL, isURL_mem); +#endif + + const Register length = r14; + const Register encode_table = r13; + Label L_process3, L_exit, L_processdata, L_vbmiLoop, L_not512, L_32byteLoop; + + // calculate length from offsets + __ movl(length, end_offset); + __ subl(length, start_offset); + __ cmpl(length, 0); + __ jcc(Assembler::lessEqual, L_exit); + + // Code for 512-bit VBMI encoding. Encodes 48 input bytes into 64 + // output bytes. We read 64 input bytes and ignore the last 16, so be + // sure not to read past the end of the input buffer. + if (VM_Version::supports_avx512_vbmi()) { + __ cmpl(length, 64); // Do not overrun input buffer. + __ jcc(Assembler::below, L_not512); + + __ shll(isURL, 6); // index into decode table based on isURL + __ lea(encode_table, ExternalAddress(StubRoutines::x86::base64_encoding_table_addr())); + __ addptr(encode_table, isURL); + __ shrl(isURL, 6); // restore isURL + + __ mov64(rax, 0x3036242a1016040aull); // Shifts + __ evmovdquq(xmm3, ExternalAddress(StubRoutines::x86::base64_shuffle_addr()), Assembler::AVX_512bit, r15); + __ evmovdquq(xmm2, Address(encode_table, 0), Assembler::AVX_512bit); + __ evpbroadcastq(xmm1, rax, Assembler::AVX_512bit); + + __ align32(); + __ BIND(L_vbmiLoop); + + __ vpermb(xmm0, xmm3, Address(source, start_offset), Assembler::AVX_512bit); + __ subl(length, 48); + + // Put the input bytes into the proper lanes for writing, then + // encode them. + __ evpmultishiftqb(xmm0, xmm1, xmm0, Assembler::AVX_512bit); + __ vpermb(xmm0, xmm0, xmm2, Assembler::AVX_512bit); + + // Write to destination + __ evmovdquq(Address(dest, dp), xmm0, Assembler::AVX_512bit); + + __ addptr(dest, 64); + __ addptr(source, 48); + __ cmpl(length, 64); + __ jcc(Assembler::aboveEqual, L_vbmiLoop); + + __ vzeroupper(); + } + + __ BIND(L_not512); + if (VM_Version::supports_avx2() + && VM_Version::supports_avx512vlbw()) { + /* + ** This AVX2 encoder is based off the paper at: + ** https://dl.acm.org/doi/10.1145/3132709 + ** + ** We use AVX2 SIMD instructions to encode 24 bytes into 32 + ** output bytes. + ** + */ + // Lengths under 32 bytes are done with scalar routine + __ cmpl(length, 31); + __ jcc(Assembler::belowEqual, L_process3); + + // Set up supporting constant table data + __ vmovdqu(xmm9, ExternalAddress(StubRoutines::x86::base64_avx2_shuffle_addr()), rax); + // 6-bit mask for 2nd and 4th (and multiples) 6-bit values + __ movl(rax, 0x0fc0fc00); + __ vmovdqu(xmm1, ExternalAddress(StubRoutines::x86::base64_avx2_input_mask_addr()), rax); + __ evpbroadcastd(xmm8, rax, Assembler::AVX_256bit); + + // Multiplication constant for "shifting" right by 6 and 10 + // bits + __ movl(rax, 0x04000040); + + __ subl(length, 24); + __ evpbroadcastd(xmm7, rax, Assembler::AVX_256bit); + + // For the first load, we mask off reading of the first 4 + // bytes into the register. This is so we can get 4 3-byte + // chunks into each lane of the register, avoiding having to + // handle end conditions. We then shuffle these bytes into a + // specific order so that manipulation is easier. + // + // The initial read loads the XMM register like this: + // + // Lower 128-bit lane: + // +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + // | XX | XX | XX | XX | A0 | A1 | A2 | B0 | B1 | B2 | C0 | C1 + // | C2 | D0 | D1 | D2 | + // +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + // + // Upper 128-bit lane: + // +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + // | E0 | E1 | E2 | F0 | F1 | F2 | G0 | G1 | G2 | H0 | H1 | H2 + // | XX | XX | XX | XX | + // +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ + // + // Where A0 is the first input byte, B0 is the fourth, etc. + // The alphabetical significance denotes the 3 bytes to be + // consumed and encoded into 4 bytes. + // + // We then shuffle the register so each 32-bit word contains + // the sequence: + // A1 A0 A2 A1, B1, B0, B2, B1, etc. + // Each of these byte sequences are then manipulated into 4 + // 6-bit values ready for encoding. + // + // If we focus on one set of 3-byte chunks, changing the + // nomenclature such that A0 => a, A1 => b, and A2 => c, we + // shuffle such that each 24-bit chunk contains: + // + // b7 b6 b5 b4 b3 b2 b1 b0 | a7 a6 a5 a4 a3 a2 a1 a0 | c7 c6 + // c5 c4 c3 c2 c1 c0 | b7 b6 b5 b4 b3 b2 b1 b0 + // Explain this step. + // b3 b2 b1 b0 c5 c4 c3 c2 | c1 c0 d5 d4 d3 d2 d1 d0 | a5 a4 + // a3 a2 a1 a0 b5 b4 | b3 b2 b1 b0 c5 c4 c3 c2 + // + // W first and off all but bits 4-9 and 16-21 (c5..c0 and + // a5..a0) and shift them using a vector multiplication + // operation (vpmulhuw) which effectively shifts c right by 6 + // bits and a right by 10 bits. We similarly mask bits 10-15 + // (d5..d0) and 22-27 (b5..b0) and shift them left by 8 and 4 + // bits respecively. This is done using vpmullw. We end up + // with 4 6-bit values, thus splitting the 3 input bytes, + // ready for encoding: + // 0 0 d5..d0 0 0 c5..c0 0 0 b5..b0 0 0 a5..a0 + // + // For translation, we recognize that there are 5 distinct + // ranges of legal Base64 characters as below: + // + // +-------------+-------------+------------+ + // | 6-bit value | ASCII range | offset | + // +-------------+-------------+------------+ + // | 0..25 | A..Z | 65 | + // | 26..51 | a..z | 71 | + // | 52..61 | 0..9 | -4 | + // | 62 | + or - | -19 or -17 | + // | 63 | / or _ | -16 or 32 | + // +-------------+-------------+------------+ + // + // We note that vpshufb does a parallel lookup in a + // destination register using the lower 4 bits of bytes from a + // source register. If we use a saturated subtraction and + // subtract 51 from each 6-bit value, bytes from [0,51] + // saturate to 0, and [52,63] map to a range of [1,12]. We + // distinguish the [0,25] and [26,51] ranges by assigning a + // value of 13 for all 6-bit values less than 26. We end up + // with: + // + // +-------------+-------------+------------+ + // | 6-bit value | Reduced | offset | + // +-------------+-------------+------------+ + // | 0..25 | 13 | 65 | + // | 26..51 | 0 | 71 | + // | 52..61 | 0..9 | -4 | + // | 62 | 11 | -19 or -17 | + // | 63 | 12 | -16 or 32 | + // +-------------+-------------+------------+ + // + // We then use a final vpshufb to add the appropriate offset, + // translating the bytes. + // + // Load input bytes - only 28 bytes. Mask the first load to + // not load into the full register. + __ vpmaskmovd(xmm1, xmm1, Address(source, start_offset, Address::times_1, -4), Assembler::AVX_256bit); + + // Move 3-byte chunks of input (12 bytes) into 16 bytes, + // ordering by: + // 1, 0, 2, 1; 4, 3, 5, 4; etc. This groups 6-bit chunks + // for easy masking + __ vpshufb(xmm1, xmm1, xmm9, Assembler::AVX_256bit); + + __ addl(start_offset, 24); + + // Load masking register for first and third (and multiples) + // 6-bit values. + __ movl(rax, 0x003f03f0); + __ evpbroadcastd(xmm6, rax, Assembler::AVX_256bit); + // Multiplication constant for "shifting" left by 4 and 8 bits + __ movl(rax, 0x01000010); + __ evpbroadcastd(xmm5, rax, Assembler::AVX_256bit); + + // Isolate 6-bit chunks of interest + __ vpand(xmm0, xmm8, xmm1, Assembler::AVX_256bit); + + // Load constants for encoding + __ movl(rax, 0x19191919); + __ evpbroadcastd(xmm3, rax, Assembler::AVX_256bit); + __ movl(rax, 0x33333333); + __ evpbroadcastd(xmm4, rax, Assembler::AVX_256bit); + + // Shift output bytes 0 and 2 into proper lanes + __ vpmulhuw(xmm2, xmm0, xmm7, Assembler::AVX_256bit); + + // Mask and shift output bytes 1 and 3 into proper lanes and + // combine + __ vpand(xmm0, xmm6, xmm1, Assembler::AVX_256bit); + __ vpmullw(xmm0, xmm5, xmm0, Assembler::AVX_256bit); + __ vpor(xmm0, xmm0, xmm2, Assembler::AVX_256bit); + + // Find out which are 0..25. This indicates which input + // values fall in the range of 'A'-'Z', which require an + // additional offset (see comments above) + __ vpcmpgtb(xmm2, xmm0, xmm3, Assembler::AVX_256bit); + __ vpsubusb(xmm1, xmm0, xmm4, Assembler::AVX_256bit); + __ vpsubb(xmm1, xmm1, xmm2, Assembler::AVX_256bit); + + // Load the proper lookup table + __ lea(r11, ExternalAddress(StubRoutines::x86::base64_avx2_lut_addr())); + __ movl(r15, isURL); + __ shll(r15, 5); + __ vmovdqu(xmm2, Address(r11, r15)); + + // Shuffle the offsets based on the range calculation done + // above. This allows us to add the correct offset to the + // 6-bit value corresponding to the range documented above. + __ vpshufb(xmm1, xmm2, xmm1, Assembler::AVX_256bit); + __ vpaddb(xmm0, xmm1, xmm0, Assembler::AVX_256bit); + + // Store the encoded bytes + __ vmovdqu(Address(dest, dp), xmm0); + __ addl(dp, 32); + + __ cmpl(length, 31); + __ jcc(Assembler::belowEqual, L_process3); + + __ align32(); + __ BIND(L_32byteLoop); + + // Get next 32 bytes + __ vmovdqu(xmm1, Address(source, start_offset, Address::times_1, -4)); + + __ subl(length, 24); + __ addl(start_offset, 24); + + // This logic is identical to the above, with only constant + // register loads removed. Shuffle the input, mask off 6-bit + // chunks, shift them into place, then add the offset to + // encode. + __ vpshufb(xmm1, xmm1, xmm9, Assembler::AVX_256bit); + + __ vpand(xmm0, xmm8, xmm1, Assembler::AVX_256bit); + __ vpmulhuw(xmm10, xmm0, xmm7, Assembler::AVX_256bit); + __ vpand(xmm0, xmm6, xmm1, Assembler::AVX_256bit); + __ vpmullw(xmm0, xmm5, xmm0, Assembler::AVX_256bit); + __ vpor(xmm0, xmm0, xmm10, Assembler::AVX_256bit); + __ vpcmpgtb(xmm10, xmm0, xmm3, Assembler::AVX_256bit); + __ vpsubusb(xmm1, xmm0, xmm4, Assembler::AVX_256bit); + __ vpsubb(xmm1, xmm1, xmm10, Assembler::AVX_256bit); + __ vpshufb(xmm1, xmm2, xmm1, Assembler::AVX_256bit); + __ vpaddb(xmm0, xmm1, xmm0, Assembler::AVX_256bit); + + // Store the encoded bytes + __ vmovdqu(Address(dest, dp), xmm0); + __ addl(dp, 32); + + __ cmpl(length, 31); + __ jcc(Assembler::above, L_32byteLoop); + + __ BIND(L_process3); + __ vzeroupper(); + } else { + __ BIND(L_process3); + } + __ cmpl(length, 3); + __ jcc(Assembler::below, L_exit); + + // Load the encoding table based on isURL + __ lea(r11, ExternalAddress(StubRoutines::x86::base64_encoding_table_addr())); + __ movl(r15, isURL); + __ shll(r15, 6); + __ addptr(r11, r15); + + __ BIND(L_processdata); + + // Load 3 bytes + __ load_unsigned_byte(r15, Address(source, start_offset)); + __ load_unsigned_byte(r10, Address(source, start_offset, Address::times_1, 1)); + __ load_unsigned_byte(r13, Address(source, start_offset, Address::times_1, 2)); + + // Build a 32-bit word with bytes 1, 2, 0, 1 + __ movl(rax, r10); + __ shll(r10, 24); + __ orl(rax, r10); + + __ subl(length, 3); + + __ shll(r15, 8); + __ shll(r13, 16); + __ orl(rax, r15); + + __ addl(start_offset, 3); + + __ orl(rax, r13); + // At this point, rax contains | byte1 | byte2 | byte0 | byte1 + // r13 has byte2 << 16 - need low-order 6 bits to translate. + // This translated byte is the fourth output byte. + __ shrl(r13, 16); + __ andl(r13, 0x3f); + + // The high-order 6 bits of r15 (byte0) is translated. + // The translated byte is the first output byte. + __ shrl(r15, 10); + + __ load_unsigned_byte(r13, Address(r11, r13)); + __ load_unsigned_byte(r15, Address(r11, r15)); + + __ movb(Address(dest, dp, Address::times_1, 3), r13); + + // Extract high-order 4 bits of byte1 and low-order 2 bits of byte0. + // This translated byte is the second output byte. + __ shrl(rax, 4); + __ movl(r10, rax); + __ andl(rax, 0x3f); + + __ movb(Address(dest, dp, Address::times_1, 0), r15); + + __ load_unsigned_byte(rax, Address(r11, rax)); + + // Extract low-order 2 bits of byte1 and high-order 4 bits of byte2. + // This translated byte is the third output byte. + __ shrl(r10, 18); + __ andl(r10, 0x3f); + + __ load_unsigned_byte(r10, Address(r11, r10)); + + __ movb(Address(dest, dp, Address::times_1, 1), rax); + __ movb(Address(dest, dp, Address::times_1, 2), r10); + + __ addl(dp, 4); + __ cmpl(length, 3); + __ jcc(Assembler::aboveEqual, L_processdata); + + __ BIND(L_exit); + __ pop(r15); + __ pop(r14); + __ pop(r13); + __ pop(r12); + __ leave(); + __ ret(0); return start; } - address base64_right_shift_mask_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "right_shift_mask"); - address start = __ pc(); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - __ emit_data64(0x0006000400020000, relocInfo::none); - + // base64 AVX512vbmi tables + address base64_vbmi_lookup_lo_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "lookup_lo_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x3f8080803e808080, relocInfo::none); + __ emit_data64(0x3b3a393837363534, relocInfo::none); + __ emit_data64(0x8080808080803d3c, relocInfo::none); + return start; + } + + address base64_vbmi_lookup_hi_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "lookup_hi_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x0605040302010080, relocInfo::none); + __ emit_data64(0x0e0d0c0b0a090807, relocInfo::none); + __ emit_data64(0x161514131211100f, relocInfo::none); + __ emit_data64(0x8080808080191817, relocInfo::none); + __ emit_data64(0x201f1e1d1c1b1a80, relocInfo::none); + __ emit_data64(0x2827262524232221, relocInfo::none); + __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); + __ emit_data64(0x8080808080333231, relocInfo::none); + return start; + } + address base64_vbmi_lookup_lo_url_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "lookup_lo_base64url"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x8080808080808080, relocInfo::none); + __ emit_data64(0x80803e8080808080, relocInfo::none); + __ emit_data64(0x3b3a393837363534, relocInfo::none); + __ emit_data64(0x8080808080803d3c, relocInfo::none); + return start; + } + + address base64_vbmi_lookup_hi_url_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "lookup_hi_base64url"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x0605040302010080, relocInfo::none); + __ emit_data64(0x0e0d0c0b0a090807, relocInfo::none); + __ emit_data64(0x161514131211100f, relocInfo::none); + __ emit_data64(0x3f80808080191817, relocInfo::none); + __ emit_data64(0x201f1e1d1c1b1a80, relocInfo::none); + __ emit_data64(0x2827262524232221, relocInfo::none); + __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); + __ emit_data64(0x8080808080333231, relocInfo::none); + return start; + } + + address base64_vbmi_pack_vec_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "pack_vec_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x090a040506000102, relocInfo::none); + __ emit_data64(0x161011120c0d0e08, relocInfo::none); + __ emit_data64(0x1c1d1e18191a1415, relocInfo::none); + __ emit_data64(0x292a242526202122, relocInfo::none); + __ emit_data64(0x363031322c2d2e28, relocInfo::none); + __ emit_data64(0x3c3d3e38393a3435, relocInfo::none); + __ emit_data64(0x0000000000000000, relocInfo::none); + __ emit_data64(0x0000000000000000, relocInfo::none); return start; } - address base64_left_shift_mask_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "left_shift_mask"); - address start = __ pc(); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); - __ emit_data64(0x0000000200040000, relocInfo::none); + address base64_vbmi_join_0_1_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "join_0_1_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x090a040506000102, relocInfo::none); + __ emit_data64(0x161011120c0d0e08, relocInfo::none); + __ emit_data64(0x1c1d1e18191a1415, relocInfo::none); + __ emit_data64(0x292a242526202122, relocInfo::none); + __ emit_data64(0x363031322c2d2e28, relocInfo::none); + __ emit_data64(0x3c3d3e38393a3435, relocInfo::none); + __ emit_data64(0x494a444546404142, relocInfo::none); + __ emit_data64(0x565051524c4d4e48, relocInfo::none); + return start; + } + address base64_vbmi_join_1_2_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "join_1_2_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x1c1d1e18191a1415, relocInfo::none); + __ emit_data64(0x292a242526202122, relocInfo::none); + __ emit_data64(0x363031322c2d2e28, relocInfo::none); + __ emit_data64(0x3c3d3e38393a3435, relocInfo::none); + __ emit_data64(0x494a444546404142, relocInfo::none); + __ emit_data64(0x565051524c4d4e48, relocInfo::none); + __ emit_data64(0x5c5d5e58595a5455, relocInfo::none); + __ emit_data64(0x696a646566606162, relocInfo::none); return start; } - address base64_and_mask_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "and_mask"); - address start = __ pc(); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); - __ emit_data64(0x3f003f003f000000, relocInfo::none); + address base64_vbmi_join_2_3_addr() { + __ align64(); + StubCodeMark mark(this, "StubRoutines", "join_2_3_base64"); + address start = __ pc(); + assert(((unsigned long long)start & 0x3f) == 0, + "Alignment problem (0x%08llx)", (unsigned long long)start); + __ emit_data64(0x363031322c2d2e28, relocInfo::none); + __ emit_data64(0x3c3d3e38393a3435, relocInfo::none); + __ emit_data64(0x494a444546404142, relocInfo::none); + __ emit_data64(0x565051524c4d4e48, relocInfo::none); + __ emit_data64(0x5c5d5e58595a5455, relocInfo::none); + __ emit_data64(0x696a646566606162, relocInfo::none); + __ emit_data64(0x767071726c6d6e68, relocInfo::none); + __ emit_data64(0x7c7d7e78797a7475, relocInfo::none); return start; } - address base64_gather_mask_addr() { - __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "gather_mask"); + address base64_decoding_table_addr() { + StubCodeMark mark(this, "StubRoutines", "decoding_table_base64"); address start = __ pc(); __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0x3fffffff3effffff, relocInfo::none); + __ emit_data64(0x3b3a393837363534, relocInfo::none); + __ emit_data64(0xffffffffffff3d3c, relocInfo::none); + __ emit_data64(0x06050403020100ff, relocInfo::none); + __ emit_data64(0x0e0d0c0b0a090807, relocInfo::none); + __ emit_data64(0x161514131211100f, relocInfo::none); + __ emit_data64(0xffffffffff191817, relocInfo::none); + __ emit_data64(0x201f1e1d1c1b1aff, relocInfo::none); + __ emit_data64(0x2827262524232221, relocInfo::none); + __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); + __ emit_data64(0xffffffffff333231, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + + // URL table + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffff3effffffffff, relocInfo::none); + __ emit_data64(0x3b3a393837363534, relocInfo::none); + __ emit_data64(0xffffffffffff3d3c, relocInfo::none); + __ emit_data64(0x06050403020100ff, relocInfo::none); + __ emit_data64(0x0e0d0c0b0a090807, relocInfo::none); + __ emit_data64(0x161514131211100f, relocInfo::none); + __ emit_data64(0x3fffffffff191817, relocInfo::none); + __ emit_data64(0x201f1e1d1c1b1aff, relocInfo::none); + __ emit_data64(0x2827262524232221, relocInfo::none); + __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); + __ emit_data64(0xffffffffff333231, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); + __ emit_data64(0xffffffffffffffff, relocInfo::none); return start; } -// Code for generating Base64 encoding. + +// Code for generating Base64 decoding. +// +// Based on the article (and associated code) from https://arxiv.org/abs/1910.05109. +// // Intrinsic function prototype in Base64.java: -// private void encodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL) { - address generate_base64_encodeBlock() { +// private void decodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL, isMIME) { + address generate_base64_decodeBlock() { __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "implEncode"); + StubCodeMark mark(this, "StubRoutines", "implDecode"); address start = __ pc(); __ enter(); @@ -5453,16 +5980,19 @@ __ push(r13); __ push(r14); __ push(r15); + __ push(rbx); // arguments const Register source = c_rarg0; // Source Array const Register start_offset = c_rarg1; // start offset const Register end_offset = c_rarg2; // end offset const Register dest = c_rarg3; // destination array + const Register isMIME = rbx; #ifndef _WIN64 const Register dp = c_rarg4; // Position for writing to dest array const Register isURL = c_rarg5;// Base64 or URL character set + __ movl(isMIME, Address(rbp, 2 * wordSize)); #else const Address dp_mem(rbp, 6 * wordSize); // length is on stack on Win64 const Address isURL_mem(rbp, 7 * wordSize); @@ -5470,219 +6000,407 @@ const Register dp = r12; __ movl(dp, dp_mem); __ movl(isURL, isURL_mem); + __ movl(isMIME, Address(rbp, 8 * wordSize)); #endif + const XMMRegister lookup_lo = xmm5; + const XMMRegister lookup_hi = xmm6; + const XMMRegister errorvec = xmm7; + const XMMRegister pack16_op = xmm9; + const XMMRegister pack32_op = xmm8; + const XMMRegister input0 = xmm3; + const XMMRegister input1 = xmm20; + const XMMRegister input2 = xmm21; + const XMMRegister input3 = xmm19; + const XMMRegister join01 = xmm12; + const XMMRegister join12 = xmm11; + const XMMRegister join23 = xmm10; + const XMMRegister translated0 = xmm2; + const XMMRegister translated1 = xmm1; + const XMMRegister translated2 = xmm0; + const XMMRegister translated3 = xmm4; + + const XMMRegister merged0 = xmm2; + const XMMRegister merged1 = xmm1; + const XMMRegister merged2 = xmm0; + const XMMRegister merged3 = xmm4; + const XMMRegister merge_ab_bc0 = xmm2; + const XMMRegister merge_ab_bc1 = xmm1; + const XMMRegister merge_ab_bc2 = xmm0; + const XMMRegister merge_ab_bc3 = xmm4; + + const XMMRegister pack24bits = xmm4; + const Register length = r14; - Label L_process80, L_process32, L_process3, L_exit, L_processdata; + const Register output_size = r13; + const Register output_mask = r15; + const KRegister input_mask = k1; + + const XMMRegister input_initial_valid_b64 = xmm0; + const XMMRegister tmp = xmm10; + const XMMRegister mask = xmm0; + const XMMRegister invalid_b64 = xmm1; + + Label L_process256, L_process64, L_process64Loop, L_exit, L_processdata, L_loadURL; + Label L_continue, L_finalBit, L_padding, L_donePadding, L_bruteForce; + Label L_forceLoop, L_bottomLoop, L_checkMIME, L_exit_no_vzero; // calculate length from offsets __ movl(length, end_offset); __ subl(length, start_offset); - __ cmpl(length, 0); - __ jcc(Assembler::lessEqual, L_exit); + __ push(dest); // Save for return value calc - __ lea(r11, ExternalAddress(StubRoutines::x86::base64_charset_addr())); - // check if base64 charset(isURL=0) or base64 url charset(isURL=1) needs to be loaded - __ cmpl(isURL, 0); - __ jcc(Assembler::equal, L_processdata); - __ lea(r11, ExternalAddress(StubRoutines::x86::base64url_charset_addr())); + // If AVX512 VBMI not supported, just compile non-AVX code + if(VM_Version::supports_avx512_vbmi() && + VM_Version::supports_avx512bw()) { + __ cmpl(length, 128); // 128-bytes is break-even for AVX-512 + __ jcc(Assembler::lessEqual, L_bruteForce); + + __ cmpl(isMIME, 0); + __ jcc(Assembler::notEqual, L_bruteForce); + + // Load lookup tables based on isURL + __ cmpl(isURL, 0); + __ jcc(Assembler::notZero, L_loadURL); + + __ evmovdquq(lookup_lo, ExternalAddress(StubRoutines::x86::base64_vbmi_lookup_lo_addr()), Assembler::AVX_512bit, r13); + __ evmovdquq(lookup_hi, ExternalAddress(StubRoutines::x86::base64_vbmi_lookup_hi_addr()), Assembler::AVX_512bit, r13); + + __ BIND(L_continue); + + __ movl(r15, 0x01400140); + __ evpbroadcastd(pack16_op, r15, Assembler::AVX_512bit); + + __ movl(r15, 0x00011000); + __ evpbroadcastd(pack32_op, r15, Assembler::AVX_512bit); + + __ cmpl(length, 0xff); + __ jcc(Assembler::lessEqual, L_process64); + + // load masks required for decoding data + __ BIND(L_processdata); + __ evmovdquq(join01, ExternalAddress(StubRoutines::x86::base64_vbmi_join_0_1_addr()), Assembler::AVX_512bit,r13); + __ evmovdquq(join12, ExternalAddress(StubRoutines::x86::base64_vbmi_join_1_2_addr()), Assembler::AVX_512bit, r13); + __ evmovdquq(join23, ExternalAddress(StubRoutines::x86::base64_vbmi_join_2_3_addr()), Assembler::AVX_512bit, r13); + + __ align32(); + __ BIND(L_process256); + // Grab input data + __ evmovdquq(input0, Address(source, start_offset, Address::times_1, 0x00), Assembler::AVX_512bit); + __ evmovdquq(input1, Address(source, start_offset, Address::times_1, 0x40), Assembler::AVX_512bit); + __ evmovdquq(input2, Address(source, start_offset, Address::times_1, 0x80), Assembler::AVX_512bit); + __ evmovdquq(input3, Address(source, start_offset, Address::times_1, 0xc0), Assembler::AVX_512bit); + + // Copy the low part of the lookup table into the destination of the permutation + __ evmovdquq(translated0, lookup_lo, Assembler::AVX_512bit); + __ evmovdquq(translated1, lookup_lo, Assembler::AVX_512bit); + __ evmovdquq(translated2, lookup_lo, Assembler::AVX_512bit); + __ evmovdquq(translated3, lookup_lo, Assembler::AVX_512bit); + + // Translate the base64 input into "decoded" bytes + __ evpermt2b(translated0, input0, lookup_hi, Assembler::AVX_512bit); + __ evpermt2b(translated1, input1, lookup_hi, Assembler::AVX_512bit); + __ evpermt2b(translated2, input2, lookup_hi, Assembler::AVX_512bit); + __ evpermt2b(translated3, input3, lookup_hi, Assembler::AVX_512bit); + + // OR all of the translations together to check for errors (high-order bit of byte set) + __ vpternlogd(input0, 0xfe, input1, input2, Assembler::AVX_512bit); + + __ vpternlogd(input3, 0xfe, translated0, translated1, Assembler::AVX_512bit); + __ vpternlogd(input0, 0xfe, translated2, translated3, Assembler::AVX_512bit); + __ vpor(errorvec, input3, input0, Assembler::AVX_512bit); + + // Check if there was an error - if so, try 64-byte chunks + __ evpmovb2m(k3, errorvec, Assembler::AVX_512bit); + __ kortestql(k3, k3); + __ jcc(Assembler::notZero, L_process64); + + // The merging and shuffling happens here + // We multiply each byte pair [00dddddd | 00cccccc | 00bbbbbb | 00aaaaaa] + // Multiply [00cccccc] by 2^6 added to [00dddddd] to get [0000cccc | ccdddddd] + // The pack16_op is a vector of 0x01400140, so multiply D by 1 and C by 0x40 + __ vpmaddubsw(merge_ab_bc0, translated0, pack16_op, Assembler::AVX_512bit); + __ vpmaddubsw(merge_ab_bc1, translated1, pack16_op, Assembler::AVX_512bit); + __ vpmaddubsw(merge_ab_bc2, translated2, pack16_op, Assembler::AVX_512bit); + __ vpmaddubsw(merge_ab_bc3, translated3, pack16_op, Assembler::AVX_512bit); + + // Now do the same with packed 16-bit values. + // We start with [0000cccc | ccdddddd | 0000aaaa | aabbbbbb] + // pack32_op is 0x00011000 (2^12, 1), so this multiplies [0000aaaa | aabbbbbb] by 2^12 + // and adds [0000cccc | ccdddddd] to yield [00000000 | aaaaaabb | bbbbcccc | ccdddddd] + __ vpmaddwd(merged0, merge_ab_bc0, pack32_op, Assembler::AVX_512bit); + __ vpmaddwd(merged1, merge_ab_bc1, pack32_op, Assembler::AVX_512bit); + __ vpmaddwd(merged2, merge_ab_bc2, pack32_op, Assembler::AVX_512bit); + __ vpmaddwd(merged3, merge_ab_bc3, pack32_op, Assembler::AVX_512bit); + + // The join vectors specify which byte from which vector goes into the outputs + // One of every 4 bytes in the extended vector is zero, so we pack them into their + // final positions in the register for storing (256 bytes in, 192 bytes out) + __ evpermt2b(merged0, join01, merged1, Assembler::AVX_512bit); + __ evpermt2b(merged1, join12, merged2, Assembler::AVX_512bit); + __ evpermt2b(merged2, join23, merged3, Assembler::AVX_512bit); + + // Store result + __ evmovdquq(Address(dest, dp, Address::times_1, 0x00), merged0, Assembler::AVX_512bit); + __ evmovdquq(Address(dest, dp, Address::times_1, 0x40), merged1, Assembler::AVX_512bit); + __ evmovdquq(Address(dest, dp, Address::times_1, 0x80), merged2, Assembler::AVX_512bit); + + __ addptr(source, 0x100); + __ addptr(dest, 0xc0); + __ subl(length, 0x100); + __ cmpl(length, 64 * 4); + __ jcc(Assembler::greaterEqual, L_process256); + + // At this point, we've decoded 64 * 4 * n bytes. + // The remaining length will be <= 64 * 4 - 1. + // UNLESS there was an error decoding the first 256-byte chunk. In this + // case, the length will be arbitrarily long. + // + // Note that this will be the path for MIME-encoded strings. + + __ BIND(L_process64); + + __ evmovdquq(pack24bits, ExternalAddress(StubRoutines::x86::base64_vbmi_pack_vec_addr()), Assembler::AVX_512bit, r13); + + __ cmpl(length, 63); + __ jcc(Assembler::lessEqual, L_finalBit); + + __ mov64(rax, 0x0000ffffffffffff); + __ kmovql(k2, rax); + + __ align32(); + __ BIND(L_process64Loop); + + // Handle first 64-byte block + + __ evmovdquq(input0, Address(source, start_offset), Assembler::AVX_512bit); + __ evmovdquq(translated0, lookup_lo, Assembler::AVX_512bit); + __ evpermt2b(translated0, input0, lookup_hi, Assembler::AVX_512bit); + + __ vpor(errorvec, translated0, input0, Assembler::AVX_512bit); + + // Check for error and bomb out before updating dest + __ evpmovb2m(k3, errorvec, Assembler::AVX_512bit); + __ kortestql(k3, k3); + __ jcc(Assembler::notZero, L_exit); + + // Pack output register, selecting correct byte ordering + __ vpmaddubsw(merge_ab_bc0, translated0, pack16_op, Assembler::AVX_512bit); + __ vpmaddwd(merged0, merge_ab_bc0, pack32_op, Assembler::AVX_512bit); + __ vpermb(merged0, pack24bits, merged0, Assembler::AVX_512bit); + + __ evmovdqub(Address(dest, dp), k2, merged0, true, Assembler::AVX_512bit); + + __ subl(length, 64); + __ addptr(source, 64); + __ addptr(dest, 48); - // load masks required for encoding data - __ BIND(L_processdata); - __ movdqu(xmm16, ExternalAddress(StubRoutines::x86::base64_gather_mask_addr())); - // Set 64 bits of K register. - __ evpcmpeqb(k3, xmm16, xmm16, Assembler::AVX_512bit); - __ evmovdquq(xmm12, ExternalAddress(StubRoutines::x86::base64_bswap_mask_addr()), Assembler::AVX_256bit, r13); - __ evmovdquq(xmm13, ExternalAddress(StubRoutines::x86::base64_right_shift_mask_addr()), Assembler::AVX_512bit, r13); - __ evmovdquq(xmm14, ExternalAddress(StubRoutines::x86::base64_left_shift_mask_addr()), Assembler::AVX_512bit, r13); - __ evmovdquq(xmm15, ExternalAddress(StubRoutines::x86::base64_and_mask_addr()), Assembler::AVX_512bit, r13); - - // Vector Base64 implementation, producing 96 bytes of encoded data - __ BIND(L_process80); - __ cmpl(length, 80); - __ jcc(Assembler::below, L_process32); - __ evmovdquq(xmm0, Address(source, start_offset, Address::times_1, 0), Assembler::AVX_256bit); - __ evmovdquq(xmm1, Address(source, start_offset, Address::times_1, 24), Assembler::AVX_256bit); - __ evmovdquq(xmm2, Address(source, start_offset, Address::times_1, 48), Assembler::AVX_256bit); - - //permute the input data in such a manner that we have continuity of the source - __ vpermq(xmm3, xmm0, 148, Assembler::AVX_256bit); - __ vpermq(xmm4, xmm1, 148, Assembler::AVX_256bit); - __ vpermq(xmm5, xmm2, 148, Assembler::AVX_256bit); - - //shuffle input and group 3 bytes of data and to it add 0 as the 4th byte. - //we can deal with 12 bytes at a time in a 128 bit register - __ vpshufb(xmm3, xmm3, xmm12, Assembler::AVX_256bit); - __ vpshufb(xmm4, xmm4, xmm12, Assembler::AVX_256bit); - __ vpshufb(xmm5, xmm5, xmm12, Assembler::AVX_256bit); - - //convert byte to word. Each 128 bit register will have 6 bytes for processing - __ vpmovzxbw(xmm3, xmm3, Assembler::AVX_512bit); - __ vpmovzxbw(xmm4, xmm4, Assembler::AVX_512bit); - __ vpmovzxbw(xmm5, xmm5, Assembler::AVX_512bit); - - // Extract bits in the following pattern 6, 4+2, 2+4, 6 to convert 3, 8 bit numbers to 4, 6 bit numbers - __ evpsrlvw(xmm0, xmm3, xmm13, Assembler::AVX_512bit); - __ evpsrlvw(xmm1, xmm4, xmm13, Assembler::AVX_512bit); - __ evpsrlvw(xmm2, xmm5, xmm13, Assembler::AVX_512bit); - - __ evpsllvw(xmm3, xmm3, xmm14, Assembler::AVX_512bit); - __ evpsllvw(xmm4, xmm4, xmm14, Assembler::AVX_512bit); - __ evpsllvw(xmm5, xmm5, xmm14, Assembler::AVX_512bit); - - __ vpsrlq(xmm0, xmm0, 8, Assembler::AVX_512bit); - __ vpsrlq(xmm1, xmm1, 8, Assembler::AVX_512bit); - __ vpsrlq(xmm2, xmm2, 8, Assembler::AVX_512bit); - - __ vpsllq(xmm3, xmm3, 8, Assembler::AVX_512bit); - __ vpsllq(xmm4, xmm4, 8, Assembler::AVX_512bit); - __ vpsllq(xmm5, xmm5, 8, Assembler::AVX_512bit); - - __ vpandq(xmm3, xmm3, xmm15, Assembler::AVX_512bit); - __ vpandq(xmm4, xmm4, xmm15, Assembler::AVX_512bit); - __ vpandq(xmm5, xmm5, xmm15, Assembler::AVX_512bit); - - // Get the final 4*6 bits base64 encoding - __ vporq(xmm3, xmm3, xmm0, Assembler::AVX_512bit); - __ vporq(xmm4, xmm4, xmm1, Assembler::AVX_512bit); - __ vporq(xmm5, xmm5, xmm2, Assembler::AVX_512bit); - - // Shift - __ vpsrlq(xmm3, xmm3, 8, Assembler::AVX_512bit); - __ vpsrlq(xmm4, xmm4, 8, Assembler::AVX_512bit); - __ vpsrlq(xmm5, xmm5, 8, Assembler::AVX_512bit); - - // look up 6 bits in the base64 character set to fetch the encoding - // we are converting word to dword as gather instructions need dword indices for looking up encoding - __ vextracti64x4(xmm6, xmm3, 0); - __ vpmovzxwd(xmm0, xmm6, Assembler::AVX_512bit); - __ vextracti64x4(xmm6, xmm3, 1); - __ vpmovzxwd(xmm1, xmm6, Assembler::AVX_512bit); - - __ vextracti64x4(xmm6, xmm4, 0); - __ vpmovzxwd(xmm2, xmm6, Assembler::AVX_512bit); - __ vextracti64x4(xmm6, xmm4, 1); - __ vpmovzxwd(xmm3, xmm6, Assembler::AVX_512bit); - - __ vextracti64x4(xmm4, xmm5, 0); - __ vpmovzxwd(xmm6, xmm4, Assembler::AVX_512bit); - - __ vextracti64x4(xmm4, xmm5, 1); - __ vpmovzxwd(xmm7, xmm4, Assembler::AVX_512bit); - - __ kmovql(k2, k3); - __ evpgatherdd(xmm4, k2, Address(r11, xmm0, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm5, k2, Address(r11, xmm1, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm8, k2, Address(r11, xmm2, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm9, k2, Address(r11, xmm3, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm10, k2, Address(r11, xmm6, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm11, k2, Address(r11, xmm7, Address::times_4, 0), Assembler::AVX_512bit); - - //Down convert dword to byte. Final output is 16*6 = 96 bytes long - __ evpmovdb(Address(dest, dp, Address::times_1, 0), xmm4, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 16), xmm5, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 32), xmm8, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 48), xmm9, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 64), xmm10, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 80), xmm11, Assembler::AVX_512bit); - - __ addq(dest, 96); - __ addq(source, 72); - __ subq(length, 72); - __ jmp(L_process80); - - // Vector Base64 implementation generating 32 bytes of encoded data - __ BIND(L_process32); - __ cmpl(length, 32); - __ jcc(Assembler::below, L_process3); - __ evmovdquq(xmm0, Address(source, start_offset), Assembler::AVX_256bit); - __ vpermq(xmm0, xmm0, 148, Assembler::AVX_256bit); - __ vpshufb(xmm6, xmm0, xmm12, Assembler::AVX_256bit); - __ vpmovzxbw(xmm6, xmm6, Assembler::AVX_512bit); - __ evpsrlvw(xmm2, xmm6, xmm13, Assembler::AVX_512bit); - __ evpsllvw(xmm3, xmm6, xmm14, Assembler::AVX_512bit); - - __ vpsrlq(xmm2, xmm2, 8, Assembler::AVX_512bit); - __ vpsllq(xmm3, xmm3, 8, Assembler::AVX_512bit); - __ vpandq(xmm3, xmm3, xmm15, Assembler::AVX_512bit); - __ vporq(xmm1, xmm2, xmm3, Assembler::AVX_512bit); - __ vpsrlq(xmm1, xmm1, 8, Assembler::AVX_512bit); - __ vextracti64x4(xmm9, xmm1, 0); - __ vpmovzxwd(xmm6, xmm9, Assembler::AVX_512bit); - __ vextracti64x4(xmm9, xmm1, 1); - __ vpmovzxwd(xmm5, xmm9, Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm8, k2, Address(r11, xmm6, Address::times_4, 0), Assembler::AVX_512bit); - __ kmovql(k2, k3); - __ evpgatherdd(xmm10, k2, Address(r11, xmm5, Address::times_4, 0), Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 0), xmm8, Assembler::AVX_512bit); - __ evpmovdb(Address(dest, dp, Address::times_1, 16), xmm10, Assembler::AVX_512bit); - __ subq(length, 24); - __ addq(dest, 32); - __ addq(source, 24); - __ jmp(L_process32); - - // Scalar data processing takes 3 bytes at a time and produces 4 bytes of encoded data - /* This code corresponds to the scalar version of the following snippet in Base64.java - ** int bits = (src[sp0++] & 0xff) << 16 |(src[sp0++] & 0xff) << 8 |(src[sp0++] & 0xff); - ** dst[dp0++] = (byte)base64[(bits >> > 18) & 0x3f]; - ** dst[dp0++] = (byte)base64[(bits >> > 12) & 0x3f]; - ** dst[dp0++] = (byte)base64[(bits >> > 6) & 0x3f]; - ** dst[dp0++] = (byte)base64[bits & 0x3f];*/ - __ BIND(L_process3); - __ cmpl(length, 3); - __ jcc(Assembler::below, L_exit); - // Read 1 byte at a time - __ movzbl(rax, Address(source, start_offset)); - __ shll(rax, 0x10); - __ movl(r15, rax); - __ movzbl(rax, Address(source, start_offset, Address::times_1, 1)); - __ shll(rax, 0x8); - __ movzwl(rax, rax); - __ orl(r15, rax); - __ movzbl(rax, Address(source, start_offset, Address::times_1, 2)); - __ orl(rax, r15); - // Save 3 bytes read in r15 - __ movl(r15, rax); - __ shrl(rax, 0x12); - __ andl(rax, 0x3f); - // rax contains the index, r11 contains base64 lookup table - __ movb(rax, Address(r11, rax, Address::times_4)); - // Write the encoded byte to destination - __ movb(Address(dest, dp, Address::times_1, 0), rax); - __ movl(rax, r15); - __ shrl(rax, 0xc); - __ andl(rax, 0x3f); - __ movb(rax, Address(r11, rax, Address::times_4)); - __ movb(Address(dest, dp, Address::times_1, 1), rax); - __ movl(rax, r15); - __ shrl(rax, 0x6); - __ andl(rax, 0x3f); - __ movb(rax, Address(r11, rax, Address::times_4)); - __ movb(Address(dest, dp, Address::times_1, 2), rax); - __ movl(rax, r15); - __ andl(rax, 0x3f); - __ movb(rax, Address(r11, rax, Address::times_4)); - __ movb(Address(dest, dp, Address::times_1, 3), rax); - __ subl(length, 3); - __ addq(dest, 4); - __ addq(source, 3); - __ jmp(L_process3); - __ BIND(L_exit); + __ cmpl(length, 64); + __ jcc(Assembler::greaterEqual, L_process64Loop); + + __ cmpl(length, 0); + __ jcc(Assembler::lessEqual, L_exit); + + __ BIND(L_finalBit); + // Now have 1 to 63 bytes left to decode + + // I was going to let Java take care of the final fragment + // however it will repeatedly call this routine for every 4 bytes + // of input data, so handle the rest here. + __ movq(rax, -1); + __ bzhiq(rax, rax, length); // Input mask in rax + + __ movl(output_size, length); + __ shrl(output_size, 2); // Find (len / 4) * 3 (output length) + __ lea(output_size, Address(output_size, output_size, Address::times_2, 0)); + // output_size in r13 + + // Strip pad characters, if any, and adjust length and mask + __ cmpb(Address(source, length, Address::times_1, -1), '='); + __ jcc(Assembler::equal, L_padding); + + __ BIND(L_donePadding); + + // Output size is (64 - output_size), output mask is (all 1s >> output_size). + __ kmovql(input_mask, rax); + __ movq(output_mask, -1); + __ bzhiq(output_mask, output_mask, output_size); + + // Load initial input with all valid base64 characters. Will be used + // in merging source bytes to avoid masking when determining if an error occurred. + __ movl(rax, 0x61616161); + __ evpbroadcastd(input_initial_valid_b64, rax, Assembler::AVX_512bit); + + // A register containing all invalid base64 decoded values + __ movl(rax, 0x80808080); + __ evpbroadcastd(invalid_b64, rax, Assembler::AVX_512bit); + + // input_mask is in k1 + // output_size is in r13 + // output_mask is in r15 + // zmm0 - free + // zmm1 - 0x00011000 + // zmm2 - 0x01400140 + // zmm3 - errorvec + // zmm4 - pack vector + // zmm5 - lookup_lo + // zmm6 - lookup_hi + // zmm7 - errorvec + // zmm8 - 0x61616161 + // zmm9 - 0x80808080 + + // Load only the bytes from source, merging into our "fully-valid" register + __ evmovdqub(input_initial_valid_b64, input_mask, Address(source, start_offset, Address::times_1, 0x0), true, Assembler::AVX_512bit); + + // Decode all bytes within our merged input + __ evmovdquq(tmp, lookup_lo, Assembler::AVX_512bit); + __ evpermt2b(tmp, input_initial_valid_b64, lookup_hi, Assembler::AVX_512bit); + __ vporq(mask, tmp, input_initial_valid_b64, Assembler::AVX_512bit); + + // Check for error. Compare (decoded | initial) to all invalid. + // If any bytes have their high-order bit set, then we have an error. + __ evptestmb(k2, mask, invalid_b64, Assembler::AVX_512bit); + __ kortestql(k2, k2); + + // If we have an error, use the brute force loop to decode what we can (4-byte chunks). + __ jcc(Assembler::notZero, L_bruteForce); + + // Shuffle output bytes + __ vpmaddubsw(tmp, tmp, pack16_op, Assembler::AVX_512bit); + __ vpmaddwd(tmp, tmp, pack32_op, Assembler::AVX_512bit); + + __ vpermb(tmp, pack24bits, tmp, Assembler::AVX_512bit); + __ kmovql(k1, output_mask); + __ evmovdqub(Address(dest, dp), k1, tmp, true, Assembler::AVX_512bit); + + __ addptr(dest, output_size); + + __ BIND(L_exit); + __ vzeroupper(); + __ pop(rax); // Get original dest value + __ subptr(dest, rax); // Number of bytes converted + __ movptr(rax, dest); + __ pop(rbx); + __ pop(r15); + __ pop(r14); + __ pop(r13); + __ pop(r12); + __ leave(); + __ ret(0); + + __ BIND(L_loadURL); + __ evmovdquq(lookup_lo, ExternalAddress(StubRoutines::x86::base64_vbmi_lookup_lo_url_addr()), Assembler::AVX_512bit, r13); + __ evmovdquq(lookup_hi, ExternalAddress(StubRoutines::x86::base64_vbmi_lookup_hi_url_addr()), Assembler::AVX_512bit, r13); + __ jmp(L_continue); + + __ BIND(L_padding); + __ decrementq(output_size, 1); + __ shrq(rax, 1); + + __ cmpb(Address(source, length, Address::times_1, -2), '='); + __ jcc(Assembler::notEqual, L_donePadding); + + __ decrementq(output_size, 1); + __ shrq(rax, 1); + __ jmp(L_donePadding); + + __ align32(); + __ BIND(L_bruteForce); + } // End of if(avx512_vbmi) + + // Use non-AVX code to decode 4-byte chunks into 3 bytes of output + + // Register state (Linux): + // r12-15 - saved on stack + // rdi - src + // rsi - sp + // rdx - sl + // rcx - dst + // r8 - dp + // r9 - isURL + + // Register state (Windows): + // r12-15 - saved on stack + // rcx - src + // rdx - sp + // r8 - sl + // r9 - dst + // r12 - dp + // r10 - isURL + + // Registers (common): + // length (r14) - bytes in src + + const Register decode_table = r11; + const Register out_byte_count = rbx; + const Register byte1 = r13; + const Register byte2 = r15; + const Register byte3 = WINDOWS_ONLY(r8) NOT_WINDOWS(rdx); + const Register byte4 = WINDOWS_ONLY(r10) NOT_WINDOWS(r9); + + __ shrl(length, 2); // Multiple of 4 bytes only - length is # 4-byte chunks + __ cmpl(length, 0); + __ jcc(Assembler::lessEqual, L_exit_no_vzero); + + __ shll(isURL, 8); // index into decode table based on isURL + __ lea(decode_table, ExternalAddress(StubRoutines::x86::base64_decoding_table_addr())); + __ addptr(decode_table, isURL); + + __ jmp(L_bottomLoop); + + __ align32(); + __ BIND(L_forceLoop); + __ shll(byte1, 18); + __ shll(byte2, 12); + __ shll(byte3, 6); + __ orl(byte1, byte2); + __ orl(byte1, byte3); + __ orl(byte1, byte4); + + __ addptr(source, 4); + + __ movb(Address(dest, dp, Address::times_1, 2), byte1); + __ shrl(byte1, 8); + __ movb(Address(dest, dp, Address::times_1, 1), byte1); + __ shrl(byte1, 8); + __ movb(Address(dest, dp, Address::times_1, 0), byte1); + + __ addptr(dest, 3); + __ decrementl(length, 1); + __ jcc(Assembler::zero, L_exit_no_vzero); + + __ BIND(L_bottomLoop); + __ load_unsigned_byte(byte1, Address(source, start_offset, Address::times_1, 0x00)); + __ load_unsigned_byte(byte2, Address(source, start_offset, Address::times_1, 0x01)); + __ load_signed_byte(byte1, Address(decode_table, byte1)); + __ load_signed_byte(byte2, Address(decode_table, byte2)); + __ load_unsigned_byte(byte3, Address(source, start_offset, Address::times_1, 0x02)); + __ load_unsigned_byte(byte4, Address(source, start_offset, Address::times_1, 0x03)); + __ load_signed_byte(byte3, Address(decode_table, byte3)); + __ load_signed_byte(byte4, Address(decode_table, byte4)); + + __ mov(rax, byte1); + __ orl(rax, byte2); + __ orl(rax, byte3); + __ orl(rax, byte4); + __ jcc(Assembler::positive, L_forceLoop); + + __ BIND(L_exit_no_vzero); + __ pop(rax); // Get original dest value + __ subptr(dest, rax); // Number of bytes converted + __ movptr(rax, dest); + __ pop(rbx); __ pop(r15); __ pop(r14); __ pop(r13); __ pop(r12); __ leave(); __ ret(0); + return start; } + /** * Arguments: * @@ -5718,7 +6436,13 @@ if (VM_Version::supports_sse4_1() && VM_Version::supports_avx512_vpclmulqdq() && VM_Version::supports_avx512bw() && VM_Version::supports_avx512vl()) { + // The constants used in the CRC32 algorithm requires the 1's compliment of the initial crc value. + // However, the constant table for CRC32-C assumes the original crc value. Account for this + // difference before calling and after returning. + __ lea(table, ExternalAddress(StubRoutines::x86::crc_table_avx512_addr())); + __ notl(crc); __ kernel_crc32_avx512(crc, buf, len, table, tmp1, tmp2); + __ notl(crc); } else { __ kernel_crc32(crc, buf, len, table, tmp1); } @@ -5770,20 +6494,27 @@ BLOCK_COMMENT("Entry:"); __ enter(); // required for proper stackwalking of RuntimeStub frame + if (VM_Version::supports_sse4_1() && VM_Version::supports_avx512_vpclmulqdq() && + VM_Version::supports_avx512bw() && + VM_Version::supports_avx512vl()) { + __ lea(j, ExternalAddress(StubRoutines::x86::crc32c_table_avx512_addr())); + __ kernel_crc32_avx512(crc, buf, len, j, l, k); + } else { #ifdef _WIN64 - __ push(y); - __ push(z); + __ push(y); + __ push(z); #endif - __ crc32c_ipl_alg2_alt2(crc, buf, len, - a, j, k, - l, y, z, - c_farg0, c_farg1, c_farg2, - is_pclmulqdq_supported); - __ movl(rax, crc); + __ crc32c_ipl_alg2_alt2(crc, buf, len, + a, j, k, + l, y, z, + c_farg0, c_farg1, c_farg2, + is_pclmulqdq_supported); #ifdef _WIN64 - __ pop(z); - __ pop(y); + __ pop(z); + __ pop(y); #endif + } + __ movl(rax, crc); __ vzeroupper(); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); @@ -6960,15 +7691,30 @@ } } + if (UseBASE64Intrinsics) { - StubRoutines::x86::_and_mask = base64_and_mask_addr(); - StubRoutines::x86::_bswap_mask = base64_bswap_mask_addr(); - StubRoutines::x86::_base64_charset = base64_charset_addr(); - StubRoutines::x86::_url_charset = base64url_charset_addr(); - StubRoutines::x86::_gather_mask = base64_gather_mask_addr(); - StubRoutines::x86::_left_shift_mask = base64_left_shift_mask_addr(); - StubRoutines::x86::_right_shift_mask = base64_right_shift_mask_addr(); + if(VM_Version::supports_avx2() && + VM_Version::supports_avx512bw() && + VM_Version::supports_avx512vl()) { + StubRoutines::x86::_avx2_shuffle_base64 = base64_avx2_shuffle_addr(); + StubRoutines::x86::_avx2_input_mask_base64 = base64_avx2_input_mask_addr(); + StubRoutines::x86::_avx2_lut_base64 = base64_avx2_lut_addr(); + } + StubRoutines::x86::_encoding_table_base64 = base64_encoding_table_addr(); + if (VM_Version::supports_avx512_vbmi()) { + StubRoutines::x86::_shuffle_base64 = base64_shuffle_addr(); + StubRoutines::x86::_lookup_lo_base64 = base64_vbmi_lookup_lo_addr(); + StubRoutines::x86::_lookup_hi_base64 = base64_vbmi_lookup_hi_addr(); + StubRoutines::x86::_lookup_lo_base64url = base64_vbmi_lookup_lo_url_addr(); + StubRoutines::x86::_lookup_hi_base64url = base64_vbmi_lookup_hi_url_addr(); + StubRoutines::x86::_pack_vec_base64 = base64_vbmi_pack_vec_addr(); + StubRoutines::x86::_join_0_1_base64 = base64_vbmi_join_0_1_addr(); + StubRoutines::x86::_join_1_2_base64 = base64_vbmi_join_1_2_addr(); + StubRoutines::x86::_join_2_3_base64 = base64_vbmi_join_2_3_addr(); + } + StubRoutines::x86::_decoding_table_base64 = base64_decoding_table_addr(); StubRoutines::_base64_encodeBlock = generate_base64_encodeBlock(); + StubRoutines::_base64_decodeBlock = generate_base64_decodeBlock(); } BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubRoutines_x86.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubRoutines_x86.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubRoutines_x86.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubRoutines_x86.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -65,14 +65,21 @@ address StubRoutines::x86::_k512_W_addr = NULL; address StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = NULL; // Base64 masks -address StubRoutines::x86::_bswap_mask = NULL; -address StubRoutines::x86::_base64_charset = NULL; -address StubRoutines::x86::_gather_mask = NULL; -address StubRoutines::x86::_right_shift_mask = NULL; -address StubRoutines::x86::_left_shift_mask = NULL; -address StubRoutines::x86::_and_mask = NULL; -address StubRoutines::x86::_url_charset = NULL; +address StubRoutines::x86::_encoding_table_base64 = NULL; +address StubRoutines::x86::_shuffle_base64 = NULL; +address StubRoutines::x86::_avx2_shuffle_base64 = NULL; +address StubRoutines::x86::_avx2_input_mask_base64 = NULL; +address StubRoutines::x86::_avx2_lut_base64 = NULL; address StubRoutines::x86::_counter_mask_addr = NULL; +address StubRoutines::x86::_lookup_lo_base64 = NULL; +address StubRoutines::x86::_lookup_hi_base64 = NULL; +address StubRoutines::x86::_lookup_lo_base64url = NULL; +address StubRoutines::x86::_lookup_hi_base64url = NULL; +address StubRoutines::x86::_pack_vec_base64 = NULL; +address StubRoutines::x86::_join_0_1_base64 = NULL; +address StubRoutines::x86::_join_1_2_base64 = NULL; +address StubRoutines::x86::_join_2_3_base64 = NULL; +address StubRoutines::x86::_decoding_table_base64 = NULL; #endif address StubRoutines::x86::_pshuffle_byte_flip_mask_addr = NULL; @@ -212,6 +219,23 @@ 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL }; +juint StubRoutines::x86::_crc32c_table_avx512[] = +{ + 0xb9e02b86UL, 0x00000000UL, 0xdcb17aa4UL, 0x00000000UL, + 0x493c7d27UL, 0x00000000UL, 0xc1068c50UL, 0x0000000eUL, + 0x06e38d70UL, 0x00000002UL, 0x6992cea2UL, 0x00000000UL, + 0x493c7d27UL, 0x00000000UL, 0xdd45aab8UL, 0x00000000UL, + 0xdea713f0UL, 0x00000000UL, 0x05ec76f0UL, 0x00000001UL, + 0x47db8317UL, 0x00000000UL, 0x2ad91c30UL, 0x00000000UL, + 0x0715ce53UL, 0x00000000UL, 0xc49f4f67UL, 0x00000000UL, + 0x39d3b296UL, 0x00000000UL, 0x083a6eecUL, 0x00000000UL, + 0x9e4addf8UL, 0x00000000UL, 0x740eef02UL, 0x00000000UL, + 0xddc0152bUL, 0x00000000UL, 0x1c291d04UL, 0x00000000UL, + 0xba4fc28eUL, 0x00000000UL, 0x3da6d0cbUL, 0x00000000UL, + 0x493c7d27UL, 0x00000000UL, 0xc1068c50UL, 0x0000000eUL, + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL +}; + juint StubRoutines::x86::_crc_by128_masks_avx512[] = { 0xffffffffUL, 0xffffffffUL, 0x00000000UL, 0x00000000UL, diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubRoutines_x86.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubRoutines_x86.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/stubRoutines_x86.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/stubRoutines_x86.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -137,6 +137,7 @@ #ifdef _LP64 static juint _crc_by128_masks_avx512[]; static juint _crc_table_avx512[]; + static juint _crc32c_table_avx512[]; static juint _shuf_table_crc32_avx512[]; static juint _adler32_shuf0_table[]; static juint _adler32_shuf1_table[]; @@ -184,13 +185,20 @@ static address _pshuffle_byte_flip_mask_addr_sha512; static address _counter_mask_addr; // Masks for base64 - static address _base64_charset; - static address _bswap_mask; - static address _gather_mask; - static address _right_shift_mask; - static address _left_shift_mask; - static address _and_mask; - static address _url_charset; + static address _encoding_table_base64; + static address _shuffle_base64; + static address _avx2_shuffle_base64; + static address _avx2_input_mask_base64; + static address _avx2_lut_base64; + static address _lookup_lo_base64; + static address _lookup_hi_base64; + static address _lookup_lo_base64url; + static address _lookup_hi_base64url; + static address _pack_vec_base64; + static address _join_0_1_base64; + static address _join_1_2_base64; + static address _join_2_3_base64; + static address _decoding_table_base64; #endif // byte flip mask for sha256 static address _pshuffle_byte_flip_mask_addr; @@ -247,6 +255,7 @@ static address crc_by128_masks_avx512_addr() { return (address)_crc_by128_masks_avx512; } static address shuf_table_crc32_avx512_addr() { return (address)_shuf_table_crc32_avx512; } static address crc_table_avx512_addr() { return (address)_crc_table_avx512; } + static address crc32c_table_avx512_addr() { return (address)_crc32c_table_avx512; } #endif // _LP64 static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; } static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; } @@ -328,14 +337,21 @@ static address k256_W_addr() { return _k256_W_adr; } static address k512_W_addr() { return _k512_W_addr; } static address pshuffle_byte_flip_mask_addr_sha512() { return _pshuffle_byte_flip_mask_addr_sha512; } - static address base64_charset_addr() { return _base64_charset; } - static address base64url_charset_addr() { return _url_charset; } - static address base64_bswap_mask_addr() { return _bswap_mask; } - static address base64_gather_mask_addr() { return _gather_mask; } - static address base64_right_shift_mask_addr() { return _right_shift_mask; } - static address base64_left_shift_mask_addr() { return _left_shift_mask; } - static address base64_and_mask_addr() { return _and_mask; } + static address base64_encoding_table_addr() { return _encoding_table_base64; } + static address base64_shuffle_addr() { return _shuffle_base64; } + static address base64_avx2_shuffle_addr() { return _avx2_shuffle_base64; } + static address base64_avx2_input_mask_addr() { return _avx2_input_mask_base64; } + static address base64_avx2_lut_addr() { return _avx2_lut_base64; } static address counter_mask_addr() { return _counter_mask_addr; } + static address base64_vbmi_lookup_lo_addr() { return _lookup_lo_base64; } + static address base64_vbmi_lookup_hi_addr() { return _lookup_hi_base64; } + static address base64_vbmi_lookup_lo_url_addr() { return _lookup_lo_base64url; } + static address base64_vbmi_lookup_hi_url_addr() { return _lookup_hi_base64url; } + static address base64_vbmi_pack_vec_addr() { return _pack_vec_base64; } + static address base64_vbmi_join_0_1_addr() { return _join_0_1_base64; } + static address base64_vbmi_join_1_2_addr() { return _join_1_2_base64; } + static address base64_vbmi_join_2_3_addr() { return _join_2_3_base64; } + static address base64_decoding_table_addr() { return _decoding_table_base64; } #endif static address pshuffle_byte_flip_mask_addr() { return _pshuffle_byte_flip_mask_addr; } static void generate_CRC32C_table(bool is_pclmulqdq_supported); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1702,21 +1702,21 @@ #ifndef _LP64 fep = __ pc(); // ftos entry point __ push(ftos); - __ jmp(L); + __ jmpb(L); dep = __ pc(); // dtos entry point __ push(dtos); - __ jmp(L); + __ jmpb(L); #else fep = __ pc(); // ftos entry point __ push_f(xmm0); - __ jmp(L); + __ jmpb(L); dep = __ pc(); // dtos entry point __ push_d(xmm0); - __ jmp(L); + __ jmpb(L); #endif // _LP64 lep = __ pc(); // ltos entry point __ push_l(); - __ jmp(L); + __ jmpb(L); aep = bep = cep = sep = iep = __ pc(); // [abcsi]tos entry point __ push_i_or_ptr(); vep = __ pc(); // vtos entry point diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/x86_32.ad openjdk-17-17.0.6+10/src/hotspot/cpu/x86/x86_32.ad --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/x86_32.ad 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/x86_32.ad 2023-01-10 13:21:55.000000000 +0000 @@ -11727,7 +11727,7 @@ instruct string_compareL(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11742,7 +11742,7 @@ instruct string_compareL_evex(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, kReg ktmp, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11757,7 +11757,7 @@ instruct string_compareU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11772,7 +11772,7 @@ instruct string_compareU_evex(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, kReg ktmp, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11787,7 +11787,7 @@ instruct string_compareLU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11802,7 +11802,7 @@ instruct string_compareLU_evex(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, eAXRegI result, regD tmp1, kReg ktmp, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11817,7 +11817,7 @@ instruct string_compareUL(eSIRegP str1, eDXRegI cnt1, eDIRegP str2, eCXRegI cnt2, eAXRegI result, regD tmp1, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11832,7 +11832,7 @@ instruct string_compareUL_evex(eSIRegP str1, eDXRegI cnt1, eDIRegP str2, eCXRegI cnt2, eAXRegI result, regD tmp1, kReg ktmp, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11848,7 +11848,7 @@ // fast string equals instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw()); match(Set result (StrEquals (Binary str1 str2) cnt)); effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); @@ -11864,7 +11864,7 @@ instruct string_equals_evex(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, regD tmp1, regD tmp2, kReg ktmp, eBXRegI tmp3, eFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw()); match(Set result (StrEquals (Binary str1 str2) cnt)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); @@ -12042,7 +12042,7 @@ instruct array_equalsB(eDIRegP ary1, eSIRegP ary2, eAXRegI result, regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); @@ -12059,7 +12059,7 @@ instruct array_equalsB_evex(eDIRegP ary1, eSIRegP ary2, eAXRegI result, regD tmp1, regD tmp2, kReg ktmp, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); @@ -12076,7 +12076,7 @@ instruct array_equalsC(eDIRegP ary1, eSIRegP ary2, eAXRegI result, regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); @@ -12093,7 +12093,7 @@ instruct array_equalsC_evex(eDIRegP ary1, eSIRegP ary2, eAXRegI result, regD tmp1, regD tmp2, kReg ktmp, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) %{ - predicate(UseAVX > 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); //ins_cost(300); @@ -12110,7 +12110,7 @@ instruct has_negatives(eSIRegP ary1, eCXRegI len, eAXRegI result, regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set result (HasNegatives ary1 len)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); @@ -12126,7 +12126,7 @@ instruct has_negatives_evex(eSIRegP ary1, eCXRegI len, eAXRegI result, regD tmp1, regD tmp2, kReg ktmp1, kReg ktmp2, eBXRegI tmp3, eFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set result (HasNegatives ary1 len)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); @@ -12143,7 +12143,7 @@ // fast char[] to byte[] compression instruct string_compress(eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); @@ -12159,7 +12159,7 @@ instruct string_compress_evex(eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4, kReg ktmp1, kReg ktmp2, eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); @@ -12176,7 +12176,7 @@ // fast byte[] to char[] inflation instruct string_inflate(Universe dummy, eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, eCXRegI tmp2, eFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set dummy (StrInflatedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); @@ -12190,7 +12190,7 @@ instruct string_inflate_evex(Universe dummy, eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, kReg ktmp, eCXRegI tmp2, eFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set dummy (StrInflatedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/x86/x86_64.ad openjdk-17-17.0.6+10/src/hotspot/cpu/x86/x86_64.ad --- openjdk-17-17.0.5+8/src/hotspot/cpu/x86/x86_64.ad 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/x86/x86_64.ad 2023-01-10 13:21:55.000000000 +0000 @@ -11260,7 +11260,7 @@ instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11276,7 +11276,7 @@ instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11292,7 +11292,7 @@ instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11308,7 +11308,7 @@ instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11324,7 +11324,7 @@ instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11340,7 +11340,7 @@ instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11356,7 +11356,7 @@ instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, rax_RegI result, legRegD tmp1, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); + predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11372,7 +11372,7 @@ instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); + predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); @@ -11555,7 +11555,7 @@ instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw()); match(Set result (StrEquals (Binary str1 str2) cnt)); effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); @@ -11571,7 +11571,7 @@ instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw()); match(Set result (StrEquals (Binary str1 str2) cnt)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); @@ -11588,7 +11588,7 @@ instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); @@ -11604,7 +11604,7 @@ instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); + predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); @@ -11620,7 +11620,7 @@ instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) %{ - predicate(UseAVX <= 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); @@ -11636,7 +11636,7 @@ instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) %{ - predicate(UseAVX > 2 && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); + predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); @@ -11652,7 +11652,7 @@ instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set result (HasNegatives ary1 len)); effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); @@ -11668,7 +11668,7 @@ instruct has_negatives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set result (HasNegatives ary1 len)); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); @@ -11684,7 +11684,7 @@ // fast char[] to byte[] compression instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); @@ -11701,7 +11701,7 @@ instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set result (StrCompressedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); @@ -11718,7 +11718,7 @@ // fast byte[] to char[] inflation instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ - predicate(UseAVX <= 2); + predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); match(Set dummy (StrInflatedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); @@ -11732,7 +11732,7 @@ instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ - predicate(UseAVX > 2); + predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); match(Set dummy (StrInflatedCopy src (Binary dst len))); effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/zero/frame_zero.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/zero/frame_zero.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/zero/frame_zero.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/zero/frame_zero.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc. + * Copyright (c) 2007, 2021, Red Hat, Inc. 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 @@ -116,13 +116,67 @@ } bool frame::safe_for_sender(JavaThread *thread) { - ShouldNotCallThis(); - return false; + address sp = (address)_sp; + + // consider stack guards when trying to determine "safe" stack pointers + // sp must be within the usable part of the stack (not in guards) + if (!thread->is_in_usable_stack(sp)) { + return false; + } + + // an fp must be within the stack and above (but not equal) sp + if (!thread->is_in_stack_range_excl((address)fp(), sp)) { + return false; + } + + // All good. + return true; } bool frame::is_interpreted_frame_valid(JavaThread *thread) const { - ShouldNotCallThis(); - return false; + assert(is_interpreted_frame(), "Not an interpreted frame"); + // These are reasonable sanity checks + if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) { + return false; + } + if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) { + return false; + } + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (fp() <= sp()) { // this attempts to deal with unsigned comparison above + return false; + } + + // do some validation of frame elements + // first the method + + Method* m = *interpreter_frame_method_addr(); + + // validate the method we'd find in this potential sender + if (!Method::is_valid_method(m)) { + return false; + } + + // validate bci/bcp + address bcp = interpreter_frame_bcp(); + if (m->validate_bci_from_bcp(bcp) < 0) { + return false; + } + + // validate ConstantPoolCache* + ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + if (MetaspaceObj::is_valid(cp) == false) { + return false; + } + + // validate locals + address locals = (address) *interpreter_frame_locals_addr(); + if (!thread->is_in_stack_range_incl(locals, (address)fp())) { + return false; + } + + return true; } BasicType frame::interpreter_frame_result(oop* oop_result, diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/zero/globalDefinitions_zero.hpp openjdk-17-17.0.6+10/src/hotspot/cpu/zero/globalDefinitions_zero.hpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/zero/globalDefinitions_zero.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/zero/globalDefinitions_zero.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,10 @@ #define SUPPORTS_NATIVE_CX8 #endif +#ifndef FFI_GO_CLOSURES +#define FFI_GO_CLOSURES 0 +#endif + #include // Indicates whether the C calling conventions require that diff -Nru openjdk-17-17.0.5+8/src/hotspot/cpu/zero/vm_version_zero.cpp openjdk-17-17.0.6+10/src/hotspot/cpu/zero/vm_version_zero.cpp --- openjdk-17-17.0.5+8/src/hotspot/cpu/zero/vm_version_zero.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/cpu/zero/vm_version_zero.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -50,6 +50,71 @@ FLAG_SET_DEFAULT(UseHeavyMonitors, true); } + if (UseAESIntrinsics) { + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + + if (UseAES) { + warning("AES instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseAES, false); + } + + if (UseAESCTRIntrinsics) { + warning("AES/CTR intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); + } + + if (UseFMA) { + warning("FMA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseFMA, false); + } + + if (UseMD5Intrinsics) { + warning("MD5 intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseMD5Intrinsics, false); + } + + if (UseSHA) { + warning("SHA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA, false); + } + + if (UseSHA1Intrinsics) { + warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + } + + if (UseSHA256Intrinsics) { + warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + } + + if (UseSHA512Intrinsics) { + warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } + + if (UseSHA3Intrinsics) { + warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU."); + FLAG_SET_DEFAULT(UseSHA3Intrinsics, false); + } + + if (UseCRC32Intrinsics) { + warning("CRC32 intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); + } + + if (UseAdler32Intrinsics) { + warning("Adler32 intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAdler32Intrinsics, false); + } + + if (UseVectorizedMismatchIntrinsic) { + warning("vectorizedMismatch intrinsic is not available on this CPU."); + FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); + } + // Not implemented UNSUPPORTED_OPTION(CriticalJNINatives); UNSUPPORTED_OPTION(UseCompiler); diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupSubsystem_linux.cpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupSubsystem_linux.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupSubsystem_linux.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupSubsystem_linux.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -122,6 +122,32 @@ return new CgroupV1Subsystem(cpuset, cpu, cpuacct, pids, memory); } +void CgroupSubsystemFactory::set_controller_paths(CgroupInfo* cg_infos, + int controller, + const char* name, + char* mount_path, + char* root_path) { + if (cg_infos[controller]._mount_path != NULL) { + // On some systems duplicate controllers get mounted in addition to + // the main cgroup controllers most likely under /sys/fs/cgroup. In that + // case pick the one under /sys/fs/cgroup and discard others. + if (strstr(cg_infos[controller]._mount_path, "/sys/fs/cgroup") != cg_infos[controller]._mount_path) { + log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.", + name, mount_path, cg_infos[controller]._mount_path); + os::free(cg_infos[controller]._mount_path); + os::free(cg_infos[controller]._root_mount_path); + cg_infos[controller]._mount_path = os::strdup(mount_path); + cg_infos[controller]._root_mount_path = os::strdup(root_path); + } else { + log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.", + name, cg_infos[controller]._mount_path, mount_path); + } + } else { + cg_infos[controller]._mount_path = os::strdup(mount_path); + cg_infos[controller]._root_mount_path = os::strdup(root_path); + } +} + bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos, const char* proc_cgroups, const char* proc_self_cgroup, @@ -287,7 +313,6 @@ bool cgroupv2_mount_point_found = false; bool any_cgroup_mounts_found = false; while ((p = fgets(buf, MAXPATHLEN, mntinfo)) != NULL) { - char tmp_mount_point[MAXPATHLEN+1]; char tmp_fs_type[MAXPATHLEN+1]; char tmproot[MAXPATHLEN+1]; char tmpmount[MAXPATHLEN+1]; @@ -298,15 +323,13 @@ // Cgroup v2 relevant info. We only look for the _mount_path iff is_cgroupsV2 so // as to avoid memory stomping of the _mount_path pointer later on in the cgroup v1 // block in the hybrid case. - // - if (is_cgroupsV2 && sscanf(p, "%*d %*d %*d:%*d %*s %s %*[^-]- %s %*s %*s", tmp_mount_point, tmp_fs_type) == 2) { + if (is_cgroupsV2 && sscanf(p, "%*d %*d %*d:%*d %s %s %*[^-]- %s %*s %*s", tmproot, tmpmount, tmp_fs_type) == 3) { // we likely have an early match return (e.g. cgroup fs match), be sure we have cgroup2 as fstype - if (!cgroupv2_mount_point_found && strcmp("cgroup2", tmp_fs_type) == 0) { + if (strcmp("cgroup2", tmp_fs_type) == 0) { cgroupv2_mount_point_found = true; any_cgroup_mounts_found = true; for (int i = 0; i < CG_INFO_LENGTH; i++) { - assert(cg_infos[i]._mount_path == NULL, "_mount_path memory stomping"); - cg_infos[i]._mount_path = os::strdup(tmp_mount_point); + set_controller_paths(cg_infos, i, "(cg2, unified)", tmpmount, tmproot); } } } @@ -331,47 +354,23 @@ while ((token = strsep(&cptr, ",")) != NULL) { if (strcmp(token, "memory") == 0) { any_cgroup_mounts_found = true; - assert(cg_infos[MEMORY_IDX]._mount_path == NULL, "stomping of _mount_path"); - cg_infos[MEMORY_IDX]._mount_path = os::strdup(tmpmount); - cg_infos[MEMORY_IDX]._root_mount_path = os::strdup(tmproot); + set_controller_paths(cg_infos, MEMORY_IDX, token, tmpmount, tmproot); cg_infos[MEMORY_IDX]._data_complete = true; } else if (strcmp(token, "cpuset") == 0) { any_cgroup_mounts_found = true; - if (cg_infos[CPUSET_IDX]._mount_path != NULL) { - // On some systems duplicate cpuset controllers get mounted in addition to - // the main cgroup controllers most likely under /sys/fs/cgroup. In that - // case pick the one under /sys/fs/cgroup and discard others. - if (strstr(cg_infos[CPUSET_IDX]._mount_path, "/sys/fs/cgroup") != cg_infos[CPUSET_IDX]._mount_path) { - log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.", - tmpmount, cg_infos[CPUSET_IDX]._mount_path); - os::free(cg_infos[CPUSET_IDX]._mount_path); - cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount); - } else { - log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.", - cg_infos[CPUSET_IDX]._mount_path, tmpmount); - } - } else { - cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount); - } - cg_infos[CPUSET_IDX]._root_mount_path = os::strdup(tmproot); + set_controller_paths(cg_infos, CPUSET_IDX, token, tmpmount, tmproot); cg_infos[CPUSET_IDX]._data_complete = true; } else if (strcmp(token, "cpu") == 0) { any_cgroup_mounts_found = true; - assert(cg_infos[CPU_IDX]._mount_path == NULL, "stomping of _mount_path"); - cg_infos[CPU_IDX]._mount_path = os::strdup(tmpmount); - cg_infos[CPU_IDX]._root_mount_path = os::strdup(tmproot); + set_controller_paths(cg_infos, CPU_IDX, token, tmpmount, tmproot); cg_infos[CPU_IDX]._data_complete = true; } else if (strcmp(token, "cpuacct") == 0) { any_cgroup_mounts_found = true; - assert(cg_infos[CPUACCT_IDX]._mount_path == NULL, "stomping of _mount_path"); - cg_infos[CPUACCT_IDX]._mount_path = os::strdup(tmpmount); - cg_infos[CPUACCT_IDX]._root_mount_path = os::strdup(tmproot); + set_controller_paths(cg_infos, CPUACCT_IDX, token, tmpmount, tmproot); cg_infos[CPUACCT_IDX]._data_complete = true; } else if (strcmp(token, "pids") == 0) { any_cgroup_mounts_found = true; - assert(cg_infos[PIDS_IDX]._mount_path == NULL, "stomping of _mount_path"); - cg_infos[PIDS_IDX]._mount_path = os::strdup(tmpmount); - cg_infos[PIDS_IDX]._root_mount_path = os::strdup(tmproot); + set_controller_paths(cg_infos, PIDS_IDX, token, tmpmount, tmproot); cg_infos[PIDS_IDX]._data_complete = true; } } @@ -555,7 +554,30 @@ if (!memory_limit->should_check_metric()) { return memory_limit->value(); } + jlong phys_mem = os::Linux::physical_memory(); + log_trace(os, container)("total physical memory: " JLONG_FORMAT, phys_mem); jlong mem_limit = read_memory_limit_in_bytes(); + + if (mem_limit <= 0 || mem_limit >= phys_mem) { + jlong read_mem_limit = mem_limit; + const char *reason; + if (mem_limit >= phys_mem) { + // Exceeding physical memory is treated as unlimited. Cg v1's implementation + // of read_memory_limit_in_bytes() caps this at phys_mem since Cg v1 has no + // value to represent 'max'. Cg v2 may return a value >= phys_mem if e.g. the + // container engine was started with a memory flag exceeding it. + reason = "ignored"; + mem_limit = -1; + } else if (OSCONTAINER_ERROR == mem_limit) { + reason = "failed"; + } else { + assert(mem_limit == -1, "Expected unlimited"); + reason = "unlimited"; + } + log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value " JLONG_FORMAT, + reason, read_mem_limit, phys_mem); + } + // Update cached metric to avoid re-reading container settings too often memory_limit->set_value(mem_limit, OSCONTAINER_CACHE_TIMEOUT); return mem_limit; diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupSubsystem_linux.hpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupSubsystem_linux.hpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupSubsystem_linux.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupSubsystem_linux.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -252,12 +252,15 @@ virtual jlong memory_and_swap_limit_in_bytes() = 0; virtual jlong memory_soft_limit_in_bytes() = 0; virtual jlong memory_max_usage_in_bytes() = 0; + virtual char * cpu_cpuset_cpus() = 0; virtual char * cpu_cpuset_memory_nodes() = 0; virtual jlong read_memory_limit_in_bytes() = 0; virtual const char * container_type() = 0; virtual CachingCgroupController* memory_controller() = 0; virtual CachingCgroupController* cpu_controller() = 0; + + virtual void print_version_specific_info(outputStream* st) = 0; }; // Utility class for storing info retrieved from /proc/cgroups, @@ -308,6 +311,11 @@ } #endif + static void set_controller_paths(CgroupInfo* cg_infos, + int controller, + const char* name, + char* mount_path, + char* root_path); // Determine the cgroup type (version 1 or version 2), given // relevant paths to files. Sets 'flags' accordingly. static bool determine_type(CgroupInfo* cg_infos, diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -31,6 +31,7 @@ #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" +#include "os_linux.hpp" /* * Set directory to subsystem specific files based @@ -105,7 +106,7 @@ GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.limit_in_bytes", "Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit); - if (memlimit >= _unlimited_memory) { + if (memlimit >= os::Linux::physical_memory()) { log_trace(os, container)("Non-Hierarchical Memory Limit is: Unlimited"); CgroupV1MemoryController* mem_controller = reinterpret_cast(_memory->controller()); if (mem_controller->is_hierarchical()) { @@ -113,7 +114,7 @@ const char* format = "%s " JULONG_FORMAT; GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchline, "Hierarchical Memory Limit is: " JULONG_FORMAT, format, hier_memlimit) - if (hier_memlimit >= _unlimited_memory) { + if (hier_memlimit >= os::Linux::physical_memory()) { log_trace(os, container)("Hierarchical Memory Limit is: Unlimited"); } else { return (jlong)hier_memlimit; @@ -127,9 +128,11 @@ } jlong CgroupV1Subsystem::memory_and_swap_limit_in_bytes() { + julong host_total_memsw; GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.memsw.limit_in_bytes", "Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit); - if (memswlimit >= _unlimited_memory) { + host_total_memsw = os::Linux::host_swap() + os::Linux::physical_memory(); + if (memswlimit >= host_total_memsw) { log_trace(os, container)("Non-Hierarchical Memory and Swap Limit is: Unlimited"); CgroupV1MemoryController* mem_controller = reinterpret_cast(_memory->controller()); if (mem_controller->is_hierarchical()) { @@ -137,7 +140,7 @@ const char* format = "%s " JULONG_FORMAT; GET_CONTAINER_INFO_LINE(julong, _memory->controller(), "/memory.stat", matchline, "Hierarchical Memory and Swap Limit is : " JULONG_FORMAT, format, hier_memswlimit) - if (hier_memswlimit >= _unlimited_memory) { + if (hier_memswlimit >= host_total_memsw) { log_trace(os, container)("Hierarchical Memory and Swap Limit is: Unlimited"); } else { jlong swappiness = read_mem_swappiness(); @@ -172,7 +175,7 @@ jlong CgroupV1Subsystem::memory_soft_limit_in_bytes() { GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.soft_limit_in_bytes", "Memory Soft Limit is: " JULONG_FORMAT, JULONG_FORMAT, memsoftlimit); - if (memsoftlimit >= _unlimited_memory) { + if (memsoftlimit >= os::Linux::physical_memory()) { log_trace(os, container)("Memory Soft Limit is: Unlimited"); return (jlong)-1; } else { @@ -209,6 +212,38 @@ return memmaxusage; } + +jlong CgroupV1Subsystem::kernel_memory_usage_in_bytes() { + GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.usage_in_bytes", + "Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_usage); + return kmem_usage; +} + +jlong CgroupV1Subsystem::kernel_memory_limit_in_bytes() { + GET_CONTAINER_INFO(julong, _memory->controller(), "/memory.kmem.limit_in_bytes", + "Kernel Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, kmem_limit); + if (kmem_limit >= os::Linux::physical_memory()) { + return (jlong)-1; + } + return (jlong)kmem_limit; +} + +jlong CgroupV1Subsystem::kernel_memory_max_usage_in_bytes() { + GET_CONTAINER_INFO(jlong, _memory->controller(), "/memory.kmem.max_usage_in_bytes", + "Maximum Kernel Memory Usage is: " JLONG_FORMAT, JLONG_FORMAT, kmem_max_usage); + return kmem_max_usage; +} + +void CgroupV1Subsystem::print_version_specific_info(outputStream* st) { + jlong kmem_usage = kernel_memory_usage_in_bytes(); + jlong kmem_limit = kernel_memory_limit_in_bytes(); + jlong kmem_max_usage = kernel_memory_max_usage_in_bytes(); + + OSContainer::print_container_helper(st, kmem_usage, "kernel_memory_usage_in_bytes"); + OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_max_usage_in_bytes"); + OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_limit_in_bytes"); +} + char * CgroupV1Subsystem::cpu_cpuset_cpus() { GET_CONTAINER_INFO_CPTR(cptr, _cpuset, "/cpuset.cpus", "cpuset.cpus is: %s", "%1023s", cpus, 1024); diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV1Subsystem_linux.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -79,6 +79,11 @@ jlong memory_soft_limit_in_bytes(); jlong memory_usage_in_bytes(); jlong memory_max_usage_in_bytes(); + + jlong kernel_memory_usage_in_bytes(); + jlong kernel_memory_limit_in_bytes(); + jlong kernel_memory_max_usage_in_bytes(); + char * cpu_cpuset_cpus(); char * cpu_cpuset_memory_nodes(); @@ -90,6 +95,8 @@ jlong pids_max(); jlong pids_current(); + void print_version_specific_info(outputStream* st); + const char * container_type() { return "cgroupv1"; } @@ -97,8 +104,6 @@ CachingCgroupController * cpu_controller() { return _cpu; } private: - julong _unlimited_memory; - /* controllers */ CachingCgroupController* _memory = NULL; CgroupV1Controller* _cpuset = NULL; @@ -121,7 +126,6 @@ _cpuacct = cpuacct; _pids = pids; _memory = new CachingCgroupController(memory); - _unlimited_memory = (LONG_MAX / os::vm_page_size()) * os::vm_page_size(); } }; diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV2Subsystem_linux.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -182,6 +182,16 @@ return os::strdup(mem_swp_limit_str); } +// memory.swap.current : total amount of swap currently used by the cgroup and its descendants +char* CgroupV2Subsystem::mem_swp_current_val() { + GET_CONTAINER_INFO_CPTR(cptr, _unified, "/memory.swap.current", + "Swap currently used is: %s", "%s", mem_swp_current_str, 1024); + if (mem_swp_current_str == NULL) { + return NULL; + } + return os::strdup(mem_swp_current_str); +} + /* memory_limit_in_bytes * * Return the limit of available memory for this process. @@ -212,6 +222,17 @@ return os::strdup(mem_limit_str); } +void CgroupV2Subsystem::print_version_specific_info(outputStream* st) { + char* mem_swp_current_str = mem_swp_current_val(); + jlong swap_current = limit_from_str(mem_swp_current_str); + + char* mem_swp_limit_str = mem_swp_limit_val(); + jlong swap_limit = limit_from_str(mem_swp_limit_str); + + OSContainer::print_container_helper(st, swap_current, "memory_swap_current_in_bytes"); + OSContainer::print_container_helper(st, swap_limit, "memory_swap_max_limit_in_bytes"); +} + char* CgroupV2Controller::construct_path(char* mount_path, char *cgroup_path) { char buf[MAXPATHLEN+1]; int buflen; diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Red Hat Inc. + * Copyright (c) 2020, 2022, Red Hat Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,7 @@ char *mem_limit_val(); char *mem_swp_limit_val(); + char *mem_swp_current_val(); char *mem_soft_limit_val(); char *cpu_quota_val(); char *pids_max_val(); @@ -77,11 +78,14 @@ jlong memory_soft_limit_in_bytes(); jlong memory_usage_in_bytes(); jlong memory_max_usage_in_bytes(); + char * cpu_cpuset_cpus(); char * cpu_cpuset_memory_nodes(); jlong pids_max(); jlong pids_current(); + void print_version_specific_info(outputStream* st); + const char * container_type() { return "cgroupv2"; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/osContainer_linux.cpp openjdk-17-17.0.6+10/src/hotspot/os/linux/osContainer_linux.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/osContainer_linux.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/osContainer_linux.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -42,8 +42,6 @@ * we are running under cgroup control. */ void OSContainer::init() { - jlong mem_limit; - assert(!_is_initialized, "Initializing OSContainer more than once"); _is_initialized = true; @@ -59,15 +57,8 @@ if (cgroup_subsystem == NULL) { return; // Required subsystem files not found or other error } - // We need to update the amount of physical memory now that - // cgroup subsystem files have been processed. - if ((mem_limit = cgroup_subsystem->memory_limit_in_bytes()) > 0) { - os::Linux::set_physical_memory(mem_limit); - log_info(os, container)("Memory Limit is: " JLONG_FORMAT, mem_limit); - } _is_containerized = true; - } const char * OSContainer::container_type() { @@ -100,6 +91,11 @@ return cgroup_subsystem->memory_max_usage_in_bytes(); } +void OSContainer::print_version_specific_info(outputStream* st) { + assert(cgroup_subsystem != NULL, "cgroup subsystem not available"); + cgroup_subsystem->print_version_specific_info(st); +} + char * OSContainer::cpu_cpuset_cpus() { assert(cgroup_subsystem != NULL, "cgroup subsystem not available"); return cgroup_subsystem->cpu_cpuset_cpus(); @@ -139,3 +135,16 @@ assert(cgroup_subsystem != NULL, "cgroup subsystem not available"); return cgroup_subsystem->pids_current(); } + +void OSContainer::print_container_helper(outputStream* st, jlong j, const char* metrics) { + st->print("%s: ", metrics); + if (j > 0) { + if (j >= 1024) { + st->print_cr(UINT64_FORMAT " k", uint64_t(j) / 1024); + } else { + st->print_cr(UINT64_FORMAT, uint64_t(j)); + } + } else { + st->print_cr("%s", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); + } +} diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/osContainer_linux.hpp openjdk-17-17.0.6+10/src/hotspot/os/linux/osContainer_linux.hpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/osContainer_linux.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/osContainer_linux.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -27,6 +27,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +#include "utilities/ostream.hpp" #include "memory/allocation.hpp" #define OSCONTAINER_ERROR (-2) @@ -43,6 +44,9 @@ public: static void init(); + static void print_version_specific_info(outputStream* st); + static void print_container_helper(outputStream* st, jlong j, const char* metrics); + static inline bool is_containerized(); static const char * container_type(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/os_linux.cpp openjdk-17-17.0.6+10/src/hotspot/os/linux/os_linux.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/os_linux.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/os_linux.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -195,15 +195,12 @@ julong avail_mem; if (OSContainer::is_containerized()) { - jlong mem_limit, mem_usage; - if ((mem_limit = OSContainer::memory_limit_in_bytes()) < 1) { - log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value", - mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit); - } + jlong mem_limit = OSContainer::memory_limit_in_bytes(); + jlong mem_usage; if (mem_limit > 0 && (mem_usage = OSContainer::memory_usage_in_bytes()) < 1) { log_debug(os, container)("container memory usage failed: " JLONG_FORMAT ", using host value", mem_usage); } - if (mem_limit > 0 && mem_usage > 0 ) { + if (mem_limit > 0 && mem_usage > 0) { avail_mem = mem_limit > mem_usage ? (julong)mem_limit - (julong)mem_usage : 0; log_trace(os)("available container memory: " JULONG_FORMAT, avail_mem); return avail_mem; @@ -224,8 +221,6 @@ log_trace(os)("total container memory: " JLONG_FORMAT, mem_limit); return mem_limit; } - log_debug(os, container)("container memory limit %s: " JLONG_FORMAT ", using host value", - mem_limit == OSCONTAINER_ERROR ? "failed" : "unlimited", mem_limit); } phys_mem = Linux::physical_memory(); @@ -354,6 +349,14 @@ return (pid_t)rslt; } +// Returns the amount of swap currently configured, in bytes. +// This can change at any time. +julong os::Linux::host_swap() { + struct sysinfo si; + sysinfo(&si); + return (julong)si.totalswap; +} + // Most versions of linux have a bug where the number of processors are // determined by looking at the /proc file system. In a chroot environment, // the system call returns 1. @@ -2275,19 +2278,6 @@ } } -static void print_container_helper(outputStream* st, jlong j, const char* metrics) { - st->print("%s: ", metrics); - if (j > 0) { - if (j >= 1024) { - st->print_cr(UINT64_FORMAT " k", uint64_t(j) / 1024); - } else { - st->print_cr(UINT64_FORMAT, uint64_t(j)); - } - } else { - st->print_cr("%s", j == OSCONTAINER_ERROR ? "not supported" : "unlimited"); - } -} - bool os::Linux::print_container_info(outputStream* st) { if (!OSContainer::is_containerized()) { st->print_cr("container information not found."); @@ -2343,11 +2333,13 @@ st->print_cr("%s", i == OSCONTAINER_ERROR ? "not supported" : "no shares"); } - print_container_helper(st, OSContainer::memory_limit_in_bytes(), "memory_limit_in_bytes"); - print_container_helper(st, OSContainer::memory_and_swap_limit_in_bytes(), "memory_and_swap_limit_in_bytes"); - print_container_helper(st, OSContainer::memory_soft_limit_in_bytes(), "memory_soft_limit_in_bytes"); - print_container_helper(st, OSContainer::memory_usage_in_bytes(), "memory_usage_in_bytes"); - print_container_helper(st, OSContainer::memory_max_usage_in_bytes(), "memory_max_usage_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::memory_limit_in_bytes(), "memory_limit_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::memory_and_swap_limit_in_bytes(), "memory_and_swap_limit_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::memory_soft_limit_in_bytes(), "memory_soft_limit_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::memory_usage_in_bytes(), "memory_usage_in_bytes"); + OSContainer::print_container_helper(st, OSContainer::memory_max_usage_in_bytes(), "memory_max_usage_in_bytes"); + + OSContainer::print_version_specific_info(st); jlong j = OSContainer::pids_max(); st->print("maximum number of tasks: "); diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/linux/os_linux.hpp openjdk-17-17.0.6+10/src/hotspot/os/linux/os_linux.hpp --- openjdk-17-17.0.5+8/src/hotspot/os/linux/os_linux.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/linux/os_linux.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -59,8 +59,6 @@ static int _page_size; static julong available_memory(); - static julong physical_memory() { return _physical_memory; } - static void set_physical_memory(julong phys_mem) { _physical_memory = phys_mem; } static int active_processor_count(); static void initialize_system_info(); @@ -136,6 +134,9 @@ static int page_size(void) { return _page_size; } static void set_page_size(int val) { _page_size = val; } + static julong physical_memory() { return _physical_memory; } + static julong host_swap(); + static intptr_t* ucontext_get_sp(const ucontext_t* uc); static intptr_t* ucontext_get_fp(const ucontext_t* uc); diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/posix/signals_posix.cpp openjdk-17-17.0.6+10/src/hotspot/os/posix/signals_posix.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/posix/signals_posix.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/posix/signals_posix.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -341,7 +341,7 @@ }; //////////////////////////////////////////////////////////////////////////////// -// sun.misc.Signal support +// sun.misc.Signal and BREAK_SIGNAL support void jdk_misc_signal_init() { // Initialize signal structures @@ -562,11 +562,6 @@ { assert(info != NULL && ucVoid != NULL, "sanity"); - if (sig == BREAK_SIGNAL) { - assert(!ReduceSignalUsage, "Should not happen with -Xrs/-XX:+ReduceSignalUsage"); - return true; // ignore it - } - // Note: it's not uncommon that JNI code uses signal/sigset to install, // then restore certain signal handler (e.g. to temporarily block SIGPIPE, // or have a SIGILL handler when detecting CPU type). When that happens, @@ -602,7 +597,7 @@ if (!signal_was_handled) { // Handle SafeFetch access. #ifndef ZERO - if (uc != NULL) { + if ((sig == SIGSEGV || sig == SIGBUS) && uc != NULL) { address pc = os::Posix::ucontext_get_pc(uc); if (StubRoutines::is_safefetch_fault(pc)) { os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); @@ -1202,7 +1197,7 @@ return -1; } -void set_signal_handler(int sig, bool do_check = true) { +void set_signal_handler(int sig) { // Check for overwrite. struct sigaction oldAct; sigaction(sig, (struct sigaction*)NULL, &oldAct); @@ -1244,9 +1239,10 @@ } #endif - // Save handler setup for later checking + // Save handler setup for possible later checking vm_handlers.set(sig, &sigAct); - do_check_signal_periodically[sig] = do_check; + + do_check_signal_periodically[sig] = true; int ret = sigaction(sig, &sigAct, &oldAct); assert(ret == 0, "check"); @@ -1285,11 +1281,24 @@ PPC64_ONLY(set_signal_handler(SIGTRAP);) set_signal_handler(SIGXFSZ); if (!ReduceSignalUsage) { - // This is just for early initialization phase. Intercepting the signal here reduces the risk - // that an attach client accidentally forces HotSpot to quit prematurely. We skip the periodic - // check because late initialization will overwrite it to UserHandler. - set_signal_handler(BREAK_SIGNAL, false); + // Install BREAK_SIGNAL's handler in early initialization phase, in + // order to reduce the risk that an attach client accidentally forces + // HotSpot to quit prematurely. + // The actual work for handling BREAK_SIGNAL is performed by the Signal + // Dispatcher thread, which is created and started at a much later point, + // see os::initialize_jdk_signal_support(). Any BREAK_SIGNAL received + // before the Signal Dispatcher thread is started is queued up via the + // pending_signals[BREAK_SIGNAL] counter, and will be processed by the + // Signal Dispatcher thread in a delayed fashion. + // + // Also note that HotSpot does NOT support signal chaining for BREAK_SIGNAL. + // Applications that require a custom BREAK_SIGNAL handler should run with + // -XX:+ReduceSignalUsage. Otherwise if libjsig is used together with + // -XX:+ReduceSignalUsage, libjsig will prevent changing BREAK_SIGNAL's + // handler to a custom handler. + os::signal(BREAK_SIGNAL, os::user_handler()); } + #if defined(__APPLE__) // lldb (gdb) installs both standard BSD signal handlers, and mach exception // handlers. By replacing the existing task exception handler, we disable lldb's mach @@ -1784,12 +1793,12 @@ signal_sets_init(); - install_signal_handlers(); - - // Initialize data for jdk.internal.misc.Signal + // Initialize data for jdk.internal.misc.Signal and BREAK_SIGNAL's handler. if (!ReduceSignalUsage) { jdk_misc_signal_init(); } + install_signal_handlers(); + return JNI_OK; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/posix/vmError_posix.cpp openjdk-17-17.0.6+10/src/hotspot/os/posix/vmError_posix.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/posix/vmError_posix.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/posix/vmError_posix.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -77,19 +77,21 @@ } // Needed to make it possible to call SafeFetch.. APIs in error handling. - if (uc && pc && StubRoutines::is_safefetch_fault(pc)) { - os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); - return; - } + if (sig == SIGSEGV || sig == SIGBUS) { + if (uc && pc && StubRoutines::is_safefetch_fault(pc)) { + os::Posix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); + return; + } - // Needed because asserts may happen in error handling too. + // Needed because asserts may happen in error handling too. #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - if (handle_assert_poison_fault(ucVoid, info->si_addr)) { - return; + if (info != NULL && info->si_addr == g_assert_poison) { + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return; + } } - } #endif // CAN_SHOW_REGISTERS_ON_ASSERT + } VMError::report_and_die(NULL, sig, pc, info, ucVoid); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os/windows/os_windows.cpp openjdk-17-17.0.6+10/src/hotspot/os/windows/os_windows.cpp --- openjdk-17-17.0.5+8/src/hotspot/os/windows/os_windows.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os/windows/os_windows.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -2266,6 +2266,15 @@ // Add a CTRL-C handler SetConsoleCtrlHandler(consoleHandler, TRUE); + + // Initialize sigbreakHandler. + // The actual work for handling CTRL-BREAK is performed by the Signal + // Dispatcher thread, which is created and started at a much later point, + // see os::initialize_jdk_signal_support(). Any CTRL-BREAK received + // before the Signal Dispatcher thread is started is queued up via the + // pending_signals[SIGBREAK] counter, and will be processed by the + // Signal Dispatcher thread in a delayed fashion. + os::signal(SIGBREAK, os::user_handler()); } void os::signal_notify(int sig) { @@ -4386,7 +4395,8 @@ SymbolEngine::recalc_search_path(); - // Initialize data for jdk.internal.misc.Signal + // Initialize data for jdk.internal.misc.Signal, and install CTRL-C and + // CTRL-BREAK handlers. if (!ReduceSignalUsage) { jdk_misc_signal_init(); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,7 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. + * Copyright (c) 2022, IBM Corp. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,33 +25,99 @@ */ #include "precompiled.hpp" +#include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.hpp" frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - intptr_t* sp = Atomic::load_acquire(&_anchor._last_Java_sp); + // Only called by current thread or when the thread is suspended. + // No memory barrier needed, here. Only writer must write sp last (for use by profiler). + intptr_t* sp = last_Java_sp(); address pc = _anchor.last_Java_pc(); // Last_Java_pc ist not set, if we come here from compiled code. - if (pc == NULL) - pc = (address) *(sp + 2); + // Assume spill slot for link register contains a suitable pc. + // Should have been filled by method entry code. + if (pc == NULL) { + pc = (address) *(sp + 2); + } return frame(sp, pc); } bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { - ucontext_t* uc = (ucontext_t*) ucontext; - *fr_addr = frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], - (address)uc->uc_mcontext.jmp_context.iar); - return true; + + // If we have a last_Java_frame, then we should use it even if + // isInJava == true. It should be more reliable than ucontext info. + if (has_last_Java_frame() && frame_anchor()->walkable()) { + intptr_t* sp = last_Java_sp(); + address pc = _anchor.last_Java_pc(); + // pc can be seen as null because not all writers use store pc + release store sp. + // Simply discard the sample in this very rare case. + if (pc == nullptr) return false; + *fr_addr = frame(sp, pc); + return true; + } + + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the ucontext + // if we were running Java code when SIGPROF came in. + if (isInJava) { + ucontext_t* uc = (ucontext_t*) ucontext; + address pc = (address)uc->uc_mcontext.jmp_context.iar; + + if (pc == NULL) { + // ucontext wasn't useful + return false; + } + + frame ret_frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], pc); + + if (ret_frame.fp() == NULL) { + // The found frame does not have a valid frame pointer. + // Bail out because this will create big trouble later on, either + // - when using istate, calculated as (NULL - ijava_state_size) or + // - when using fp() directly in safe_for_sender() + // + // There is no conclusive description (yet) how this could happen, but it does. + // For more details on what was observed, see thread_linux_s390.cpp + return false; + } + + if (ret_frame.is_interpreted_frame()) { + frame::ijava_state *istate = ret_frame.get_ijava_state(); + const Method *m = (const Method*)(istate->method); + if (!Method::is_valid_method(m)) return false; + if (!Metaspace::contains(m->constMethod())) return false; + + uint64_t reg_bcp = uc->uc_mcontext.jmp_context.gpr[14/*R14_bcp*/]; + uint64_t istate_bcp = istate->bcp; + uint64_t code_start = (uint64_t)(m->code_base()); + uint64_t code_end = (uint64_t)(m->code_base() + m->code_size()); + if (istate_bcp >= code_start && istate_bcp < code_end) { + // we have a valid bcp, don't touch it, do nothing + } else if (reg_bcp >= code_start && reg_bcp < code_end) { + istate->bcp = reg_bcp; + } else { + return false; + } + } + if (!ret_frame.safe_for_sender(this)) { + // nothing else to try if the frame isn't good + return false; + } + *fr_addr = ret_frame; + return true; + } + // nothing else to try + return false; } -// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Aix/PPC. +// Forte Analyzer AsyncGetCallTrace profiling support. bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) { - Unimplemented(); - return false; + return pd_get_top_frame_for_profiling(fr_addr, ucontext, isInJava); } void JavaThread::cache_global_variables() { } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -350,3 +350,9 @@ // Zero does not require an additional stack bang. return 0; } + +#if defined(AARCH64) && defined(__APPLE__) +void os::current_thread_enable_wx(WXMode mode) { + pthread_jit_write_protect_np(mode == WXExec); +} +#endif diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -468,9 +468,8 @@ st->print_cr("Register to memory mapping:"); st->cr(); for (int r = 0; r < ARM_REGS_IN_CONTEXT; r++) { - st->print_cr(" %-3s = " INTPTR_FORMAT, as_Register(r)->name(), reg_area[r]); + st->print(" %-3s = ", as_Register(r)->name()); print_location(st, reg_area[r]); - st->cr(); } st->cr(); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -31,7 +31,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - intptr_t* sp = Atomic::load_acquire(&_anchor._last_Java_sp); + // Only called by current thread or when the thread is suspended. + // No memory barrier needed, here. Only writer must write sp last (for use by profiler). + intptr_t* sp = last_Java_sp(); address pc = _anchor.last_Java_pc(); // Last_Java_pc ist not set, if we come here from compiled code. @@ -49,7 +51,12 @@ // If we have a last_Java_frame, then we should use it even if // isInJava == true. It should be more reliable than ucontext info. if (has_last_Java_frame() && frame_anchor()->walkable()) { - *fr_addr = pd_last_frame(); + intptr_t* sp = last_Java_sp(); + address pc = _anchor.last_Java_pc(); + // pc can be seen as null because not all writers use store pc + release store sp. + // Simply discard the sample in this very rare case. + if (pc == nullptr) return false; + *fr_addr = frame(sp, pc); return true; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -459,11 +459,26 @@ } juint os::cpu_microcode_revision() { + // Note: this code runs on startup, and therefore should not be slow, + // see JDK-8283200. + juint result = 0; - char data[2048] = {0}; // lines should fit in 2K buf - size_t len = sizeof(data); - FILE *fp = fopen("/proc/cpuinfo", "r"); + + // Attempt 1 (faster): Read the microcode version off the sysfs. + FILE *fp = fopen("/sys/devices/system/cpu/cpu0/microcode/version", "r"); + if (fp) { + int read = fscanf(fp, "%x", &result); + fclose(fp); + if (read > 0) { + return result; + } + } + + // Attempt 2 (slower): Read the microcode version off the procfs. + fp = fopen("/proc/cpuinfo", "r"); if (fp) { + char data[2048] = {0}; // lines should fit in 2K buf + size_t len = sizeof(data); while (!feof(fp)) { if (fgets(data, len, fp)) { if (strstr(data, "microcode") != NULL) { @@ -475,6 +490,7 @@ } fclose(fp); } + return result; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_zero/thread_linux_zero.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. - * Copyright 2009, 2010 Red Hat, Inc. + * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, Red Hat, Inc. 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 @@ -35,3 +35,40 @@ void JavaThread::cache_global_variables() { // nothing to do } + +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) { + if (has_last_Java_frame()) { + *fr_addr = pd_last_frame(); + return true; + } + + if (isInJava) { + // We know we are in Java, but there is no frame? + // Try to find the top-most Java frame on Zero stack then. + intptr_t* sp = zero_stack()->sp(); + ZeroFrame* zf = top_zero_frame(); + while (zf != NULL) { + if (zf->is_interpreter_frame()) { + interpreterState istate = zf->as_interpreter_frame()->interpreter_state(); + if (istate->self_link() == istate) { + // Valid interpreter state found, this is our frame. + *fr_addr = frame(zf, sp); + return true; + } + } + sp = ((intptr_t *) zf) + 1; + zf = zf->next(); + } + } + + // No dice. + return false; +} + +bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, + void* ucontext, + bool isInJava) { + return pd_get_top_frame_for_signal_handler(fr_addr, ucontext, isInJava); +} diff -Nru openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp --- openjdk-17-17.0.5+8/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/os_cpu/linux_zero/thread_linux_zero.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. + * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, Red Hat, Inc. 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 @@ -96,16 +96,10 @@ public: bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, - bool isInJava) { - ShouldNotCallThis(); - return false; // silence compile warning - } + bool isInJava); bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, - bool isInJava) { - ShouldNotCallThis(); - return false; // silence compile warning - } + bool isInJava); #endif // OS_CPU_LINUX_ZERO_THREAD_LINUX_ZERO_HPP diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_Canonicalizer.cpp openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_Canonicalizer.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_Canonicalizer.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_Canonicalizer.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -790,7 +790,7 @@ else if (lss_sux == gtr_sux) { cond = If::neq; tsux = lss_sux; fsux = eql_sux; } else if (eql_sux == gtr_sux) { cond = If::geq; tsux = eql_sux; fsux = lss_sux; } else { ShouldNotReachHere(); } - If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, cmp->state_before(), x->is_safepoint()); + If* canon = new If(cmp->x(), cond, nan_sux == tsux, cmp->y(), tsux, fsux, x->state_before(), x->is_safepoint()); if (cmp->x() == cmp->y()) { do_If(canon); } else { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_GraphBuilder.cpp openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_GraphBuilder.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_GraphBuilder.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_GraphBuilder.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -2154,8 +2154,7 @@ void GraphBuilder::new_instance(int klass_index) { ValueStack* state_before = copy_state_exhandling(); - bool will_link; - ciKlass* klass = stream()->get_klass(will_link); + ciKlass* klass = stream()->get_klass(); assert(klass->is_instance_klass(), "must be an instance klass"); NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before, stream()->is_unresolved_klass()); _memory->new_instance(new_instance); @@ -2170,8 +2169,7 @@ void GraphBuilder::new_object_array() { - bool will_link; - ciKlass* klass = stream()->get_klass(will_link); + ciKlass* klass = stream()->get_klass(); ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); NewArray* n = new NewObjectArray(klass, ipop(), state_before); apush(append_split(n)); @@ -2196,8 +2194,7 @@ void GraphBuilder::check_cast(int klass_index) { - bool will_link; - ciKlass* klass = stream()->get_klass(will_link); + ciKlass* klass = stream()->get_klass(); ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception(); CheckCast* c = new CheckCast(klass, apop(), state_before); apush(append_split(c)); @@ -2217,8 +2214,7 @@ void GraphBuilder::instance_of(int klass_index) { - bool will_link; - ciKlass* klass = stream()->get_klass(will_link); + ciKlass* klass = stream()->get_klass(); ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); InstanceOf* i = new InstanceOf(klass, apop(), state_before); ipush(append_split(i)); @@ -2252,8 +2248,7 @@ void GraphBuilder::new_multi_array(int dimensions) { - bool will_link; - ciKlass* klass = stream()->get_klass(will_link); + ciKlass* klass = stream()->get_klass(); ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); Values* dims = new Values(dimensions, dimensions, NULL); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_Runtime1.cpp openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_Runtime1.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/c1/c1_Runtime1.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/c1/c1_Runtime1.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1254,6 +1254,37 @@ #else // DEOPTIMIZE_WHEN_PATCHING +static bool is_patching_needed(JavaThread* current, Runtime1::StubID stub_id) { + if (stub_id == Runtime1::load_klass_patching_id || + stub_id == Runtime1::load_mirror_patching_id) { + // last java frame on stack + vframeStream vfst(current, true); + assert(!vfst.at_end(), "Java frame must exist"); + + methodHandle caller_method(current, vfst.method()); + int bci = vfst.bci(); + Bytecodes::Code code = caller_method()->java_code_at(bci); + + switch (code) { + case Bytecodes::_new: + case Bytecodes::_anewarray: + case Bytecodes::_multianewarray: + case Bytecodes::_instanceof: + case Bytecodes::_checkcast: { + Bytecode bc(caller_method(), caller_method->bcp_from(bci)); + constantTag tag = caller_method->constants()->tag_at(bc.get_index_u2(code)); + if (tag.is_unresolved_klass_in_error()) { + return false; // throws resolution error + } + break; + } + + default: break; + } + } + return true; +} + void Runtime1::patch_code(JavaThread* current, Runtime1::StubID stub_id) { NOT_PRODUCT(_patch_code_slowcase_cnt++); @@ -1271,10 +1302,12 @@ frame caller_frame = runtime_frame.sender(®_map); assert(caller_frame.is_compiled_frame(), "Wrong frame type"); - // Make sure the nmethod is invalidated, i.e. made not entrant. - nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); - if (nm != NULL) { - nm->make_not_entrant(); + if (is_patching_needed(current, stub_id)) { + // Make sure the nmethod is invalidated, i.e. made not entrant. + nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); + if (nm != NULL) { + nm->make_not_entrant(); + } } Deoptimization::deoptimize_frame(current, caller_frame.id()); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/ci/ciInstanceKlass.cpp openjdk-17-17.0.6+10/src/hotspot/share/ci/ciInstanceKlass.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/ci/ciInstanceKlass.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/ci/ciInstanceKlass.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -355,7 +355,7 @@ ciKlass::print_impl(st); GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i(loader()));) if (is_loaded()) { - st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", + st->print(" initialized=%s finalized=%s subklass=%s size=%d flags=", bool_to_str(is_initialized()), bool_to_str(has_finalizer()), bool_to_str(has_subklass()), @@ -370,8 +370,6 @@ if (_java_mirror) { st->print(" mirror=PRESENT"); } - } else { - st->print(" loaded=false"); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/ci/ciKlass.cpp openjdk-17-17.0.6+10/src/hotspot/share/ci/ciKlass.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/ci/ciKlass.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/ci/ciKlass.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -233,6 +233,7 @@ void ciKlass::print_impl(outputStream* st) { st->print(" name="); print_name_on(st); + st->print(" loaded=%s", (is_loaded() ? "true" : "false")); } // ------------------------------------------------------------------ diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/ci/ciStreams.cpp openjdk-17-17.0.6+10/src/hotspot/share/ci/ciStreams.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/ci/ciStreams.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/ci/ciStreams.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -23,9 +23,10 @@ */ #include "precompiled.hpp" -#include "ci/ciCallSite.hpp" #include "ci/ciConstant.hpp" #include "ci/ciField.hpp" +#include "ci/ciKlass.hpp" +#include "ci/ciObjArrayKlass.hpp" #include "ci/ciStreams.hpp" #include "ci/ciSymbols.hpp" #include "ci/ciUtilities.inline.hpp" @@ -191,6 +192,21 @@ return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder); } +// ciBytecodeStream::get_klass +// +// If this bytecode is a new, newarray, multianewarray, instanceof, +// or checkcast, get the referenced klass. Retuns an unloaded ciKlass +// if the referenced klass is not accessible. +ciKlass* ciBytecodeStream::get_klass() { + bool will_link; + ciKlass* klass = get_klass(will_link); + if (!will_link && klass->is_loaded()) { // klass not accessible + VM_ENTRY_MARK; + klass = CURRENT_ENV->get_unloaded_klass(_holder, klass->name()); + } + return klass; +} + // ------------------------------------------------------------------ // ciBytecodeStream::get_constant_raw_index // diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/ci/ciStreams.hpp openjdk-17-17.0.6+10/src/hotspot/share/ci/ciStreams.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/ci/ciStreams.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/ci/ciStreams.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -217,6 +217,7 @@ // If this bytecode is a new, newarray, multianewarray, instanceof, // or checkcast, get the referenced klass. + ciKlass* get_klass(); ciKlass* get_klass(bool& will_link); int get_klass_index() const; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/classfile/javaClasses.cpp openjdk-17-17.0.6+10/src/hotspot/share/classfile/javaClasses.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/classfile/javaClasses.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/classfile/javaClasses.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -4480,6 +4480,7 @@ oop base = vmClasses::System_klass()->static_field_base_raw(); int never = base->int_field(_static_never_offset); allowed = (base->int_field(_static_allow_security_offset) != never); + initialized = true; } return allowed; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/classfile/vmIntrinsics.hpp openjdk-17-17.0.6+10/src/hotspot/share/classfile/vmIntrinsics.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/classfile/vmIntrinsics.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/classfile/vmIntrinsics.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -460,7 +460,7 @@ do_class(java_util_Base64_Decoder, "java/util/Base64$Decoder") \ do_intrinsic(_base64_decodeBlock, java_util_Base64_Decoder, decodeBlock_name, decodeBlock_signature, F_R) \ do_name(decodeBlock_name, "decodeBlock") \ - do_signature(decodeBlock_signature, "([BII[BIZ)I") \ + do_signature(decodeBlock_signature, "([BII[BIZZ)I") \ \ /* support for com.sun.crypto.provider.GHASH */ \ do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH") \ diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/code/codeCache.cpp openjdk-17-17.0.6+10/src/hotspot/share/code/codeCache.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/code/codeCache.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/code/codeCache.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -296,19 +296,20 @@ const size_t alignment = MAX2(page_size(false, 8), (size_t) os::vm_allocation_granularity()); non_nmethod_size = align_up(non_nmethod_size, alignment); profiled_size = align_down(profiled_size, alignment); + non_profiled_size = align_down(non_profiled_size, alignment); // Reserve one continuous chunk of memory for CodeHeaps and split it into // parts for the individual heaps. The memory layout looks like this: // ---------- high ----------- // Non-profiled nmethods - // Profiled nmethods // Non-nmethods + // Profiled nmethods // ---------- low ------------ ReservedCodeSpace rs = reserve_heap_memory(cache_size); - ReservedSpace non_method_space = rs.first_part(non_nmethod_size); - ReservedSpace rest = rs.last_part(non_nmethod_size); - ReservedSpace profiled_space = rest.first_part(profiled_size); - ReservedSpace non_profiled_space = rest.last_part(profiled_size); + ReservedSpace profiled_space = rs.first_part(profiled_size); + ReservedSpace rest = rs.last_part(profiled_size); + ReservedSpace non_method_space = rest.first_part(non_nmethod_size); + ReservedSpace non_profiled_space = rest.last_part(non_nmethod_size); // Non-nmethods (stubs, adapters, ...) add_heap(non_method_space, "CodeHeap 'non-nmethods'", CodeBlobType::NonNMethod); @@ -898,6 +899,23 @@ return max_cap; } +bool CodeCache::is_non_nmethod(address addr) { + CodeHeap* blob = get_code_heap(CodeBlobType::NonNMethod); + return blob->contains(addr); +} + +size_t CodeCache::max_distance_to_non_nmethod() { + if (!SegmentedCodeCache) { + return ReservedCodeCacheSize; + } else { + CodeHeap* blob = get_code_heap(CodeBlobType::NonNMethod); + // the max distance is minimized by placing the NonNMethod segment + // in between MethodProfiled and MethodNonProfiled segments + size_t dist1 = (size_t)blob->high() - (size_t)_low_bound; + size_t dist2 = (size_t)_high_bound - (size_t)blob->low(); + return dist1 > dist2 ? dist1 : dist2; + } +} // Returns the reverse free ratio. E.g., if 25% (1/4) of the code cache // is free, reverse_free_ratio() returns 4. @@ -1295,6 +1313,7 @@ event.set_adaptorCount(heap->adapter_count()); event.set_unallocatedCapacity(heap->unallocated_capacity()); event.set_fullCount(heap->full_count()); + event.set_codeCacheMaxCapacity(CodeCache::max_capacity()); event.commit(); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/code/codeCache.hpp openjdk-17-17.0.6+10/src/hotspot/share/code/codeCache.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/code/codeCache.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/code/codeCache.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -213,6 +213,9 @@ static double reverse_free_ratio(); + static size_t max_distance_to_non_nmethod(); + static bool is_non_nmethod(address addr); + static void clear_inline_caches(); // clear all inline caches static void cleanup_inline_caches(); // clean unloaded/zombie nmethods from inline caches diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shared/barrierSet.hpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shared/barrierSet.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shared/barrierSet.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shared/barrierSet.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -310,10 +310,6 @@ static void clone_in_heap(oop src, oop dst, size_t size) { Raw::clone(src, dst, size); } - - static oop resolve(oop obj) { - return Raw::resolve(obj); - } }; }; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shared/collectedHeap.hpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shared/collectedHeap.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shared/collectedHeap.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shared/collectedHeap.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2022, 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 @@ -77,7 +77,7 @@ // ShenandoahHeap // ZCollectedHeap // -class CollectedHeap : public CHeapObj { +class CollectedHeap : public CHeapObj { friend class VMStructs; friend class JVMCIVMStructs; friend class IsGCActiveMark; // Block structured external access to _is_gc_active diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1080,7 +1080,8 @@ } else if (can_reshape && n->Opcode() == Op_If && ShenandoahBarrierC2Support::is_heap_stable_test(n) && - n->in(0) != NULL) { + n->in(0) != NULL && + n->outcnt() == 2) { Node* dom = n->in(0); Node* prev_dom = n; int op = n->Opcode(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -65,19 +65,18 @@ } ShenandoahHeuristics* ShenandoahIUMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); - } else { - vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); - } + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); + if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahAggressiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { + return new ShenandoahStaticHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahAdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { + return new ShenandoahCompactHeuristics(); + } + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return NULL; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" #include "runtime/globals_extension.hpp" +#include "runtime/java.hpp" void ShenandoahPassiveMode::initialize_flags() const { // Do not allow concurrent cycles. @@ -55,9 +56,8 @@ // No barriers are required to run. } ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - return new ShenandoahPassiveHeuristics(); + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); - return NULL; + return new ShenandoahPassiveHeuristics(); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -53,19 +53,18 @@ } ShenandoahHeuristics* ShenandoahSATBMode::initialize_heuristics() const { - if (ShenandoahGCHeuristics != NULL) { - if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { - return new ShenandoahAggressiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { - return new ShenandoahStaticHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { - return new ShenandoahAdaptiveHeuristics(); - } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { - return new ShenandoahCompactHeuristics(); - } else { - vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); - } + if (ShenandoahGCHeuristics == NULL) { + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option (null)"); } - ShouldNotReachHere(); + if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) { + return new ShenandoahAggressiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) { + return new ShenandoahStaticHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) { + return new ShenandoahAdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) { + return new ShenandoahCompactHeuristics(); + } + vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option"); return NULL; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Red Hat, Inc. All rights reserved. + * Copyright (c) 2015, 2022, Red Hat, Inc. 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 @@ -84,13 +84,8 @@ _heap->in_collection_set(obj)) { // Subsumes NULL-check assert(obj != NULL, "cset check must have subsumed NULL-check"); oop fwd = resolve_forwarded_not_null(obj); - // TODO: It should not be necessary to check evac-in-progress here. - // We do it for mark-compact, which may have forwarded objects, - // and objects in cset and gets here via runtime barriers. - // We can probably fix this as soon as mark-compact has its own - // marking phase. if (obj == fwd && _heap->is_evacuation_in_progress()) { - Thread* t = Thread::current(); + Thread* t = Thread::current(); ShenandoahEvacOOMScope oom_evac_scope(t); return _heap->evacuate_object(obj, t); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -66,6 +66,10 @@ _gc_timer(ShenandoahHeap::heap()->gc_timer()), _preserved_marks(new PreservedMarksSet(true)) {} +ShenandoahFullGC::~ShenandoahFullGC() { + delete _preserved_marks; +} + bool ShenandoahFullGC::collect(GCCause::Cause cause) { vmop_entry_full(cause); // Always success diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahFullGC.hpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahFullGC.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahFullGC.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahFullGC.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -66,6 +66,7 @@ public: ShenandoahFullGC(); + ~ShenandoahFullGC(); bool collect(GCCause::Cause cause); private: diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -416,7 +416,7 @@ vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option"); } } else { - ShouldNotReachHere(); + vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option (null)"); } _gc_mode->initialize_flags(); if (_gc_mode->is_diagnostic() && !UnlockDiagnosticVMOptions) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/gc/z/zDriver.cpp openjdk-17-17.0.6+10/src/hotspot/share/gc/z/zDriver.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/gc/z/zDriver.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/gc/z/zDriver.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -493,6 +493,11 @@ // Run GC gc(request); + if (should_terminate()) { + // Abort + break; + } + // Notify GC completed _gc_cycle_port.ack(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/interpreter/bytecode.hpp openjdk-17-17.0.6+10/src/hotspot/share/interpreter/bytecode.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/interpreter/bytecode.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/interpreter/bytecode.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -77,9 +77,11 @@ int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const { assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); address p = addr_at(is_wide ? 2 : 1); - if (can_use_native_byte_order(bc, is_wide)) + if (can_use_native_byte_order(bc, is_wide)) { return Bytes::get_native_u2(p); - else return Bytes::get_Java_u2(p); + } else { + return Bytes::get_Java_u2(p); + } } int get_index_u1_cpcache(Bytecodes::Code bc) const { assert_same_format_as(bc); assert_index_size(1, bc); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/interpreter/interpreter.hpp openjdk-17-17.0.6+10/src/hotspot/share/interpreter/interpreter.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/interpreter/interpreter.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/interpreter/interpreter.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -46,10 +46,10 @@ friend class VMStructs; friend class CodeCacheDumper; // possible extension [do not remove] private: - int _size; // the size in bytes - const char* _description; // a description of the codelet, for debugging & printing - Bytecodes::Code _bytecode; // associated bytecode if any NOT_PRODUCT(CodeStrings _strings;) // Comments for annotating assembler output. + const char* _description; // A description of the codelet, for debugging & printing + int _size; // The codelet size in bytes + Bytecodes::Code _bytecode; // Associated bytecode, if any public: // Initialization/finalization diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/interpreter/templateInterpreter.cpp openjdk-17-17.0.6+10/src/hotspot/share/interpreter/templateInterpreter.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/interpreter/templateInterpreter.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/interpreter/templateInterpreter.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -47,7 +47,11 @@ // allocate interpreter int code_size = InterpreterCodeSize; NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space - _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, + // 270+ interpreter codelets are generated and each of them is required to be aligned to + // CodeEntryAlignment twice. So we need additional size due to alignment. + int max_aligned_codelets = 280; + int max_aligned_bytes = max_aligned_codelets * CodeEntryAlignment * 2; + _code = new StubQueue(new InterpreterCodeletInterface, code_size + max_aligned_bytes, NULL, "Interpreter"); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/metadata/metadata.xml openjdk-17-17.0.6+10/src/hotspot/share/jfr/metadata/metadata.xml --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/metadata/metadata.xml 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/metadata/metadata.xml 2023-01-10 13:21:55.000000000 +0000 @@ -494,6 +494,11 @@ + + + + + @@ -548,6 +553,7 @@ + diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -119,7 +119,9 @@ #ifdef ASSERT static void assert_lease(const BufferPtr buffer) { - assert(buffer != NULL, "invariant"); + if (buffer == nullptr) { + return; + } assert(buffer->acquired_by_self(), "invariant"); assert(buffer->lease(), "invariant"); } @@ -220,8 +222,9 @@ return NULL; } BufferPtr new_buffer = lease(old, thread, used + requested); - assert(new_buffer != NULL, "invariant"); - migrate_outstanding_writes(old, new_buffer, used, requested); + if (new_buffer != nullptr) { + migrate_outstanding_writes(old, new_buffer, used, requested); + } retire(old); return new_buffer; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/repository/jfrChunk.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -47,6 +47,8 @@ const jlong now = seconds * 1000000000 + nanos; if (now > last) { last = now; + } else { + ++last; } return last; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrBuffer.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -35,13 +35,15 @@ _size(0), _header_size(0), _flags(0), - _context(0) {} + _context(0) + LP64_ONLY(COMMA _pad(0)) {} bool JfrBuffer::initialize(size_t header_size, size_t size) { assert(_next == NULL, "invariant"); assert(_identity == NULL, "invariant"); - _header_size = (u2)header_size; - _size = (u4)(size / BytesPerWord); + assert(header_size <= max_jushort, "invariant"); + _header_size = static_cast(header_size); + _size = size; set_pos(start()); set_top(start()); assert(free_size() == size, "invariant"); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrBuffer.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -70,10 +70,11 @@ const void* _identity; u1* _pos; mutable const u1* _top; - u4 _size; + size_t _size; u2 _header_size; u1 _flags; u1 _context; + LP64_ONLY(const u4 _pad;) const u1* stable_top() const; @@ -125,7 +126,7 @@ void release_critical_section_top(const u1* new_top); size_t size() const { - return _size * BytesPerWord; + return _size; } size_t total_size() const { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/recorder/storage/jfrMemorySpace.inline.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -202,16 +202,24 @@ // allocations are even multiples of the mspace min size static inline size_t align_allocation_size(size_t requested_size, size_t min_element_size) { + if (requested_size > static_cast(min_intx)) { + assert(false, "requested size: " SIZE_FORMAT " is too large", requested_size); + return 0; + } u8 alloc_size_bytes = min_element_size; while (requested_size > alloc_size_bytes) { alloc_size_bytes <<= 1; } - return (size_t)alloc_size_bytes; + assert(alloc_size_bytes <= static_cast(min_intx), "invariant"); + return static_cast(alloc_size_bytes); } template class RetrievalPolicy, typename FreeListType, typename FullListType, bool epoch_aware> inline typename FreeListType::NodePtr JfrMemorySpace::allocate(size_t size) { const size_t aligned_size_bytes = align_allocation_size(size, _min_element_size); + if (aligned_size_bytes == 0) { + return NULL; + } void* const allocation = JfrCHeapObj::new_array(aligned_size_bytes + sizeof(Node)); if (allocation == NULL) { return NULL; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp openjdk-17-17.0.6+10/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -73,6 +73,7 @@ inline void WriterHost::write(const T* value, size_t len) { assert(value != NULL, "invariant"); assert(len > 0, "invariant"); + assert(len <= max_jint, "invariant"); // Might need T + 1 size u1* const pos = ensure_size(sizeof(T) * len + len); if (pos) { @@ -125,8 +126,9 @@ inline void WriterHost::be_write(const T* value, size_t len) { assert(value != NULL, "invariant"); assert(len > 0, "invariant"); - // Might need T + 1 size - u1* const pos = ensure_size(sizeof(T) * len + len); + assert(len <= max_jint, "invariant"); + // Big endian writes map one-to-one for length, so no extra space is needed. + u1* const pos = ensure_size(sizeof(T) * len); if (pos) { this->set_current_pos(BE::be_write(value, len, pos)); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp openjdk-17-17.0.6+10/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -647,6 +647,16 @@ return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj)); C2V_END +C2V_VMENTRY_NULL(jobject, getUncachedStringInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index)) + constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool)); + constantTag tag = cp->tag_at(index); + if (!tag.is_string()) { + JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected constant pool tag at index %d: %d", index, tag.value())); + } + oop obj = cp->uncached_string_at(index, CHECK_NULL); + return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj)); +C2V_END + C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index)) constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool)); return cp->name_and_type_ref_index_at(index); @@ -1783,9 +1793,6 @@ } InstanceKlass* iklass = InstanceKlass::cast(klass); - // Ensure class is linked - iklass->link_class(CHECK_NULL); - GrowableArray constructors_array; for (int i = 0; i < iklass->methods()->length(); i++) { Method* m = iklass->methods()->at(i); @@ -1813,9 +1820,6 @@ } InstanceKlass* iklass = InstanceKlass::cast(klass); - // Ensure class is linked - iklass->link_class(CHECK_NULL); - GrowableArray methods_array; for (int i = 0; i < iklass->methods()->length(); i++) { Method* m = iklass->methods()->at(i); @@ -2690,6 +2694,7 @@ {CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)}, {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, {CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)}, + {CC "getUncachedStringInPool", CC "(" HS_CONSTANT_POOL "I)" JAVACONSTANT, FN_PTR(getUncachedStringInPool)}, {CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)}, {CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)}, {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)}, diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/oops/accessBackend.hpp openjdk-17-17.0.6+10/src/hotspot/share/oops/accessBackend.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/oops/accessBackend.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/oops/accessBackend.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -63,8 +63,7 @@ BARRIER_ATOMIC_XCHG, BARRIER_ATOMIC_XCHG_AT, BARRIER_ARRAYCOPY, - BARRIER_CLONE, - BARRIER_RESOLVE + BARRIER_CLONE }; template @@ -114,7 +113,6 @@ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, size_t length); typedef void (*clone_func_t)(oop src, oop dst, size_t size); - typedef oop (*resolve_func_t)(oop obj); }; template @@ -141,7 +139,6 @@ ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t); ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t); ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t); - ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t); #undef ACCESS_GENERATE_ACCESS_FUNCTION template @@ -391,8 +388,6 @@ size_t length); static void clone(oop src, oop dst, size_t size); - - static oop resolve(oop obj) { return obj; } }; // Below is the implementation of the first 4 steps of the template pipeline: @@ -574,18 +569,6 @@ } }; - template - struct RuntimeDispatch: AllStatic { - typedef typename AccessFunction::type func_t; - static func_t _resolve_func; - - static oop resolve_init(oop obj); - - static inline oop resolve(oop obj) { - return _resolve_func(obj); - } - }; - // Initialize the function pointers to point to the resolving function. template typename AccessFunction::type @@ -627,10 +610,6 @@ typename AccessFunction::type RuntimeDispatch::_clone_func = &clone_init; - template - typename AccessFunction::type - RuntimeDispatch::_resolve_func = &resolve_init; - // Step 3: Pre-runtime dispatching. // The PreRuntimeDispatch class is responsible for filtering the barrier strength // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/oops/access.hpp openjdk-17-17.0.6+10/src/hotspot/share/oops/access.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/oops/access.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/oops/access.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -57,7 +57,6 @@ // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value. // * arraycopy: Copy data from one heap array to another heap array. The ArrayAccess class has convenience functions for this. // * clone: Clone the contents of an object to a newly allocated object. -// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition. // // == IMPLEMENTATION == // Each access goes through the following steps in a template pipeline. diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/oops/access.inline.hpp openjdk-17-17.0.6+10/src/hotspot/share/oops/access.inline.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/oops/access.inline.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/oops/access.inline.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -200,13 +200,6 @@ } }; - template - struct PostRuntimeDispatch: public AllStatic { - static oop access_barrier(oop obj) { - return GCBarrierType::resolve(obj); - } - }; - // Resolving accessors with barriers from the barrier set happens in two steps. // 1. Expand paths with runtime-decorators, e.g. is UseCompressedOops on or off. // 2. Expand paths for each BarrierSet available in the system. @@ -354,13 +347,6 @@ _clone_func = function; function(src, dst, size); } - - template - oop RuntimeDispatch::resolve_init(oop obj) { - func_t function = BarrierResolver::resolve_barrier(); - _resolve_func = function; - return function(obj); - } } #endif // SHARE_OOPS_ACCESS_INLINE_HPP diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/oops/generateOopMap.cpp openjdk-17-17.0.6+10/src/hotspot/share/oops/generateOopMap.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/oops/generateOopMap.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/oops/generateOopMap.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -547,7 +547,13 @@ case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: (*jmpFct)(this, bcs->dest(), data); - (*jmpFct)(this, bci + 3, data); + // Class files verified by the old verifier can have a conditional branch + // as their last bytecode, provided the conditional branch is unreachable + // during execution. Check if this instruction is the method's last bytecode + // and, if so, don't call the jmpFct. + if (bci + 3 < method()->code_size()) { + (*jmpFct)(this, bci + 3, data); + } break; case Bytecodes::_goto: diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/library_call.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/library_call.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/library_call.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/library_call.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1551,12 +1551,19 @@ return false; } + // Save state and restore on bailout + uint old_sp = sp(); + SafePointNode* old_map = clone_map(); + value = must_be_not_null(value, true); Node* adr = array_element_address(value, index, T_CHAR); if (adr->is_top()) { + set_map(old_map); + set_sp(old_sp); return false; } + old_map->destruct(&_gvn); if (is_store) { access_store_at(value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED); } else { @@ -6416,7 +6423,7 @@ address stubAddr; const char *stubName; assert(UseBASE64Intrinsics, "need Base64 intrinsics support"); - assert(callee()->signature()->size() == 6, "base64_decodeBlock has 6 parameters"); + assert(callee()->signature()->size() == 7, "base64_decodeBlock has 7 parameters"); stubAddr = StubRoutines::base64_decodeBlock(); stubName = "decodeBlock"; @@ -6428,6 +6435,7 @@ Node* dest = argument(4); Node* dest_offset = argument(5); Node* isURL = argument(6); + Node* isMIME = argument(7); src = must_be_not_null(src, true); dest = must_be_not_null(dest, true); @@ -6440,7 +6448,7 @@ Node* call = make_runtime_call(RC_LEAF, OptoRuntime::base64_decodeBlock_Type(), stubAddr, stubName, TypePtr::BOTTOM, - src_start, src_offset, len, dest_start, dest_offset, isURL); + src_start, src_offset, len, dest_start, dest_offset, isURL, isMIME); Node* result = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); set_result(result); return true; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/loopnode.hpp openjdk-17-17.0.6+10/src/hotspot/share/opto/loopnode.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/loopnode.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/loopnode.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -924,6 +924,8 @@ IdealLoopTree* outer_loop, Node* input_proj); Node* clone_skeleton_predicate_bool(Node* iff, Node* new_init, Node* new_stride, Node* control); static bool skeleton_predicate_has_opaque(IfNode* iff); + static void count_opaque_loop_nodes(Node* n, uint& init, uint& stride); + static bool subgraph_has_opaque(Node* n); static void get_skeleton_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque = false); void update_main_loop_skeleton_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con); void copy_skeleton_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* init, Node* stride); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/loopopts.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/loopopts.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/loopopts.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/loopopts.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -2055,11 +2055,18 @@ Node* c = phase->get_ctrl(u); IdealLoopTree* u_loop = phase->get_loop(c); assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only"); - if (outer_loop->is_member(u_loop) || - // nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of - // the outer loop too - (u->in(0) != NULL && outer_loop->is_member(phase->get_loop(u->in(0))))) { + if (outer_loop->is_member(u_loop)) { wq.push(u); + } else { + // nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of + // the outer loop too + Node* u_c = u->in(0); + if (u_c != NULL) { + IdealLoopTree* u_c_loop = phase->get_loop(u_c); + if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) { + wq.push(u); + } + } } } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/loopTransform.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/loopTransform.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/loopTransform.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/loopTransform.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1304,7 +1304,8 @@ } } -static bool skeleton_follow_inputs(Node* n, int op) { +static bool skeleton_follow_inputs(Node* n) { + int op = n->Opcode(); return (n->is_Bool() || n->is_Cmp() || op == Op_AndL || @@ -1322,31 +1323,27 @@ op == Op_CastII); } +bool PhaseIdealLoop::subgraph_has_opaque(Node* n) { + if (n->Opcode() == Op_OpaqueLoopInit || n->Opcode() == Op_OpaqueLoopStride) { + return true; + } + if (!skeleton_follow_inputs(n)) { + return false; + } + uint init; + uint stride; + count_opaque_loop_nodes(n, init, stride); + return init != 0 || stride != 0; +} + + bool PhaseIdealLoop::skeleton_predicate_has_opaque(IfNode* iff) { + uint init; + uint stride; + count_opaque_loop_nodes(iff->in(1)->in(1), init, stride); +#ifdef ASSERT ResourceMark rm; Unique_Node_List wq; - wq.push(iff->in(1)->in(1)); - uint init = 0; - uint stride = 0; - for (uint i = 0; i < wq.size(); i++) { - Node* n = wq.at(i); - int op = n->Opcode(); - if (skeleton_follow_inputs(n, op)) { - for (uint j = 1; j < n->req(); j++) { - Node* m = n->in(j); - if (m != NULL) { - wq.push(m); - } - } - continue; - } - if (n->Opcode() == Op_OpaqueLoopInit) { - init++; - } else if (n->Opcode() == Op_OpaqueLoopStride) { - stride++; - } - } -#ifdef ASSERT wq.clear(); wq.push(iff->in(1)->in(1)); uint verif_init = 0; @@ -1375,6 +1372,31 @@ return init != 0; } +void PhaseIdealLoop::count_opaque_loop_nodes(Node* n, uint& init, uint& stride) { + init = 0; + stride = 0; + ResourceMark rm; + Unique_Node_List wq; + wq.push(n); + for (uint i = 0; i < wq.size(); i++) { + Node* n = wq.at(i); + if (skeleton_follow_inputs(n)) { + for (uint j = 1; j < n->req(); j++) { + Node* m = n->in(j); + if (m != NULL) { + wq.push(m); + } + } + continue; + } + if (n->Opcode() == Op_OpaqueLoopInit) { + init++; + } else if (n->Opcode() == Op_OpaqueLoopStride) { + stride++; + } + } +} + // Clone the skeleton predicate bool for a main or unswitched loop: // Main loop: Set new_init and new_stride nodes as new inputs. // Unswitched loop: new_init and new_stride are both NULL. Clone OpaqueLoopInit and OpaqueLoopStride instead. @@ -1394,8 +1416,7 @@ Node* n = to_clone.node(); uint i = to_clone.index(); Node* m = n->in(i); - int op = m->Opcode(); - if (skeleton_follow_inputs(m, op)) { + if (skeleton_follow_inputs(m)) { to_clone.push(m, 1); continue; } @@ -1404,6 +1425,7 @@ n = n->clone(); register_new_node(n, control); } + int op = m->Opcode(); if (op == Op_OpaqueLoopInit) { if (is_unswitched_loop && m->_idx < current && new_init == NULL) { new_init = m->clone(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/parse2.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/parse2.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/parse2.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/parse2.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1420,7 +1420,7 @@ branch_block->next_path_num(); } } else { // Path is live. - adjust_map_after_if(btest, c, prob, branch_block, next_block); + adjust_map_after_if(btest, c, prob, branch_block); if (!stopped()) { merge(target_bci); } @@ -1438,8 +1438,7 @@ next_block->next_path_num(); } } else { // Path is live. - adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob, - next_block, branch_block); + adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob, next_block); } } @@ -1533,7 +1532,7 @@ branch_block->next_path_num(); } } else { - adjust_map_after_if(taken_btest, c, prob, branch_block, next_block); + adjust_map_after_if(taken_btest, c, prob, branch_block); if (!stopped()) { merge(target_bci); } @@ -1550,8 +1549,7 @@ next_block->next_path_num(); } } else { - adjust_map_after_if(untaken_btest, c, untaken_prob, - next_block, branch_block); + adjust_map_after_if(untaken_btest, c, untaken_prob, next_block); } } @@ -1581,8 +1579,7 @@ // branch, seeing how it constrains a tested value, and then // deciding if it's worth our while to encode this constraint // as graph nodes in the current abstract interpretation map. -void Parse::adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, - Block* path, Block* other_path) { +void Parse::adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, Block* path) { if (!c->is_Cmp()) { maybe_add_predicate_after_if(path); return; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/parse.hpp openjdk-17-17.0.6+10/src/hotspot/share/opto/parse.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/parse.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/parse.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -535,8 +535,7 @@ void do_ifnull(BoolTest::mask btest, Node* c); void do_if(BoolTest::mask btest, Node* c); int repush_if_args(); - void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, - Block* path, Block* other_path); + void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob, Block* path); void sharpen_type_after_if(BoolTest::mask btest, Node* con, const Type* tcon, Node* val, const Type* tval); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/phaseX.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/phaseX.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/phaseX.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/phaseX.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1775,6 +1775,10 @@ } else { n = worklist.pop(); } + if (n->is_SafePoint()) { + // Keep track of SafePoint nodes for PhaseCCP::transform() + _safepoints.push(n); + } const Type *t = n->Value(this); if (t != type(n)) { assert(ccp_type_widens(t, type(n)), "ccp type must widen"); @@ -1891,6 +1895,23 @@ GrowableArray trstack(C->live_nodes() >> 1); trstack.push(new_node); // Process children of cloned node + + // This CCP pass may prove that no exit test for a loop ever succeeds (i.e. the loop is infinite). In that case, + // the logic below doesn't follow any path from Root to the loop body: there's at least one such path but it's proven + // never taken (its type is TOP). As a consequence the node on the exit path that's input to Root (let's call it n) is + // replaced by the top node and the inputs of that node n are not enqueued for further processing. If CCP only works + // through the graph from Root, this causes the loop body to never be processed here even when it's not dead (that + // is reachable from Root following its uses). To prevent that issue, transform() starts walking the graph from Root + // and all safepoints. + for (uint i = 0; i < _safepoints.size(); ++i) { + Node* nn = _safepoints.at(i); + Node* new_node = _nodes[nn->_idx]; + assert(new_node == NULL, ""); + new_node = transform_once(nn); + _nodes.map(nn->_idx, new_node); + trstack.push(new_node); + } + while ( trstack.is_nonempty() ) { Node *clone = trstack.pop(); uint cnt = clone->req(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/phaseX.hpp openjdk-17-17.0.6+10/src/hotspot/share/opto/phaseX.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/phaseX.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/phaseX.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -565,6 +565,7 @@ // Phase for performing global Conditional Constant Propagation. // Should be replaced with combined CCP & GVN someday. class PhaseCCP : public PhaseIterGVN { + Unique_Node_List _safepoints; // Non-recursive. Use analysis to transform single Node. virtual Node *transform_once( Node *n ); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/runtime.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/runtime.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/runtime.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/runtime.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1193,7 +1193,7 @@ } // Base64 decode function const TypeFunc* OptoRuntime::base64_decodeBlock_Type() { - int argcnt = 6; + int argcnt = 7; const Type** fields = TypeTuple::fields(argcnt); int argp = TypeFunc::Parms; @@ -1203,6 +1203,7 @@ fields[argp++] = TypePtr::NOTNULL; // dest array fields[argp++] = TypeInt::INT; // dest offset fields[argp++] = TypeInt::BOOL; // isURL + fields[argp++] = TypeInt::BOOL; // isMIME assert(argp == TypeFunc::Parms + argcnt, "correct decoding"); const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/split_if.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/split_if.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/split_if.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/split_if.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -200,7 +200,7 @@ return true; } } - if (n->Opcode() == Op_OpaqueLoopStride || n->Opcode() == Op_OpaqueLoopInit) { + if (subgraph_has_opaque(n)) { Unique_Node_List wq; wq.push(n); for (uint i = 0; i < wq.size(); i++) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/stringopts.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/stringopts.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/stringopts.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/stringopts.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -294,10 +294,12 @@ Node* cmp = bol->in(1); assert(cmp->is_Cmp(), "unexpected if shape"); if (cmp->in(1)->is_top() || cmp->in(2)->is_top()) { - // This region should lose its Phis and be optimized out by igvn but there's a chance the if folds to top first - // which then causes a reachable part of the graph to become dead. + // This region should lose its Phis. They are removed either in PhaseRemoveUseless (for data phis) or in IGVN + // (for memory phis). During IGVN, there is a chance that the If folds to top before the Region is processed + // which then causes a reachable part of the graph to become dead. To prevent this, set the boolean input of + // the If to a constant to nicely let the diamond Region/If fold away. Compile* C = _stringopts->C; - C->gvn_replace_by(n, iff->in(0)); + C->gvn_replace_by(iff->in(1), _stringopts->gvn()->intcon(0)); } } } @@ -1030,6 +1032,21 @@ fail = true; break; } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) { + // Check for side effect between Initialize and the constructor + for (SimpleDUIterator iter(ptr); iter.has_next(); iter.next()) { + Node* use = iter.get(); + if (!use->is_CFG() && !use->is_CheckCastPP() && !use->is_Load()) { +#ifndef PRODUCT + if (PrintOptimizeStringConcat) { + tty->print_cr("unexpected control use of Initialize"); + ptr->in(0)->dump(); // Initialize node + use->dump(1); + } +#endif + fail = true; + break; + } + } ptr = ptr->in(0)->in(0); } else if (ptr->is_Region()) { Node* copy = ptr->as_Region()->is_copy(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/opto/subnode.cpp openjdk-17-17.0.6+10/src/hotspot/share/opto/subnode.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/opto/subnode.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/opto/subnode.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1521,14 +1521,15 @@ } // Change x u< 1 or x u<= 0 to x == 0 + // and x u> 0 or u>= 1 to x != 0 if (cop == Op_CmpU && cmp1_op != Op_LoadRange && - ((_test._test == BoolTest::lt && + (((_test._test == BoolTest::lt || _test._test == BoolTest::ge) && cmp2->find_int_con(-1) == 1) || - (_test._test == BoolTest::le && + ((_test._test == BoolTest::le || _test._test == BoolTest::gt) && cmp2->find_int_con(-1) == 0))) { Node* ncmp = phase->transform(new CmpINode(cmp1, phase->intcon(0))); - return new BoolNode(ncmp, BoolTest::eq); + return new BoolNode(ncmp, _test.is_less() ? BoolTest::eq : BoolTest::ne); } // Change (arraylength <= 0) or (arraylength == 0) diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/forte.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/forte.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/forte.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/forte.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -314,6 +314,46 @@ frame candidate = *fr; +#ifdef ZERO + // Zero has no frames with code blobs, so the generic code fails. + // Instead, try to do Zero-specific search for Java frame. + + { + RegisterMap map(thread, false, false); + + while (true) { + // Cannot walk this frame? Cannot do anything anymore. + if (!candidate.safe_for_sender(thread)) { + return false; + } + + if (candidate.is_entry_frame()) { + // jcw is NULL if the java call wrapper could not be found + JavaCallWrapper* jcw = candidate.entry_frame_call_wrapper_if_safe(thread); + // If initial frame is frame from StubGenerator and there is no + // previous anchor, there are no java frames associated with a method + if (jcw == NULL || jcw->is_first_frame()) { + return false; + } + } + + // If we find a decipherable interpreted frame, this is our initial frame. + if (candidate.is_interpreted_frame()) { + if (is_decipherable_interpreted_frame(thread, &candidate, method_p, bci_p)) { + *initial_frame_p = candidate; + return true; + } + } + + // Walk some more. + candidate = candidate.sender(&map); + } + + // No dice, report no initial frames. + return false; + } +#endif + // If the starting frame we were given has no codeBlob associated with // it see if we can find such a frame because only frames with codeBlobs // are possible Java frames. @@ -522,12 +562,14 @@ extern "C" { JNIEXPORT void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { - JavaThread* thread; - if (trace->env_id == NULL || - (thread = JavaThread::thread_from_jni_environment(trace->env_id)) == NULL || - thread->is_exiting()) { + // Can't use thread_from_jni_environment as it may also perform a VM exit check that is unsafe to + // do from this context. + Thread* raw_thread = Thread::current_or_null_safe(); + JavaThread* thread; + if (trace->env_id == NULL || raw_thread == NULL || !raw_thread->is_Java_thread() || + (thread = ((JavaThread*)raw_thread))->is_exiting()) { // bad env_id, thread has exited or thread is exiting trace->num_frames = ticks_thread_exit; // -8 return; @@ -539,7 +581,8 @@ return; } - assert(JavaThread::current() == thread, + // This is safe now as the thread has not terminated and so no VM exit check occurs. + assert(thread == JavaThread::thread_from_jni_environment(trace->env_id), "AsyncGetCallTrace must be called by the current interrupted thread"); if (!JvmtiExport::should_post_class_load()) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEnvBase.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEnvBase.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEnvBase.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEnvBase.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -718,8 +718,8 @@ } // Get off stack monitors. (e.g. acquired via jni MonitorEnter). - JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this); - ObjectSynchronizer::monitors_iterate(&jmc); + JvmtiMonitorClosure jmc(calling_thread, owned_monitors_list, this); + ObjectSynchronizer::monitors_iterate(&jmc, java_thread); err = jmc.error(); return err; @@ -1454,34 +1454,32 @@ // to the list. return; } - if (mon->owner() == _java_thread ) { - // Filter out on stack monitors collected during stack walk. - oop obj = mon->object(); - bool found = false; - for (int j = 0; j < _owned_monitors_list->length(); j++) { - jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor; - oop check = JNIHandles::resolve(jobj); - if (check == obj) { - // On stack monitor already collected during the stack walk. - found = true; - break; - } + // Filter out on stack monitors collected during stack walk. + oop obj = mon->object(); + bool found = false; + for (int j = 0; j < _owned_monitors_list->length(); j++) { + jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor; + oop check = JNIHandles::resolve(jobj); + if (check == obj) { + // On stack monitor already collected during the stack walk. + found = true; + break; } - if (found == false) { - // This is off stack monitor (e.g. acquired via jni MonitorEnter). - jvmtiError err; - jvmtiMonitorStackDepthInfo *jmsdi; - err = _env->allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi); - if (err != JVMTI_ERROR_NONE) { - _error = err; - return; - } - Handle hobj(Thread::current(), obj); - jmsdi->monitor = _env->jni_reference(_calling_thread, hobj); - // stack depth is unknown for this monitor. - jmsdi->stack_depth = -1; - _owned_monitors_list->append(jmsdi); + } + if (found == false) { + // This is off stack monitor (e.g. acquired via jni MonitorEnter). + jvmtiError err; + jvmtiMonitorStackDepthInfo *jmsdi; + err = _env->allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi); + if (err != JVMTI_ERROR_NONE) { + _error = err; + return; } + Handle hobj(Thread::current(), obj); + jmsdi->monitor = _env->jni_reference(_calling_thread, hobj); + // stack depth is unknown for this monitor. + jmsdi->stack_depth = -1; + _owned_monitors_list->append(jmsdi); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEnvBase.hpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEnvBase.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEnvBase.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEnvBase.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -639,17 +639,15 @@ // Jvmti monitor closure to collect off stack monitors. class JvmtiMonitorClosure: public MonitorClosure { private: - JavaThread *_java_thread; JavaThread *_calling_thread; GrowableArray *_owned_monitors_list; jvmtiError _error; JvmtiEnvBase *_env; public: - JvmtiMonitorClosure(JavaThread* thread, JavaThread *calling_thread, + JvmtiMonitorClosure(JavaThread *calling_thread, GrowableArray *owned_monitors, JvmtiEnvBase *env) { - _java_thread = thread; _calling_thread = calling_thread; _owned_monitors_list = owned_monitors; _error = JVMTI_ERROR_NONE; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEventController.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEventController.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiEventController.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiEventController.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -830,10 +830,6 @@ thread==NULL? "ALL": JvmtiTrace::safe_get_thread_name(thread), enabled? "enabled" : "disabled", JvmtiTrace::event_name(event_type))); - if (event_type == JVMTI_EVENT_OBJECT_FREE) { - flush_object_free_events(env); - } - if (thread == NULL) { env->env_event_enable()->set_user_enabled(event_type, enabled); } else { @@ -982,6 +978,10 @@ void JvmtiEventController::set_user_enabled(JvmtiEnvBase *env, JavaThread *thread, jvmtiEvent event_type, bool enabled) { + if (event_type == JVMTI_EVENT_OBJECT_FREE) { + JvmtiEventControllerPrivate::flush_object_free_events(env); + } + if (Threads::number_of_threads() == 0) { // during early VM start-up locks don't exist, but we are safely single threaded, // call the functionality without holding the JvmtiThreadState_lock. diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiExport.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiExport.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiExport.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiExport.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -730,6 +730,8 @@ void JvmtiExport::post_vm_death() { EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("Trg VM death event triggered" )); + JvmtiTagMap::flush_all_object_free_events(); + JvmtiEnvIterator it; for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) { @@ -1490,15 +1492,23 @@ } } -void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) { - assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking"); +void JvmtiExport::post_object_free(JvmtiEnv* env, GrowableArray* objects) { + assert(objects != NULL, "Nothing to post"); + if (!env->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { + return; // the event type has been already disabled + } EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Trg Object Free triggered" )); EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("[?] Evt Object Free sent")); + JavaThread* javaThread = JavaThread::current(); + JvmtiThreadEventMark jem(javaThread); + JvmtiJavaThreadEventTransition jet(javaThread); jvmtiEventObjectFree callback = env->callbacks()->ObjectFree; if (callback != NULL) { - (*callback)(env->jvmti_external(), tag); + for (int index = 0; index < objects->length(); index++) { + (*callback)(env->jvmti_external(), objects->at(index)); + } } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiExport.hpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiExport.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiExport.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiExport.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -370,7 +370,7 @@ static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) NOT_JVMTI_RETURN; static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) NOT_JVMTI_RETURN; static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) NOT_JVMTI_RETURN; - static void post_object_free(JvmtiEnv* env, jlong tag) NOT_JVMTI_RETURN; + static void post_object_free(JvmtiEnv* env, GrowableArray* objects) NOT_JVMTI_RETURN; static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) NOT_JVMTI_RETURN; static void record_vm_internal_object_allocation(oop object) NOT_JVMTI_RETURN; // Post objects collected by vm_object_alloc_event_collector. diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMap.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMap.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMap.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMap.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -76,7 +76,8 @@ _lock(Mutex::nonleaf+1, "JvmtiTagMap_lock", Mutex::_allow_vm_block_flag, Mutex::_safepoint_check_never), _needs_rehashing(false), - _needs_cleaning(false) { + _needs_cleaning(false), + _posting_events(false) { assert(JvmtiThreadState_lock->is_locked(), "sanity check"); assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment"); @@ -135,18 +136,16 @@ } // This checks for posting and rehashing before operations that -// this tagmap table. The calls from a JavaThread only rehash, posting is -// only done before heap walks. -void JvmtiTagMap::check_hashmap(bool post_events) { - assert(!post_events || SafepointSynchronize::is_at_safepoint(), "precondition"); +// this tagmap table. +void JvmtiTagMap::check_hashmap(GrowableArray* objects) { assert(is_locked(), "checking"); if (is_empty()) { return; } if (_needs_cleaning && - post_events && + objects != NULL && env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { - remove_dead_entries_locked(true /* post_object_free */); + remove_dead_entries_locked(objects); } if (_needs_rehashing) { log_info(jvmti, table)("TagMap table needs rehashing"); @@ -156,7 +155,7 @@ } // This checks for posting and rehashing and is called from the heap walks. -void JvmtiTagMap::check_hashmaps_for_heapwalk() { +void JvmtiTagMap::check_hashmaps_for_heapwalk(GrowableArray* objects) { assert(SafepointSynchronize::is_at_safepoint(), "called from safepoints"); // Verify that the tag map tables are valid and unconditionally post events @@ -167,7 +166,7 @@ if (tag_map != NULL) { // The ZDriver may be walking the hashmaps concurrently so this lock is needed. MutexLocker ml(tag_map->lock(), Mutex::_no_safepoint_check_flag); - tag_map->check_hashmap(/*post_events*/ true); + tag_map->check_hashmap(objects); } } } @@ -358,7 +357,7 @@ // SetTag should not post events because the JavaThread has to // transition to native for the callback and this cannot stop for // safepoints with the hashmap lock held. - check_hashmap(/*post_events*/ false); + check_hashmap(NULL); /* don't collect dead objects */ // resolve the object oop o = JNIHandles::resolve_non_null(object); @@ -393,7 +392,7 @@ // GetTag should not post events because the JavaThread has to // transition to native for the callback and this cannot stop for // safepoints with the hashmap lock held. - check_hashmap(/*post_events*/ false); + check_hashmap(NULL); /* don't collect dead objects */ // resolve the object oop o = JNIHandles::resolve_non_null(object); @@ -888,15 +887,17 @@ class VM_HeapIterateOperation: public VM_Operation { private: ObjectClosure* _blk; + GrowableArray* const _dead_objects; public: - VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; } + VM_HeapIterateOperation(ObjectClosure* blk, GrowableArray* objects) : + _blk(blk), _dead_objects(objects) { } VMOp_Type type() const { return VMOp_HeapIterateOperation; } void doit() { // allows class files maps to be cached during iteration ClassFieldMapCacheMark cm; - JvmtiTagMap::check_hashmaps_for_heapwalk(); + JvmtiTagMap::check_hashmaps_for_heapwalk(_dead_objects); // make sure that heap is parsable (fills TLABs with filler objects) Universe::heap()->ensure_parsability(false); // no need to retire TLABs @@ -1135,14 +1136,20 @@ object_filter == JVMTI_HEAP_OBJECT_EITHER, JavaThread::current()); eb.deoptimize_objects_all_threads(); - MutexLocker ml(Heap_lock); - IterateOverHeapObjectClosure blk(this, - klass, - object_filter, - heap_object_callback, - user_data); - VM_HeapIterateOperation op(&blk); - VMThread::execute(&op); + Arena dead_object_arena(mtServiceability); + GrowableArray dead_objects(&dead_object_arena, 10, 0, 0); + { + MutexLocker ml(Heap_lock); + IterateOverHeapObjectClosure blk(this, + klass, + object_filter, + heap_object_callback, + user_data); + VM_HeapIterateOperation op(&blk, &dead_objects); + VMThread::execute(&op); + } + // Post events outside of Heap_lock + post_dead_objects(&dead_objects); } @@ -1155,67 +1162,83 @@ // EA based optimizations on tagged objects are already reverted. EscapeBarrier eb(!(heap_filter & JVMTI_HEAP_FILTER_UNTAGGED), JavaThread::current()); eb.deoptimize_objects_all_threads(); - MutexLocker ml(Heap_lock); - IterateThroughHeapObjectClosure blk(this, - klass, - heap_filter, - callbacks, - user_data); - VM_HeapIterateOperation op(&blk); - VMThread::execute(&op); + + Arena dead_object_arena(mtServiceability); + GrowableArray dead_objects(&dead_object_arena, 10, 0, 0); + { + MutexLocker ml(Heap_lock); + IterateThroughHeapObjectClosure blk(this, + klass, + heap_filter, + callbacks, + user_data); + VM_HeapIterateOperation op(&blk, &dead_objects); + VMThread::execute(&op); + } + // Post events outside of Heap_lock + post_dead_objects(&dead_objects); } -void JvmtiTagMap::remove_dead_entries_locked(bool post_object_free) { +void JvmtiTagMap::remove_dead_entries_locked(GrowableArray* objects) { assert(is_locked(), "precondition"); if (_needs_cleaning) { // Recheck whether to post object free events under the lock. - post_object_free = post_object_free && env()->is_enabled(JVMTI_EVENT_OBJECT_FREE); + if (!env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { + objects = NULL; + } log_info(jvmti, table)("TagMap table needs cleaning%s", - (post_object_free ? " and posting" : "")); - hashmap()->remove_dead_entries(env(), post_object_free); + ((objects != NULL) ? " and posting" : "")); + hashmap()->remove_dead_entries(objects); _needs_cleaning = false; } } -void JvmtiTagMap::remove_dead_entries(bool post_object_free) { +void JvmtiTagMap::remove_dead_entries(GrowableArray* objects) { MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag); - remove_dead_entries_locked(post_object_free); + remove_dead_entries_locked(objects); } -class VM_JvmtiPostObjectFree: public VM_Operation { - JvmtiTagMap* _tag_map; - public: - VM_JvmtiPostObjectFree(JvmtiTagMap* tag_map) : _tag_map(tag_map) {} - VMOp_Type type() const { return VMOp_Cleanup; } - void doit() { - _tag_map->remove_dead_entries(true /* post_object_free */); +void JvmtiTagMap::post_dead_objects(GrowableArray* const objects) { + assert(Thread::current()->is_Java_thread(), "Must post from JavaThread"); + if (objects != NULL && objects->length() > 0) { + JvmtiExport::post_object_free(env(), objects); + log_info(jvmti)("%d free object posted", objects->length()); } +} - // Doesn't need a safepoint, just the VM thread - virtual bool evaluate_at_safepoint() const { return false; } -}; - -// PostObjectFree can't be called by JavaThread, so call it from the VM thread. -void JvmtiTagMap::post_dead_objects_on_vm_thread() { - VM_JvmtiPostObjectFree op(this); - VMThread::execute(&op); +void JvmtiTagMap::remove_and_post_dead_objects() { + ResourceMark rm; + GrowableArray objects; + remove_dead_entries(&objects); + post_dead_objects(&objects); } void JvmtiTagMap::flush_object_free_events() { assert_not_at_safepoint(); if (env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { { - MutexLocker ml(lock(), Mutex::_no_safepoint_check_flag); + MonitorLocker ml(lock(), Mutex::_no_safepoint_check_flag); + // If another thread is posting events, let it finish + while (_posting_events) { + ml.wait(); + } + if (!_needs_cleaning || is_empty()) { _needs_cleaning = false; return; } + _posting_events = true; } // Drop the lock so we can do the cleaning on the VM thread. // Needs both cleaning and event posting (up to some other thread // getting there first after we dropped the lock). - post_dead_objects_on_vm_thread(); + remove_and_post_dead_objects(); + { + MonitorLocker ml(lock(), Mutex::_no_safepoint_check_flag); + _posting_events = false; + ml.notify_all(); + } } else { - remove_dead_entries(false); + remove_dead_entries(NULL); } } @@ -1327,9 +1350,6 @@ // it is collected yet. entry_iterate(&collector); } - if (collector.some_dead_found() && env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { - post_dead_objects_on_vm_thread(); - } return collector.result(count_ptr, object_result_ptr, tag_result_ptr); } @@ -2376,6 +2396,9 @@ Handle _initial_object; GrowableArray* _visit_stack; // the visit stack + // Dead object tags in JvmtiTagMap + GrowableArray* _dead_objects; + bool _following_object_refs; // are we following object references bool _reporting_primitive_fields; // optional reporting @@ -2417,12 +2440,14 @@ VM_HeapWalkOperation(JvmtiTagMap* tag_map, Handle initial_object, BasicHeapWalkContext callbacks, - const void* user_data); + const void* user_data, + GrowableArray* objects); VM_HeapWalkOperation(JvmtiTagMap* tag_map, Handle initial_object, AdvancedHeapWalkContext callbacks, - const void* user_data); + const void* user_data, + GrowableArray* objects); ~VM_HeapWalkOperation(); @@ -2434,7 +2459,8 @@ VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, Handle initial_object, BasicHeapWalkContext callbacks, - const void* user_data) { + const void* user_data, + GrowableArray* objects) { _is_advanced_heap_walk = false; _tag_map = tag_map; _initial_object = initial_object; @@ -2443,6 +2469,7 @@ _reporting_primitive_array_values = false; _reporting_string_values = false; _visit_stack = create_visit_stack(); + _dead_objects = objects; CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks); @@ -2451,7 +2478,8 @@ VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map, Handle initial_object, AdvancedHeapWalkContext callbacks, - const void* user_data) { + const void* user_data, + GrowableArray* objects) { _is_advanced_heap_walk = true; _tag_map = tag_map; _initial_object = initial_object; @@ -2460,6 +2488,7 @@ _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);; _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);; _visit_stack = create_visit_stack(); + _dead_objects = objects; CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks); } @@ -2930,7 +2959,7 @@ ObjectMarkerController marker; ClassFieldMapCacheMark cm; - JvmtiTagMap::check_hashmaps_for_heapwalk(); + JvmtiTagMap::check_hashmaps_for_heapwalk(_dead_objects); assert(visit_stack()->is_empty(), "visit stack must be empty"); @@ -2978,10 +3007,16 @@ JavaThread* jt = JavaThread::current(); EscapeBarrier eb(true, jt); eb.deoptimize_objects_all_threads(); - MutexLocker ml(Heap_lock); - BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback); - VM_HeapWalkOperation op(this, Handle(), context, user_data); - VMThread::execute(&op); + Arena dead_object_arena(mtServiceability); + GrowableArray dead_objects(&dead_object_arena, 10, 0, 0); + { + MutexLocker ml(Heap_lock); + BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback); + VM_HeapWalkOperation op(this, Handle(), context, user_data, &dead_objects); + VMThread::execute(&op); + } + // Post events outside of Heap_lock + post_dead_objects(&dead_objects); } // iterate over all objects that are reachable from a given object @@ -2991,10 +3026,16 @@ oop obj = JNIHandles::resolve(object); Handle initial_object(Thread::current(), obj); - MutexLocker ml(Heap_lock); - BasicHeapWalkContext context(NULL, NULL, object_ref_callback); - VM_HeapWalkOperation op(this, initial_object, context, user_data); - VMThread::execute(&op); + Arena dead_object_arena(mtServiceability); + GrowableArray dead_objects(&dead_object_arena, 10, 0, 0); + { + MutexLocker ml(Heap_lock); + BasicHeapWalkContext context(NULL, NULL, object_ref_callback); + VM_HeapWalkOperation op(this, initial_object, context, user_data, &dead_objects); + VMThread::execute(&op); + } + // Post events outside of Heap_lock + post_dead_objects(&dead_objects); } // follow references from an initial object or the GC roots @@ -3012,10 +3053,17 @@ !(heap_filter & JVMTI_HEAP_FILTER_UNTAGGED), jt); eb.deoptimize_objects_all_threads(); - MutexLocker ml(Heap_lock); - AdvancedHeapWalkContext context(heap_filter, klass, callbacks); - VM_HeapWalkOperation op(this, initial_object, context, user_data); - VMThread::execute(&op); + + Arena dead_object_arena(mtServiceability); + GrowableArray dead_objects(&dead_object_arena, 10, 0, 0); + { + MutexLocker ml(Heap_lock); + AdvancedHeapWalkContext context(heap_filter, klass, callbacks); + VM_HeapWalkOperation op(this, initial_object, context, user_data, &dead_objects); + VMThread::execute(&op); + } + // Post events outside of Heap_lock + post_dead_objects(&dead_objects); } // Concurrent GC needs to call this in relocation pause, so after the objects are moved diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMap.hpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMap.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMap.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMap.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -38,10 +38,11 @@ private: JvmtiEnv* _env; // the jvmti environment - Mutex _lock; // lock for this tag map + Monitor _lock; // lock for this tag map JvmtiTagMapTable* _hashmap; // the hashmap for tags bool _needs_rehashing; bool _needs_cleaning; + bool _posting_events; static bool _has_object_free_events; @@ -51,15 +52,14 @@ // accessors inline JvmtiEnv* env() const { return _env; } - void check_hashmap(bool post_events); + void check_hashmap(GrowableArray* objects); void entry_iterate(JvmtiTagMapEntryClosure* closure); - void post_dead_objects_on_vm_thread(); public: // indicates if this tag map is locked bool is_locked() { return lock()->is_locked(); } - inline Mutex* lock() { return &_lock; } + inline Monitor* lock() { return &_lock; } JvmtiTagMapTable* hashmap() { return _hashmap; } @@ -109,11 +109,12 @@ jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr); + void remove_and_post_dead_objects(); + void remove_dead_entries(GrowableArray* objects); + void remove_dead_entries_locked(GrowableArray* objects); + void post_dead_objects(GrowableArray* const objects); - void remove_dead_entries(bool post_object_free); - void remove_dead_entries_locked(bool post_object_free); - - static void check_hashmaps_for_heapwalk(); + static void check_hashmaps_for_heapwalk(GrowableArray* objects); static void set_needs_rehashing() NOT_JVMTI_RETURN; static void set_needs_cleaning() NOT_JVMTI_RETURN; static void gc_notification(size_t num_dead_entries) NOT_JVMTI_RETURN; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMapTable.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMapTable.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMapTable.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMapTable.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -186,8 +186,9 @@ } } -// Serially remove entries for dead oops from the table, and notify jvmti. -void JvmtiTagMapTable::remove_dead_entries(JvmtiEnv* env, bool post_object_free) { +// Serially remove entries for dead oops from the table and store dead oops' +// tag in objects array if provided. +void JvmtiTagMapTable::remove_dead_entries(GrowableArray* objects) { int oops_removed = 0; int oops_counted = 0; for (int i = 0; i < table_size(); ++i) { @@ -206,19 +207,18 @@ *p = entry->next(); free_entry(entry); - // post the event to the profiler - if (post_object_free) { - JvmtiExport::post_object_free(env, tag); + // collect object tags for posting JVMTI events later + if (objects != NULL) { + objects->append(tag); } - } // get next entry entry = *p; } } - log_info(jvmti, table) ("JvmtiTagMap entries counted %d removed %d; %s", - oops_counted, oops_removed, post_object_free ? "free object posted" : "no posting"); + log_info(jvmti, table) ("JvmtiTagMap entries counted %d removed %d", + oops_counted, oops_removed); } // Rehash oops in the table diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMapTable.hpp openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMapTable.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/jvmtiTagMapTable.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/jvmtiTagMapTable.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -87,8 +87,8 @@ bool is_empty() const { return number_of_entries() == 0; } - // Cleanup cleared entries and post - void remove_dead_entries(JvmtiEnv* env, bool post_object_free); + // Cleanup cleared entries and store dead object tags in objects array + void remove_dead_entries(GrowableArray* objects); void rehash(); void clear(); }; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/prims/methodHandles.cpp openjdk-17-17.0.6+10/src/hotspot/share/prims/methodHandles.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/prims/methodHandles.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/prims/methodHandles.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, 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 @@ -89,7 +89,11 @@ ResourceMark rm; TraceTime timer("MethodHandles adapters generation", TRACETIME_LOG(Info, startuptime)); - _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size); + // The adapter entry is required to be aligned to CodeEntryAlignment. + // So we need additional bytes due to alignment. + int adapter_num = (int)Interpreter::method_handle_invoke_LAST - (int)Interpreter::method_handle_invoke_FIRST + 1; + int max_aligned_bytes = adapter_num * CodeEntryAlignment; + _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size + max_aligned_bytes); CodeBuffer code(_adapter_code); MethodHandlesAdapterGenerator g(&code); g.generate(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/abstract_vm_version.cpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/abstract_vm_version.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/abstract_vm_version.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/abstract_vm_version.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -238,6 +238,10 @@ #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.0 (VS2022)" #elif _MSC_VER == 1931 #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.1 (VS2022)" + #elif _MSC_VER == 1932 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.2 (VS2022)" + #elif _MSC_VER == 1933 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.3 (VS2022)" #else #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER) #endif diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/fieldDescriptor.hpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/fieldDescriptor.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/fieldDescriptor.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/fieldDescriptor.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -62,7 +62,7 @@ AccessFlags access_flags() const { return _access_flags; } oop loader() const; - // Offset (in words) of field from start of instanceOop / Klass* + // Offset (in bytes) of field from start of instanceOop / Klass* inline int offset() const; Symbol* generic_signature() const; int index() const { return _index; } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/globals.hpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/globals.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/globals.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/globals.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1572,7 +1572,7 @@ "Stack space (bytes) required for JVM_InvokeMethod to complete") \ \ /* code cache parameters */ \ - develop_pd(uintx, CodeCacheSegmentSize, \ + product_pd(uintx, CodeCacheSegmentSize, EXPERIMENTAL, \ "Code cache segment size (in bytes) - smallest unit of " \ "allocation") \ range(1, 1024) \ diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/os.cpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/os.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/os.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/os.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -513,8 +513,6 @@ Threads::add(signal_thread); Thread::start(signal_thread); } - // Handle ^BREAK - os::signal(SIGBREAK, os::user_handler()); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/sweeper.cpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/sweeper.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/sweeper.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/sweeper.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -406,11 +406,6 @@ _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep); } - EventSweepCodeCache event(UNTIMED); - if (event.should_commit()) { - post_sweep_event(&event, sweep_start_counter, sweep_end_counter, (s4)_traversals, swept_count, flushed_count, zombified_count); - } - #ifdef ASSERT if(PrintMethodFlushing) { tty->print_cr("### sweeper: sweep time(" JLONG_FORMAT "): ", sweep_time.value()); @@ -437,6 +432,15 @@ CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); log.debug("restart compiler"); log_sweep("restart_compiler"); + EventJITRestart event; + event.set_freedMemory(freed_memory); + event.set_codeCacheMaxCapacity(CodeCache::max_capacity()); + event.commit(); + } + + EventSweepCodeCache event(UNTIMED); + if (event.should_commit()) { + post_sweep_event(&event, sweep_start_counter, sweep_end_counter, (s4)_traversals, swept_count, flushed_count, zombified_count); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/synchronizer.cpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/synchronizer.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/synchronizer.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/synchronizer.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -1056,10 +1056,13 @@ // Visitors ... -void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) { +void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure, JavaThread* thread) { MonitorList::Iterator iter = _in_use_list.iterator(); while (iter.has_next()) { ObjectMonitor* mid = iter.next(); + if (mid->owner() != thread) { + continue; + } if (!mid->is_being_async_deflated() && mid->object_peek() != NULL) { // Only process with closure if the object is set. @@ -1547,9 +1550,7 @@ public: ReleaseJavaMonitorsClosure(JavaThread* thread) : _thread(thread) {} void do_monitor(ObjectMonitor* mid) { - if (mid->owner() == _thread) { - (void)mid->complete_exit(_thread); - } + (void)mid->complete_exit(_thread); } }; @@ -1572,7 +1573,7 @@ assert(current == JavaThread::current(), "must be current Java thread"); NoSafepointVerifier nsv; ReleaseJavaMonitorsClosure rjmc(current); - ObjectSynchronizer::monitors_iterate(&rjmc); + ObjectSynchronizer::monitors_iterate(&rjmc, current); assert(!current->has_pending_exception(), "Should not be possible"); current->clear_pending_exception(); } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/runtime/synchronizer.hpp openjdk-17-17.0.6+10/src/hotspot/share/runtime/synchronizer.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/runtime/synchronizer.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/runtime/synchronizer.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -133,7 +133,7 @@ // JNI detach support static void release_monitors_owned_by_thread(JavaThread* current); - static void monitors_iterate(MonitorClosure* m); + static void monitors_iterate(MonitorClosure* m, JavaThread* thread); // Initialize the gInflationLocks static void initialize(); diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/services/mallocTracker.cpp openjdk-17-17.0.6+10/src/hotspot/share/services/mallocTracker.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/services/mallocTracker.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/services/mallocTracker.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -60,6 +60,15 @@ } #endif +// Total malloc invocation count +size_t MallocMemorySnapshot::total_count() const { + size_t amount = 0; + for (int index = 0; index < mt_number_of_types; index ++) { + amount += _malloc[index].malloc_count(); + } + return amount; +} + // Total malloc'd memory amount size_t MallocMemorySnapshot::total() const { size_t amount = 0; diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/services/mallocTracker.hpp openjdk-17-17.0.6+10/src/hotspot/share/services/mallocTracker.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/services/mallocTracker.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/services/mallocTracker.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -153,6 +153,8 @@ return &_tracking_header; } + // Total malloc invocation count + size_t total_count() const; // Total malloc'd memory amount size_t total() const; // Total malloc'd memory used by arenas diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/services/memReporter.cpp openjdk-17-17.0.6+10/src/hotspot/share/services/memReporter.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/services/memReporter.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/services/memReporter.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -98,10 +98,12 @@ void MemSummaryReporter::report() { outputStream* out = output(); - size_t total_reserved_amount = _malloc_snapshot->total() + - _vm_snapshot->total_reserved(); - size_t total_committed_amount = _malloc_snapshot->total() + - _vm_snapshot->total_committed(); + const size_t total_malloced_bytes = _malloc_snapshot->total(); + const size_t total_mmap_reserved_bytes = _vm_snapshot->total_reserved(); + const size_t total_mmap_committed_bytes = _vm_snapshot->total_committed(); + + size_t total_reserved_amount = total_malloced_bytes + total_mmap_reserved_bytes; + size_t total_committed_amount = total_malloced_bytes + total_mmap_committed_bytes; // Overall total out->print_cr("\nNative Memory Tracking:\n"); @@ -113,7 +115,14 @@ out->print("Total: "); print_total(total_reserved_amount, total_committed_amount); - out->print("\n"); + out->cr(); + out->print_cr(" malloc: " SIZE_FORMAT "%s #" SIZE_FORMAT, + amount_in_current_scale(total_malloced_bytes), current_scale(), + _malloc_snapshot->total_count()); + out->print(" mmap: "); + print_total(total_mmap_reserved_bytes, total_mmap_committed_bytes); + out->cr(); + out->cr(); // Summary by memory type for (int index = 0; index < mt_number_of_types; index ++) { diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/services/threadService.cpp openjdk-17-17.0.6+10/src/hotspot/share/services/threadService.cpp --- openjdk-17-17.0.5+8/src/hotspot/share/services/threadService.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/services/threadService.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -622,18 +622,14 @@ class InflatedMonitorsClosure: public MonitorClosure { private: ThreadStackTrace* _stack_trace; - Thread* _thread; public: - InflatedMonitorsClosure(Thread* t, ThreadStackTrace* st) { - _thread = t; + InflatedMonitorsClosure(ThreadStackTrace* st) { _stack_trace = st; } void do_monitor(ObjectMonitor* mid) { - if (mid->owner() == _thread) { - oop object = mid->object(); - if (!_stack_trace->is_owned_monitor_on_stack(object)) { - _stack_trace->add_jni_locked_monitor(object); - } + oop object = mid->object(); + if (!_stack_trace->is_owned_monitor_on_stack(object)) { + _stack_trace->add_jni_locked_monitor(object); } } }; @@ -692,8 +688,8 @@ if (_with_locked_monitors) { // Iterate inflated monitors and find monitors locked by this thread // not found in the stack - InflatedMonitorsClosure imc(_thread, this); - ObjectSynchronizer::monitors_iterate(&imc); + InflatedMonitorsClosure imc(this); + ObjectSynchronizer::monitors_iterate(&imc, _thread); } } diff -Nru openjdk-17-17.0.5+8/src/hotspot/share/utilities/powerOfTwo.hpp openjdk-17-17.0.6+10/src/hotspot/share/utilities/powerOfTwo.hpp --- openjdk-17-17.0.5+8/src/hotspot/share/utilities/powerOfTwo.hpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/hotspot/share/utilities/powerOfTwo.hpp 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -103,7 +103,8 @@ template::value)> inline T round_up_power_of_2(T value) { assert(value > 0, "Invalid value"); - assert(value <= max_power_of_2(), "Overflow"); + assert(value <= max_power_of_2(), "Overflowing maximum allowed power of two with " UINT64_FORMAT_X, + static_cast(value)); if (is_power_of_2(value)) { return value; } diff -Nru openjdk-17-17.0.5+8/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java openjdk-17-17.0.6+10/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java --- openjdk-17-17.0.5+8/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/linux/classes/jdk/internal/platform/CgroupMetrics.java 2023-01-10 13:21:55.000000000 +0000 @@ -121,7 +121,13 @@ @Override public long getMemoryLimit() { - return subsystem.getMemoryLimit(); + long subsMem = subsystem.getMemoryLimit(); + // Catch the cgroup memory limit exceeding host physical memory. + // Treat this as unlimited. + if (subsMem >= getTotalMemorySize0()) { + return CgroupSubsystem.LONG_RETVAL_UNLIMITED; + } + return subsMem; } @Override @@ -178,5 +184,6 @@ } private static native boolean isUseContainerSupport(); + private static native long getTotalMemorySize0(); } diff -Nru openjdk-17-17.0.5+8/src/java.base/linux/classes/jdk/internal/platform/CgroupSubsystemFactory.java openjdk-17-17.0.6+10/src/java.base/linux/classes/jdk/internal/platform/CgroupSubsystemFactory.java --- openjdk-17-17.0.5+8/src/java.base/linux/classes/jdk/internal/platform/CgroupSubsystemFactory.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/linux/classes/jdk/internal/platform/CgroupSubsystemFactory.java 2023-01-10 13:21:55.000000000 +0000 @@ -320,30 +320,11 @@ case MEMORY_CTRL: // fall-through case CPU_CTRL: case CPUACCT_CTRL: + case CPUSET_CTRL: case PIDS_CTRL: case BLKIO_CTRL: { CgroupInfo info = infos.get(controllerName); - assert info.getMountPoint() == null; - assert info.getMountRoot() == null; - info.setMountPoint(mountPath); - info.setMountRoot(mountRoot); - cgroupv1ControllerFound = true; - break; - } - case CPUSET_CTRL: { - CgroupInfo info = infos.get(controllerName); - if (info.getMountPoint() != null) { - // On some systems duplicate cpuset controllers get mounted in addition to - // the main cgroup controllers most likely under /sys/fs/cgroup. In that - // case pick the one under /sys/fs/cgroup and discard others. - if (!info.getMountPoint().startsWith("/sys/fs/cgroup")) { - info.setMountPoint(mountPath); - info.setMountRoot(mountRoot); - } - } else { - info.setMountPoint(mountPath); - info.setMountRoot(mountRoot); - } + setMountPoints(info, mountPath, mountRoot); cgroupv1ControllerFound = true; break; } @@ -357,10 +338,7 @@ // All controllers have the same mount point and root mount // for unified hierarchy. for (CgroupInfo info: infos.values()) { - assert info.getMountPoint() == null; - assert info.getMountRoot() == null; - info.setMountPoint(mountPath); - info.setMountRoot(mountRoot); + setMountPoints(info, mountPath, mountRoot); } } cgroupv2ControllerFound = true; @@ -369,6 +347,22 @@ return cgroupv1ControllerFound || cgroupv2ControllerFound; } + private static void setMountPoints(CgroupInfo info, String mountPath, String mountRoot) { + if (info.getMountPoint() != null) { + // On some systems duplicate controllers get mounted in addition to + // the main cgroup controllers (which are under /sys/fs/cgroup). In that + // case pick the main one and discard others as the limits + // are associated with the ones in /sys/fs/cgroup. + if (!info.getMountPoint().startsWith("/sys/fs/cgroup")) { + info.setMountPoint(mountPath); + info.setMountRoot(mountRoot); + } + } else { + info.setMountPoint(mountPath); + info.setMountRoot(mountRoot); + } + } + public static final class CgroupTypeResult { private final boolean isCgroupV2; private final boolean anyControllersEnabled; diff -Nru openjdk-17-17.0.5+8/src/java.base/linux/native/libjava/CgroupMetrics.c openjdk-17-17.0.6+10/src/java.base/linux/native/libjava/CgroupMetrics.c --- openjdk-17-17.0.5+8/src/java.base/linux/native/libjava/CgroupMetrics.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/linux/native/libjava/CgroupMetrics.c 2023-01-10 13:21:55.000000000 +0000 @@ -22,6 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +#include #include "jni.h" #include "jvm.h" @@ -33,3 +34,10 @@ { return JVM_IsUseContainerSupport(); } + +JNIEXPORT jlong JNICALL +Java_jdk_internal_platform_CgroupMetrics_getTotalMemorySize0 + (JNIEnv *env, jclass ignored) +{ + return sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java openjdk-17-17.0.6+10/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ import sun.security.provider.ParameterCache; import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE; +import static sun.security.util.SecurityProviderConstants.getDefDHPrivateExpSize; /** * This class represents the key pair generator for Diffie-Hellman key pairs. @@ -60,9 +61,6 @@ // The size in bits of the prime modulus private int pSize; - // The size in bits of the random exponent (private value) - private int lSize; - // The source of randomness private SecureRandom random; @@ -71,7 +69,8 @@ initialize(DEF_DH_KEY_SIZE, null); } - private static void checkKeySize(int keysize) + // pkg private; used by DHParameterGenerator class as well + static void checkKeySize(int keysize, int expSize) throws InvalidParameterException { if ((keysize < 512) || (keysize > 8192) || ((keysize & 0x3F) != 0)) { @@ -80,6 +79,13 @@ "from 512 to 8192 (inclusive). " + "The specific key size " + keysize + " is not supported"); } + + // optional, could be 0 if not specified + if ((expSize < 0) || (expSize > keysize)) { + throw new InvalidParameterException + ("Exponent size must be positive and no larger than" + + " modulus size"); + } } /** @@ -91,21 +97,17 @@ * @param random the source of randomness */ public void initialize(int keysize, SecureRandom random) { - checkKeySize(keysize); + checkKeySize(keysize, 0); - // Use the built-in parameters (ranging from 512 to 8192) - // when available. - this.params = ParameterCache.getCachedDHParameterSpec(keysize); - - // Due to performance issue, only support DH parameters generation - // up to 1024 bits. - if ((this.params == null) && (keysize > 1024)) { - throw new InvalidParameterException( - "Unsupported " + keysize + "-bit DH parameter generation"); + try { + // Use the built-in parameters (ranging from 512 to 8192) + // when available. + this.params = ParameterCache.getDHParameterSpec(keysize, random); + } catch (GeneralSecurityException e) { + throw new InvalidParameterException(e.getMessage()); } this.pSize = keysize; - this.lSize = 0; this.random = random; } @@ -130,22 +132,13 @@ ("Inappropriate parameter type"); } - params = (DHParameterSpec)algParams; + params = (DHParameterSpec) algParams; pSize = params.getP().bitLength(); try { - checkKeySize(pSize); + checkKeySize(pSize, params.getL()); } catch (InvalidParameterException ipe) { throw new InvalidAlgorithmParameterException(ipe.getMessage()); } - - // exponent size is optional, could be 0 - lSize = params.getL(); - - // Require exponentSize < primeSize - if ((lSize != 0) && (lSize > pSize)) { - throw new InvalidAlgorithmParameterException - ("Exponent size must not be larger than modulus size"); - } this.random = random; } @@ -159,24 +152,12 @@ random = SunJCE.getRandom(); } - if (params == null) { - try { - params = ParameterCache.getDHParameterSpec(pSize, random); - } catch (GeneralSecurityException e) { - // should never happen - throw new ProviderException(e); - } - } - BigInteger p = params.getP(); BigInteger g = params.getG(); - if (lSize <= 0) { - lSize = pSize >> 1; - // use an exponent size of (pSize / 2) but at least 384 bits - if (lSize < 384) { - lSize = 384; - } + int lSize = params.getL(); + if (lSize == 0) { // not specified; use our own default + lSize = getDefDHPrivateExpSize(params); } BigInteger x; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java openjdk-17-17.0.6+10/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -59,7 +59,7 @@ // The source of randomness private SecureRandom random = null; - private static void checkKeySize(int keysize) + private static void checkSupport(int keysize, int exponentSize) throws InvalidParameterException { boolean supported = ((keysize == 2048) || (keysize == 3072) || @@ -67,9 +67,13 @@ if (!supported) { throw new InvalidParameterException( - "DH key size must be multiple of 64 and range " + + "Supported DH key size must be multiple of 64 and range " + "from 512 to 1024 (inclusive), or 2048, 3072. " + - "The specific key size " + keysize + " is not supported"); + "The specified key size " + keysize + " is not supported"); + } + + if (exponentSize != 0) { + DHKeyPairGenerator.checkKeySize(keysize, exponentSize); } } @@ -83,7 +87,8 @@ */ @Override protected void engineInit(int keysize, SecureRandom random) { - checkKeySize(keysize); + checkSupport(keysize, 0); + this.primeSize = keysize; this.random = random; } @@ -108,21 +113,17 @@ ("Inappropriate parameter type"); } - DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; - primeSize = dhParamSpec.getPrimeSize(); - exponentSize = dhParamSpec.getExponentSize(); - if ((exponentSize <= 0) || (exponentSize >= primeSize)) { - throw new InvalidAlgorithmParameterException( - "Exponent size (" + exponentSize + - ") must be positive and less than modulus size (" + - primeSize + ")"); - } + DHGenParameterSpec dhParamSpec = (DHGenParameterSpec) genParamSpec; + int primeSize = dhParamSpec.getPrimeSize(); + int exponentSize = dhParamSpec.getExponentSize(); try { - checkKeySize(primeSize); + checkSupport(primeSize, exponentSize); } catch (InvalidParameterException ipe) { throw new InvalidAlgorithmParameterException(ipe.getMessage()); } + this.primeSize = primeSize; + this.exponentSize = exponentSize; this.random = random; } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/lang/StringConcatHelper.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/lang/StringConcatHelper.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/lang/StringConcatHelper.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/lang/StringConcatHelper.java 2023-01-10 13:21:55.000000000 +0000 @@ -490,8 +490,11 @@ @ForceInline static byte[] newArray(long indexCoder) { byte coder = (byte)(indexCoder >> 32); - int index = (int)indexCoder; - return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); + int index = ((int)indexCoder) << coder; + if (index < 0) { + throw new OutOfMemoryError("Overflow: String length out of range"); + } + return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index); } /** diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/lang/String.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/lang/String.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/lang/String.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/lang/String.java 2023-01-10 13:21:55.000000000 +0000 @@ -541,8 +541,7 @@ offset++; continue; } - if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) && - offset + 1 < sl) { + if ((b1 & 0xfe) == 0xc2 && offset + 1 < sl) { // b1 either 0xc2 or 0xc3 int b2 = bytes[offset + 1]; if (!isNotContinuation(b2)) { dst[dp++] = (byte)decode2(b1, b2); @@ -698,8 +697,7 @@ offset++; continue; } - if ((b1 == (byte) 0xc2 || b1 == (byte) 0xc3) && - offset + 1 < sl) { + if ((b1 & 0xfe) == 0xc2 && offset + 1 < sl) { // b1 either 0xc2 or 0xc3 int b2 = bytes[offset + 1]; if (!isNotContinuation(b2)) { dst[dp++] = (byte) decode2(b1, b2); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/net/InetAddress.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/net/InetAddress.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/net/InetAddress.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/net/InetAddress.java 2023-01-10 13:21:55.000000000 +0000 @@ -1360,6 +1360,10 @@ InetAddress[] ret = new InetAddress[1]; if(addr != null) { if (addr.length == Inet4Address.INADDRSZ) { + if (numericZone != -1 || ifname != null) { + // IPv4-mapped address must not contain zone-id + throw new UnknownHostException(host + ": invalid IPv4-mapped address"); + } ret[0] = new Inet4Address(null, addr); } else { if (ifname != null) { @@ -1404,22 +1408,23 @@ int percent = s.indexOf ('%'); int slen = s.length(); int digit, zone=0; + int multmax = Integer.MAX_VALUE / 10; // for int overflow detection if (percent == -1) { return -1; } for (int i=percent+1; i multmax) { return -1; } zone = (zone * 10) + digit; + if (zone < 0) { + return -1; + } + } return zone; } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/Base64.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/Base64.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/Base64.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/Base64.java 2023-01-10 13:21:55.000000000 +0000 @@ -753,16 +753,15 @@ * chunks of the src that are of a favorable size for the specific * processor it's running on. * - * If the intrinsic function does not process all of the bytes in - * src, it must process a multiple of four of them, making the - * returned destination length a multiple of three. - * * If any illegal base64 bytes are encountered in src by the * intrinsic, the intrinsic must return the actual number of valid * data bytes already written to dst. Note that the '=' pad * character is treated as an illegal Base64 character by * decodeBlock, so it will not process a block of 4 bytes - * containing pad characters. + * containing pad characters. However, MIME decoding ignores + * illegal characters, so any intrinsic overriding decodeBlock + * can choose how to handle illegal characters based on the isMIME + * parameter. * * Given the parameters, no length check is possible on dst, so dst * is assumed to be large enough to store the decoded bytes. @@ -779,10 +778,12 @@ * the offset into dst array to begin writing * @param isURL * boolean, when true decode RFC4648 URL-safe base64 characters + * @param isMIME + * boolean, when true decode according to RFC2045 (ignore illegal chars) * @return the number of destination data bytes produced */ @IntrinsicCandidate - private int decodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL) { + private int decodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL, boolean isMIME) { int[] base64 = isURL ? fromBase64URL : fromBase64; int sl0 = sp + ((sl - sp) & ~0b11); int new_dp = dp; @@ -810,12 +811,12 @@ while (sp < sl) { if (shiftto == 18 && sp < sl - 4) { // fast path - int dl = decodeBlock(src, sp, sl, dst, dp, isURL); + int dl = decodeBlock(src, sp, sl, dst, dp, isURL, isMIME); /* * Calculate how many characters were processed by how many * bytes of data were returned. */ - int chars_decoded = (dl / 3) * 4; + int chars_decoded = ((dl + 2) / 3) * 4; sp += chars_decoded; dp += dl; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalDouble.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalDouble.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalDouble.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalDouble.java 2023-01-10 13:21:55.000000000 +0000 @@ -328,7 +328,7 @@ @Override public String toString() { return isPresent - ? String.format("OptionalDouble[%s]", value) + ? ("OptionalDouble[" + value + "]") : "OptionalDouble.empty"; } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalInt.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalInt.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalInt.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalInt.java 2023-01-10 13:21:55.000000000 +0000 @@ -326,7 +326,7 @@ @Override public String toString() { return isPresent - ? String.format("OptionalInt[%s]", value) + ? ("OptionalInt[" + value + "]") : "OptionalInt.empty"; } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/Optional.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/Optional.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/Optional.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/Optional.java 2023-01-10 13:21:55.000000000 +0000 @@ -454,7 +454,7 @@ @Override public String toString() { return value != null - ? String.format("Optional[%s]", value) + ? ("Optional[" + value + "]") : "Optional.empty"; } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalLong.java openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalLong.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/java/util/OptionalLong.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/java/util/OptionalLong.java 2023-01-10 13:21:55.000000000 +0000 @@ -326,7 +326,7 @@ @Override public String toString() { return isPresent - ? String.format("OptionalLong[%s]", value) + ? ("OptionalLong[" + value + "]") : "OptionalLong.empty"; } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/login/LoginContext.java openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/login/LoginContext.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/login/LoginContext.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/login/LoginContext.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, 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 @@ -691,13 +691,13 @@ // - this can only be non-zero if methodName is LOGIN_METHOD for (int i = moduleIndex; i < moduleStack.length; i++, moduleIndex++) { + String name = moduleStack[i].entry.getLoginModuleName(); try { if (moduleStack[i].module == null) { // locate and instantiate the LoginModule // - String name = moduleStack[i].entry.getLoginModuleName(); Set> lmProviders; synchronized(providersCache){ lmProviders = providersCache.get(contextClassLoader); @@ -780,16 +780,16 @@ clearState(); if (debug != null) - debug.println(methodName + " SUFFICIENT success"); + debug.println(name + " " + methodName + " SUFFICIENT success"); return; } if (debug != null) - debug.println(methodName + " success"); + debug.println(name + " " + methodName + " success"); success = true; } else { if (debug != null) - debug.println(methodName + " ignored"); + debug.println(name + " " + methodName + " ignored"); } } catch (Exception ite) { @@ -854,7 +854,7 @@ AppConfigurationEntry.LoginModuleControlFlag.REQUISITE) { if (debug != null) - debug.println(methodName + " REQUISITE failure"); + debug.println(name + " " + methodName + " REQUISITE failure"); // if REQUISITE, then immediately throw an exception if (methodName.equals(ABORT_METHOD) || @@ -869,7 +869,7 @@ AppConfigurationEntry.LoginModuleControlFlag.REQUIRED) { if (debug != null) - debug.println(methodName + " REQUIRED failure"); + debug.println(name + " " + methodName + " REQUIRED failure"); // mark down that a REQUIRED module failed if (firstRequiredError == null) @@ -878,7 +878,7 @@ } else { if (debug != null) - debug.println(methodName + " OPTIONAL failure"); + debug.println(name + " " + methodName + " OPTIONAL failure"); // mark down that an OPTIONAL module failed if (firstError == null) diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/spi/LoginModule.java openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/spi/LoginModule.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/spi/LoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/spi/LoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, 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 @@ -26,7 +26,6 @@ package javax.security.auth.spi; import javax.security.auth.Subject; -import javax.security.auth.AuthPermission; import javax.security.auth.callback.*; import javax.security.auth.login.*; import java.util.Map; @@ -50,13 +49,13 @@ * a {@code Subject}, a {@code CallbackHandler}, shared * {@code LoginModule} state, and LoginModule-specific options. * - * The {@code Subject} represents the + *

    The {@code Subject} represents the * {@code Subject} currently being authenticated and is updated * with relevant Credentials if authentication succeeds. * LoginModules use the {@code CallbackHandler} to * communicate with users. The {@code CallbackHandler} may be * used to prompt for usernames and passwords, for example. - * Note that the {@code CallbackHandler} may be null. LoginModules + * Note that the {@code CallbackHandler} may be {@code null}. LoginModules * which absolutely require a {@code CallbackHandler} to authenticate * the {@code Subject} may throw a {@code LoginException}. * LoginModules optionally use the shared state to share information @@ -129,7 +128,7 @@ public interface LoginModule { /** - * Initialize this LoginModule. + * Initialize this {@code LoginModule}. * *

    This method is called by the {@code LoginContext} * after this {@code LoginModule} has been instantiated. @@ -163,12 +162,12 @@ * {@code Subject} information such * as a username and password and then attempt to verify the password. * This method saves the result of the authentication attempt - * as private state within the LoginModule. + * as private state within the {@code LoginModule}. * * @exception LoginException if the authentication fails * - * @return true if the authentication succeeded, or false if this - * {@code LoginModule} should be ignored. + * @return {@code true} if the authentication succeeded, or {@code false} + * if this {@code LoginModule} should be ignored. */ boolean login() throws LoginException; @@ -190,8 +189,8 @@ * * @exception LoginException if the commit fails * - * @return true if this method succeeded, or false if this - * {@code LoginModule} should be ignored. + * @return {@code true} if this method succeeded, or {@code false} + * if this {@code LoginModule} should be ignored. */ boolean commit() throws LoginException; @@ -210,8 +209,8 @@ * * @exception LoginException if the abort fails * - * @return true if this method succeeded, or false if this - * {@code LoginModule} should be ignored. + * @return {@code true} if this method succeeded, or {@code false} + * if this {@code LoginModule} should be ignored. */ boolean abort() throws LoginException; @@ -223,8 +222,15 @@ * * @exception LoginException if the logout fails * - * @return true if this method succeeded, or false if this - * {@code LoginModule} should be ignored. + * @return {@code true} if this method succeeded, or {@code false} + * if this {@code LoginModule} should be ignored. + * + * @implNote Implementations should check if a variable is {@code null} + * before removing it from the Principals or Credentials set + * of a {@code Subject}, otherwise a {@code NullPointerException} + * will be thrown as these sets {@linkplain Subject#Subject() + * prohibit null elements}. This is especially important if + * this method is called after a login failure. */ boolean logout() throws LoginException; } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/Subject.java openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/Subject.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/javax/security/auth/Subject.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/javax/security/auth/Subject.java 2023-01-10 13:21:55.000000000 +0000 @@ -144,8 +144,8 @@ * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. These Sets - * also prohibit null elements, and attempts to add or query a null - * element will result in a {@code NullPointerException}. + * also prohibit null elements, and attempts to add, query, or remove + * a null element will result in a {@code NullPointerException}. * *

    To modify the Principals Set, the caller must have * {@code AuthPermission("modifyPrincipals")}. @@ -174,8 +174,8 @@ * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. These Sets - * also prohibit null elements, and attempts to add or query a null - * element will result in a {@code NullPointerException}. + * also prohibit null elements, and attempts to add, query, or remove + * a null element will result in a {@code NullPointerException}. * *

    To modify the Principals Set, the caller must have * {@code AuthPermission("modifyPrincipals")}. diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java openjdk-17-17.0.6+10/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java 2023-01-10 13:21:55.000000000 +0000 @@ -385,7 +385,21 @@ throw new InternalError("Native library " + name + " has been loaded"); } - return load(this, name, isBuiltin, isJNI, loadLibraryOnlyIfPresent); + return load(this, name, isBuiltin, isJNI, throwExceptionIfFail()); + } + + @SuppressWarnings("removal") + private boolean throwExceptionIfFail() { + if (loadLibraryOnlyIfPresent) return true; + + // If the file exists but fails to load, UnsatisfiedLinkException thrown by the VM + // will include the error message from dlopen to provide diagnostic information + return AccessController.doPrivileged(new PrivilegedAction<>() { + public Boolean run() { + File file = new File(name); + return file.exists(); + } + }); } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/net/util/IPAddressUtil.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/net/util/IPAddressUtil.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/net/util/IPAddressUtil.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/net/util/IPAddressUtil.java 2023-01-10 13:21:55.000000000 +0000 @@ -785,7 +785,7 @@ } // Parse ASCII digit in given radix - private static int parseAsciiDigit(char c, int radix) { + public static int parseAsciiDigit(char c, int radix) { assert radix == OCTAL || radix == DECIMAL || radix == HEXADECIMAL; if (radix == HEXADECIMAL) { return parseAsciiHexDigit(c); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2023-01-10 13:21:55.000000000 +0000 @@ -2266,11 +2266,6 @@ /* Update existing KeyEntry in entries table */ if (chain.size() > 0) { entry.chain = chain.toArray(new Certificate[chain.size()]); - } else { - // Remove private key entries where there is no associated - // certs. Most likely the keystore is loaded with a null - // password. - entries.remove(entry); } } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/provider/ParameterCache.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/provider/ParameterCache.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/provider/ParameterCache.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/provider/ParameterCache.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ import java.security.spec.*; import javax.crypto.spec.DHParameterSpec; +import sun.security.util.SafeDHParameterSpec; /** * Cache for DSA and DH parameter specs. Used by the KeyPairGenerators @@ -55,6 +56,26 @@ // cache of DH parameters private static final Map dhCache; + // convert DHParameterSpec to SafeDHParameterSpec if its parameters are + // safe primes; validation takes time but should be worthwhile for the + // parameter cache since the parameters may be reused many times. + private static DHParameterSpec makeSafe(DHParameterSpec spec) { + if (spec instanceof SafeDHParameterSpec) { + return spec; + } + + BigInteger p = spec.getP(); + BigInteger g = spec.getG(); + + boolean isSafe = (g.equals(BigInteger.TWO) && p.testBit(0) && + p.shiftRight(1).isProbablePrime(100)); + if (isSafe) { + return new SafeDHParameterSpec(p, g, spec.getL()); + } else { + return spec; + } + } + /** * Return cached DSA parameters for the given length combination of * prime and subprime, or null if none are available in the cache. @@ -74,7 +95,7 @@ * are available in the cache. */ public static DHParameterSpec getCachedDHParameterSpec(int keyLength) { - return dhCache.get(Integer.valueOf(keyLength)); + return dhCache.get(keyLength); } /** @@ -132,7 +153,7 @@ gen.init(keyLength, random); AlgorithmParameters params = gen.generateParameters(); spec = params.getParameterSpec(DHParameterSpec.class); - dhCache.put(Integer.valueOf(keyLength), spec); + dhCache.put(keyLength, makeSafe(spec)); return spec; } @@ -394,6 +415,12 @@ // the common generator BigInteger dhG = BigInteger.TWO; + // Self generated following the approach from RFC 2412 Appendix E but + // using random source instead of binary expansion of pi + BigInteger dhP512 = new BigInteger( + "FFFFFFFFFFFFFFFF8B479B3A6E8DE86C294188F0BF2CD86C" + + "DB950ADB36D0F61FD51E46F69C99ED95ABE5A7BBB230A6ED" + + "1D0B4506B5317284FFFFFFFFFFFFFFFF", 16); // // From RFC 7296 @@ -562,16 +589,18 @@ "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" + "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 16); - // use DSA parameters for DH for sizes not defined in RFC 7296, 3526 - dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512)); + // self-generated safe prime + dhCache.put(512, new SafeDHParameterSpec(dhP512, dhG)); - dhCache.put(Integer.valueOf(768), new DHParameterSpec(dhP768, dhG)); - dhCache.put(Integer.valueOf(1024), new DHParameterSpec(dhP1024, dhG)); - dhCache.put(Integer.valueOf(1536), new DHParameterSpec(dhP1536, dhG)); - dhCache.put(Integer.valueOf(2048), new DHParameterSpec(dhP2048, dhG)); - dhCache.put(Integer.valueOf(3072), new DHParameterSpec(dhP3072, dhG)); - dhCache.put(Integer.valueOf(4096), new DHParameterSpec(dhP4096, dhG)); - dhCache.put(Integer.valueOf(6144), new DHParameterSpec(dhP6144, dhG)); - dhCache.put(Integer.valueOf(8192), new DHParameterSpec(dhP8192, dhG)); + // from RFC 7296 + dhCache.put(768, new SafeDHParameterSpec(dhP768, dhG)); + dhCache.put(1024, new SafeDHParameterSpec(dhP1024, dhG)); + // from RFC 3526 + dhCache.put(1536, new SafeDHParameterSpec(dhP1536, dhG)); + dhCache.put(2048, new SafeDHParameterSpec(dhP2048, dhG)); + dhCache.put(3072, new SafeDHParameterSpec(dhP3072, dhG)); + dhCache.put(4096, new SafeDHParameterSpec(dhP4096, dhG)); + dhCache.put(6144, new SafeDHParameterSpec(dhP6144, dhG)); + dhCache.put(8192, new SafeDHParameterSpec(dhP8192, dhG)); } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/ClientHello.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/ClientHello.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/ClientHello.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/ClientHello.java 2023-01-10 13:21:55.000000000 +0000 @@ -568,15 +568,15 @@ "No new session is allowed and " + "no existing session can be resumed"); } - - if (chc.maximumActiveProtocol.useTLS13PlusSpec() && - SSLConfiguration.useCompatibilityMode) { - // In compatibility mode, the TLS 1.3 legacy_session_id - // field MUST be non-empty, so a client not offering a - // pre-TLS 1.3 session MUST generate a new 32-byte value. - sessionId = + } + if (sessionId.length() == 0 && + chc.maximumActiveProtocol.useTLS13PlusSpec() && + SSLConfiguration.useCompatibilityMode) { + // In compatibility mode, the TLS 1.3 legacy_session_id + // field MUST be non-empty, so a client not offering a + // pre-TLS 1.3 session MUST generate a new 32-byte value. + sessionId = new SessionId(true, chc.sslContext.getSecureRandom()); - } } ProtocolVersion minimumVersion = ProtocolVersion.NONE; @@ -1379,25 +1379,30 @@ shc.resumingSession = resumingSession ? previous : null; } - HelloCookieManager hcm = - shc.sslContext.getHelloCookieManager(ProtocolVersion.DTLS10); - if (!shc.isResumption && - !hcm.isCookieValid(shc, clientHello, clientHello.cookie)) { - // - // Perform cookie exchange for DTLS handshaking if no cookie - // or the cookie is invalid in the ClientHello message. - // - // update the responders - shc.handshakeProducers.put( - SSLHandshake.HELLO_VERIFY_REQUEST.id, - SSLHandshake.HELLO_VERIFY_REQUEST); - // - // produce response handshake message - // - SSLHandshake.HELLO_VERIFY_REQUEST.produce(context, clientHello); + // We will by default exchange DTLS cookies for all handshakes + // (new and resumed) unless jdk.tls.enableDtlsResumeCookie=false. + // The property only affects the cookie exchange for resumption. + if (!shc.isResumption || SSLConfiguration.enableDtlsResumeCookie) { + HelloCookieManager hcm = + shc.sslContext.getHelloCookieManager(ProtocolVersion.DTLS10); + if (!hcm.isCookieValid(shc, clientHello, clientHello.cookie)) { + // + // Perform cookie exchange for DTLS handshaking if no cookie + // or the cookie is invalid in the ClientHello message. + // + // update the responders + shc.handshakeProducers.put( + SSLHandshake.HELLO_VERIFY_REQUEST.id, + SSLHandshake.HELLO_VERIFY_REQUEST); - return; + // + // produce response handshake message + // + SSLHandshake.HELLO_VERIFY_REQUEST.produce(context, clientHello); + + return; + } } // cache the client random number for further using diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.crypto.spec.DHParameterSpec; +import sun.security.util.SafeDHParameterSpec; /** * Predefined default DH ephemeral parameters. @@ -280,8 +281,8 @@ String baseGenerator = paramsFinder.group(2); BigInteger g = new BigInteger(baseGenerator, 16); - DHParameterSpec spec = new DHParameterSpec(p, g); int primeLen = p.bitLength(); + DHParameterSpec spec = new DHParameterSpec(p, g); defaultParams.put(primeLen, spec); } } else if (SSLLogger.isOn && SSLLogger.isOn("sslctx")) { @@ -293,7 +294,7 @@ Map tempFFDHEs = new HashMap<>(); for (BigInteger p : ffdhePrimes) { int primeLen = p.bitLength(); - DHParameterSpec dhps = new DHParameterSpec(p, BigInteger.TWO); + DHParameterSpec dhps = new SafeDHParameterSpec(p, BigInteger.TWO); tempFFDHEs.put(primeLen, dhps); defaultParams.putIfAbsent(primeLen, dhps); } @@ -301,8 +302,8 @@ for (BigInteger p : supportedPrimes) { int primeLen = p.bitLength(); if (defaultParams.get(primeLen) == null) { - defaultParams.put(primeLen, - new DHParameterSpec(p, BigInteger.TWO)); + defaultParams.put(primeLen, new SafeDHParameterSpec(p, + BigInteger.TWO)); } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java 2023-01-10 13:21:55.000000000 +0000 @@ -97,7 +97,7 @@ static final boolean allowLegacyMasterSecret = Utilities.getBooleanProperty("jdk.tls.allowLegacyMasterSecret", true); - // Allow full handshake without Extended Master Secret extension. + // Use TLS1.3 middlebox compatibility mode. static final boolean useCompatibilityMode = Utilities.getBooleanProperty( "jdk.tls.client.useCompatibilityMode", true); @@ -113,6 +113,9 @@ static final int maxCertificateChainLength = GetIntegerAction.privilegedGetProperty( "jdk.tls.maxCertificateChainLength", 10); + static final boolean enableDtlsResumeCookie = Utilities.getBooleanProperty( + "jdk.tls.enableDtlsResumeCookie", true); + // Is the extended_master_secret extension supported? static { boolean supportExtendedMasterSecret = Utilities.getBooleanProperty( diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -48,7 +48,7 @@ import javax.net.ssl.SSLSession; /** - * Implementation of an non-blocking SSLEngine. + * Implementation of a non-blocking SSLEngine. * * @author Brad Wetmore */ @@ -270,7 +270,7 @@ if (ciphertext == null && !conContext.isNegotiated && conContext.isInboundClosed() && hsStatus == HandshakeStatus.NEED_WRAP) { - // Even the outboud is open, no futher data could be wrapped as: + // Even the outbound is open, no further data could be wrapped as: // 1. the outbound is empty // 2. no negotiated connection // 3. the inbound has closed, cannot complete the handshake @@ -789,17 +789,17 @@ // Is it ready to close inbound? // // No exception if the initial handshake is not started. - if (!conContext.isInputCloseNotified && - (conContext.isNegotiated || - conContext.handshakeContext != null)) { - - throw conContext.fatal(Alert.INTERNAL_ERROR, + if (!conContext.isInputCloseNotified && (conContext.isNegotiated + || conContext.handshakeContext != null)) { + throw new SSLException( "closing inbound before receiving peer's close_notify"); } - - conContext.closeInbound(); } finally { - engineLock.unlock(); + try { + conContext.closeInbound(); + } finally { + engineLock.unlock(); + } } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -639,8 +639,12 @@ if (!conContext.protocolVersion.useTLS13PlusSpec()) { hasCloseReceipt = true; } else { - // Use a user_canceled alert for TLS 1.3 duplex close. - useUserCanceled = true; + // Do not use user_canceled workaround if the other side has + // already half-closed the connection + if (!conContext.isInboundClosed()) { + // Use a user_canceled alert for TLS 1.3 duplex close. + useUserCanceled = true; + } } } else if (conContext.handshakeContext != null) { // initial handshake // Use user_canceled alert regardless the protocol versions. @@ -838,9 +842,10 @@ // No need to throw exception if the initial handshake is not started. try { if (checkCloseNotify && !conContext.isInputCloseNotified && - (conContext.isNegotiated || conContext.handshakeContext != null)) { - throw new SSLException( - "closing inbound before receiving peer's close_notify"); + (conContext.isNegotiated || + conContext.handshakeContext != null)) { + throw new SSLException( + "closing inbound before receiving peer's close_notify"); } } finally { conContext.closeInbound(); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/SSLSocketInputRecord.java 2023-01-10 13:21:55.000000000 +0000 @@ -255,7 +255,11 @@ // Decrypt the fragment // ByteBuffer fragment; + recordLock.lock(); try { + if (isClosed) { + return null; + } Plaintext plaintext = readCipher.decrypt(contentType, recordBody, null); fragment = plaintext.fragment; @@ -265,6 +269,8 @@ } catch (GeneralSecurityException gse) { throw (SSLProtocolException)(new SSLProtocolException( "Unexpected exception")).initCause(gse); + } finally { + recordLock.unlock(); } if (contentType != ContentType.HANDSHAKE.id && diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/Utilities.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/Utilities.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/Utilities.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/Utilities.java 2023-01-10 13:21:55.000000000 +0000 @@ -101,14 +101,19 @@ * not look like a FQDN */ private static SNIHostName rawToSNIHostName(String hostname) { - SNIHostName sniHostName = null; + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (hostname != null && hostname.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + hostname = hostname.substring(0, hostname.length() - 1); + } + if (hostname != null && hostname.indexOf('.') > 0 && !hostname.endsWith(".") && !IPAddressUtil.isIPv4LiteralAddress(hostname) && !IPAddressUtil.isIPv6LiteralAddress(hostname)) { try { - sniHostName = new SNIHostName(hostname); + return new SNIHostName(hostname); } catch (IllegalArgumentException iae) { // don't bother to handle illegal host_name if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { @@ -118,7 +123,7 @@ } } - return sniHostName; + return null; } /** diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -404,6 +404,12 @@ boolean identifiable = false; String peerHost = session.getPeerHost(); + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (peerHost != null && peerHost.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + peerHost = peerHost.substring(0, peerHost.length() - 1); + } + if (!checkClientTrusted) { List sniNames = getRequestedServerNames(session); String sniHostName = getHostNameInSNI(sniNames); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, 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 @@ -160,7 +160,7 @@ } } catch (Exception e) { - throw new IllegalArgumentException(e.getMessage()); + throw new IllegalArgumentException(e.getMessage(), e); } generateInternal(); } @@ -176,7 +176,7 @@ keyGen.initialize(keyBits, prng); } catch (Exception e) { - throw new IllegalArgumentException(e.getMessage()); + throw new IllegalArgumentException(e.getMessage(), e); } } generateInternal(); @@ -349,7 +349,7 @@ } catch (IOException e) { throw new CertificateEncodingException("getSelfCert: " + - e.getMessage()); + e.getMessage(), e); } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/Main.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,10 +31,14 @@ import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertStoreException; import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; +import java.security.cert.TrustAnchor; import java.security.cert.URICertStoreParameters; @@ -60,6 +64,7 @@ import java.util.Base64; import sun.security.pkcs12.PKCS12KeyStore; +import sun.security.provider.certpath.CertPathConstraintsParameters; import sun.security.util.ECKeySizeParameterSpec; import sun.security.util.KeyUtil; import sun.security.util.NamedCurve; @@ -83,6 +88,7 @@ import sun.security.tools.PathList; import sun.security.util.DerValue; import sun.security.util.Pem; +import sun.security.validator.Validator; import sun.security.x509.*; import static java.security.KeyStore.*; @@ -178,6 +184,8 @@ // Warnings on weak algorithms etc private List weakWarnings = new ArrayList<>(); + private Set trustedCerts = new HashSet<>(); + private static final DisabledAlgorithmConstraints DISABLED_CHECK = new DisabledAlgorithmConstraints( DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); @@ -1117,6 +1125,7 @@ } } + KeyStore cakstore = buildTrustedCerts(); // -trustcacerts can be specified on -importcert, -printcert or -printcrl. // Reset it so that warnings on CA cert will remain for other command. if (command != IMPORTCERT && command != PRINTCERT @@ -1125,7 +1134,13 @@ } if (trustcacerts) { - caks = KeyStoreUtil.getCacertsKeyStore(); + if (cakstore != null) { + caks = cakstore; + } else { + // try to load cacerts again, and let exception propagate + // if it cannot be loaded + caks = KeyStoreUtil.getCacertsKeyStore(); + } } // Perform the specified command @@ -1482,7 +1497,9 @@ byte[] rawReq = Pem.decode(new String(sb)); PKCS10 req = new PKCS10(rawReq); - checkWeak(rb.getString("the.certificate.request"), req); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, cpcp); info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo())); info.set(X509CertInfo.SUBJECT, @@ -1541,8 +1558,11 @@ } } - checkWeak(rb.getString("the.issuer"), keyStore.getCertificateChain(alias)); - checkWeak(rb.getString("the.generated.certificate"), cert); + checkWeakConstraint(rb.getString("the.issuer"), + keyStore.getCertificateChain(alias)); + cpcp = buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.generated.certificate"), + cert, cpcp); } private void doGenCRL(PrintStream out) @@ -1591,7 +1611,10 @@ } else { out.write(crl.getEncodedInternal()); } - checkWeak(rb.getString("the.generated.crl"), crl, privateKey); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + privateKey, null, null); + checkWeakConstraint(rb.getString("the.generated.crl"), crl, privateKey, + cpcp); } /** @@ -1637,7 +1660,10 @@ request.encodeAndSign(subject, privKey, sigAlgName); request.print(out); - checkWeak(rb.getString("the.generated.certificate.request"), request); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + request.getSubjectPublicKeyInfo(), null, null); + checkWeakConstraint(rb.getString("the.generated.certificate.request"), + request, cpcp); } /** @@ -1682,7 +1708,9 @@ throw new Exception(form.format(source)); } dumpCert(cert, out); - checkWeak(rb.getString("the.certificate"), cert); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.certificate"), cert, cpcp); } /** @@ -2020,7 +2048,8 @@ } else { finalChain = new Certificate[] { newCert }; } - checkWeak(rb.getString("the.generated.certificate"), finalChain); + checkWeakConstraint(rb.getString("the.generated.certificate"), + finalChain); keyStore.setKeyEntry(alias, privKey, keyPass, finalChain); } @@ -2113,6 +2142,7 @@ private void doPrintEntry(String label, String alias, PrintStream out) throws Exception { + CertPathConstraintsParameters cpcp; if (keyStore.containsAlias(alias) == false) { MessageFormat form = new MessageFormat (rb.getString("Alias.alias.does.not.exist")); @@ -2169,6 +2199,10 @@ if (verbose || rfc || debug) { out.println(rb.getString ("Certificate.chain.length.") + chain.length); + + X509Certificate[] xcerts = convertCerts(chain); + List certs = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(certs); for (int i = 0; i < chain.length; i ++) { MessageFormat form = new MessageFormat (rb.getString("Certificate.i.1.")); @@ -2181,14 +2215,26 @@ } else { dumpCert(chain[i], out); } - checkWeak(label, chain[i]); + + if (i == 0 && + ((X509Certificate)chain[0]). + getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint((X509Certificate) chain[i], anchor); + } else { + cpcp = new CertPathConstraintsParameters( + (X509Certificate)chain[i], null, anchor, + null); + } + + checkWeakConstraint(label, chain[i], cpcp); } } else { // Print the digest of the user cert only out.println (rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", chain[0])); - checkWeak(label, chain); + checkWeakConstraint(label, chain); } } else { out.println(rb.getString @@ -2217,7 +2263,8 @@ out.println(rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", cert)); } - checkWeak(label, cert); + cpcp = buildCertPathConstraint((X509Certificate)cert, null); + checkWeakConstraint(label, cert, cpcp); } else { out.println(rb.getString("Unknown.Entry.Type")); } @@ -2444,7 +2491,9 @@ try { Certificate c = srckeystore.getCertificate(alias); if (c != null) { - checkWeak("<" + newAlias + ">", c); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)c, null); + checkWeakConstraint("<" + newAlias + ">", c, cpcp); } keyStore.setEntry(newAlias, entry, pp); // Place the check so that only successful imports are blocked. @@ -2641,11 +2690,14 @@ issuer = verifyCRL(caks, crl); if (issuer != null) { signer = caks.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "cacerts", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2653,11 +2705,14 @@ issuer = verifyCRL(keyStore, crl); if (issuer != null) { signer = keyStore.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "keystore", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2674,7 +2729,15 @@ out.println(rb.getString ("STARNN")); } - checkWeak(rb.getString("the.crl"), crl, signer == null ? null : signer.getPublicKey()); + + if (signer != null) { + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, null); + checkWeakConstraint(rb.getString("the.crl"), crl, + signer.getPublicKey(), cpcp); + } else { + checkWeak(rb.getString("the.crl"), crl, null); + } } } @@ -2720,10 +2783,12 @@ PKCS10 req = new PKCS10(Pem.decode(new String(sb))); PublicKey pkey = req.getSubjectPublicKeyInfo(); + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters(pkey, null, null); out.printf(rb.getString("PKCS.10.with.weak"), req.getSubjectName(), pkey.getFormat(), - withWeak(pkey), + withWeakConstraint(pkey, cpcp), withWeak(req.getSigAlg())); for (PKCS10Attribute attr: req.getAttributes().getAttributes()) { ObjectIdentifier oid = attr.getAttributeId(); @@ -2747,7 +2812,12 @@ if (debug) { out.println(req); // Just to see more, say, public key length... } - checkWeak(rb.getString("the.certificate.request"), req); + + CertPathConstraintsParameters cpcp1 = + new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, + cpcp1); } /** @@ -2767,6 +2837,9 @@ throw new Exception(rb.getString("Empty.input")); } Certificate[] certs = c.toArray(new Certificate[c.size()]); + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i=0; i 1 && signerCnt == 1) { + return String.format(rb.getString("one.in.many1"), label, certNo); + } + if (certCnt == 1 && signerCnt > 1) { + return String.format(rb.getString("one.in.many2"), label, signerNo); + } + if (certCnt > 1 && signerCnt > 1) { + return String.format(rb.getString("one.in.many3"), label, certNo, signerNo); + } + return label; + } + private void doPrintCert(final PrintStream out) throws Exception { if (jarfile != null) { // reset "jdk.certpath.disabledAlgorithms" security property @@ -2853,7 +2953,7 @@ JarFile jf = new JarFile(jarfile, true); Enumeration entries = jf.entries(); - Set ss = new HashSet<>(); + LinkedHashSet ss = new LinkedHashSet<>(); byte[] buffer = new byte[8192]; int pos = 0; while (entries.hasMoreElements()) { @@ -2870,48 +2970,83 @@ for (CodeSigner signer: signers) { if (!ss.contains(signer)) { ss.add(signer); - out.printf(rb.getString("Signer.d."), ++pos); - out.println(); - out.println(); - out.println(rb.getString("Signature.")); - out.println(); - - List certs - = signer.getSignerCertPath().getCertificates(); - int cc = 0; - for (Certificate cert: certs) { - X509Certificate x = (X509Certificate)cert; - if (rfc) { - out.println(rb.getString("Certificate.owner.") + x.getSubjectX500Principal() + "\n"); - dumpCert(x, out); - } else { - printX509Cert(x, out); - } - out.println(); - checkWeak(oneInMany(rb.getString("the.certificate"), cc++, certs.size()), x); - } - Timestamp ts = signer.getTimestamp(); - if (ts != null) { - out.println(rb.getString("Timestamp.")); - out.println(); - certs = ts.getSignerCertPath().getCertificates(); - cc = 0; - for (Certificate cert: certs) { - X509Certificate x = (X509Certificate)cert; - if (rfc) { - out.println(rb.getString("Certificate.owner.") + x.getSubjectX500Principal() + "\n"); - dumpCert(x, out); - } else { - printX509Cert(x, out); - } - out.println(); - checkWeak(oneInMany(rb.getString("the.tsa.certificate"), cc++, certs.size()), x); - } - } } } } } + + for (CodeSigner signer: ss) { + out.printf(rb.getString("Signer.d."), ++pos); + out.println(); + out.println(); + + List certs + = signer.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List chain = + (List)certs; + TrustAnchor anchor = findTrustAnchor(chain); + CertPathConstraintsParameters cpcp; + int cc = 0; + for (Certificate cert: certs) { + out.printf(rb.getString("Certificate.d."), ++cc); + out.println(); + X509Certificate x = (X509Certificate)cert; + if (rfc) { + out.println(rb.getString("Certificate.owner.") + x.getSubjectX500Principal() + "\n"); + dumpCert(x, out); + } else { + printX509Cert(x, out); + } + out.println(); + if (cc == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( + "the.certificate"), cc, + certs.size(), pos, + ss.size()), x, cpcp); + } + Timestamp ts = signer.getTimestamp(); + if (ts != null) { + out.println(rb.getString("Timestamp.")); + out.println(); + certs = ts.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List tschain = + (List)certs; + anchor = findTrustAnchor(tschain); + cc = 0; + for (Certificate cert: certs) { + out.printf(rb.getString("Certificate.d."), ++cc); + out.println(); + X509Certificate x = (X509Certificate)cert; + if (rfc) { + out.println(rb.getString("Certificate.owner.") + x.getSubjectX500Principal() + "\n"); + dumpCert(x, out); + } else { + printX509Cert(x, out); + } + out.println(); + if (cc == 0 && + x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( + "the.tsa.certificate"), cc, + certs.size(), pos, + ss.size()), x, cpcp); + } + } + } jf.close(); if (ss.isEmpty()) { out.println(rb.getString("Not.a.signed.jar.file")); @@ -2938,6 +3073,9 @@ } int i = 0; + @SuppressWarnings("unchecked") + List xcerts = (List)chain; + TrustAnchor anchor = findTrustAnchor(xcerts); for (Certificate cert : chain) { try { if (rfc) { @@ -2948,7 +3086,17 @@ printX509Cert((X509Certificate)cert, out); out.println(); } - checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert); + X509Certificate x = (X509Certificate)cert; + CertPathConstraintsParameters cpcp; + if (i == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInMany(rb.getString( + "the.certificate"), i++, chain.size()), x, cpcp); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -3172,8 +3320,11 @@ throw new Exception(rb.getString("Input.not.an.X.509.certificate")); } + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + if (noprompt) { - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); keyStore.setCertificateEntry(alias, cert); return true; } @@ -3193,7 +3344,7 @@ ("Certificate.already.exists.in.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.no.")); @@ -3204,7 +3355,7 @@ ("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no.")); @@ -3213,7 +3364,7 @@ // Print the cert and ask user if they really want to add // it to their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3240,7 +3391,7 @@ // Print the cert and ask user if they really want to add it to // their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3380,6 +3531,21 @@ return keyPass; } + private String withWeakConstraint(String alg, + CertPathConstraintsParameters cpcp) { + try { + DISABLED_CHECK.permits(alg, cpcp, false); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.disabled"), alg); + } + try { + LEGACY_CHECK.permits(alg, cpcp, false); + return alg; + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.weak"), alg); + } + } + private String withWeak(String alg) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { @@ -3406,21 +3572,24 @@ return result; } - private String withWeak(Key key) { + private String withWeakConstraint(Key key, + CertPathConstraintsParameters cpcp) { int kLen = KeyUtil.getKeySize(key); String displayAlg = fullDisplayAlgName(key); - if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen, displayAlg); - } else { - return String.format(rb.getString("unknown.size.1"), displayAlg); - } + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen, displayAlg); } else { - return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); + return String.format(rb.getString("unknown.size.1"), displayAlg); } - } else { - return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); } } @@ -3435,9 +3604,11 @@ (rb.getString(".PATTERN.printX509Cert.with.weak")); PublicKey pkey = cert.getPublicKey(); String sigName = cert.getSigAlgName(); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); // No need to warn about sigalg of a trust anchor if (!isTrustedCert(cert)) { - sigName = withWeak(sigName); + sigName = withWeakConstraint(sigName, cpcp); } Object[] source = {cert.getSubjectX500Principal().toString(), cert.getIssuerX500Principal().toString(), @@ -3447,7 +3618,7 @@ getCertFingerPrint("SHA-1", cert), getCertFingerPrint("SHA-256", cert), sigName, - withWeak(pkey), + withWeakConstraint(pkey, cpcp), cert.getVersion() }; out.println(form.format(source)); @@ -3771,7 +3942,7 @@ throws Exception { - checkWeak(rb.getString("reply"), replyCerts); + checkWeakConstraint(rb.getString("reply"), replyCerts); // order the certs in the reply (bottom-up). // we know that all certs in the reply are of type X.509, because @@ -3853,11 +4024,14 @@ replyCerts.length); tmpCerts[tmpCerts.length-1] = root.snd; replyCerts = tmpCerts; - checkWeak(String.format(fromKeyStore + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)root.snd, + null); + checkWeakConstraint(String.format(fromKeyStore ? rb.getString("alias.in.keystore") : rb.getString("alias.in.cacerts"), root.fst), - root.snd); + root.snd, cpcp); } } return replyCerts; @@ -3922,7 +4096,9 @@ (X509Certificate) certToVerify), chain, certs)) { for (Pair p : chain) { - checkWeak(p.fst, p.snd); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(p.snd, null); + checkWeakConstraint(p.fst, p.snd, cpcp); } Certificate[] newChain = new Certificate[chain.size()]; @@ -4718,6 +4894,67 @@ } } + private void checkWeakConstraint(String label, String sigAlg, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (sigAlg != null) { + try { + DISABLED_CHECK.permits(sigAlg, cpcp, false); + try { + LEGACY_CHECK.permits(sigAlg, cpcp, false); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.weak"), label, sigAlg)); + } + } catch (CertPathValidatorException e) { + String eMessage = e.getMessage(); + if (eMessage.contains("denyAfter constraint check failed") && + e.getReason() == BasicReason.ALGORITHM_CONSTRAINED) { + String startSeparator = "Constraint date: "; + int startSepPos = eMessage.indexOf(startSeparator); + String endSeparator = "; params date"; + int endSepPos = eMessage.indexOf(endSeparator); + String denyAfterDate = null; + try { + denyAfterDate = eMessage.substring(startSepPos + startSeparator.length(), + endSepPos); + } catch (IndexOutOfBoundsException e1) { + throw new Exception(rb.getString( + "Unable.to.parse.denyAfter.string.in.exception.message")); + } + + weakWarnings.add(String.format( + rb.getString("whose.sigalg.usagesignedjar"), label, sigAlg, + denyAfterDate)); + } else { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.disabled"), label, sigAlg)); + } + if (debug) { + e.printStackTrace(); + } + } + } + + if (key != null) { + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.weak"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.disabled"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } + } + private void checkWeak(String label, String sigAlg, Key key) { if (sigAlg != null) { if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) { @@ -4744,8 +4981,11 @@ } } - private void checkWeak(String label, Certificate[] certs) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate[] certs) + throws KeyStoreException, Exception { + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i = 0; i < certs.length; i++) { Certificate cert = certs[i]; if (cert instanceof X509Certificate) { @@ -4754,23 +4994,43 @@ if (certs.length > 1) { fullLabel = oneInMany(label, i, certs.length); } - checkWeak(fullLabel, xc); + + CertPathConstraintsParameters cpcp = null; + if (i == 0 && xc.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(xc, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + xc, null, anchor, null); + } + checkWeakConstraint(fullLabel, xc, cpcp); } } } - private void checkWeak(String label, Certificate cert) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate cert, + CertPathConstraintsParameters cpcp) + throws KeyStoreException, Exception { if (cert instanceof X509Certificate) { X509Certificate xc = (X509Certificate)cert; // No need to check the sigalg of a trust anchor String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName(); - checkWeak(label, sigAlg, xc.getPublicKey()); + checkWeakConstraint(label, sigAlg, xc.getPublicKey(), cpcp); } } - private void checkWeak(String label, PKCS10 p10) { - checkWeak(label, p10.getSigAlg(), p10.getSubjectPublicKeyInfo()); + private void checkWeakConstraint(String label, PKCS10 p10, + CertPathConstraintsParameters cpcp) throws Exception { + checkWeakConstraint(label, p10.getSigAlg(), + p10.getSubjectPublicKeyInfo(), cpcp); + } + + private void checkWeakConstraint(String label, CRL crl, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (crl instanceof X509CRLImpl) { + X509CRLImpl impl = (X509CRLImpl)crl; + checkWeakConstraint(label, impl.getSigAlgName(), key, cpcp); + } } private void checkWeak(String label, CRL crl, Key key) { @@ -4780,6 +5040,76 @@ } } + private KeyStore buildTrustedCerts() { + KeyStore caks = null; + try { + caks = KeyStoreUtil.getCacertsKeyStore(); + if (caks != null) { + Enumeration aliases = caks.aliases(); + while (aliases.hasMoreElements()) { + String a = aliases.nextElement(); + try { + trustedCerts.add((X509Certificate)caks.getCertificate(a)); + } catch (Exception e2) { + // ignore, if the keystore has not been loaded/initialized properly + } + } + } + } catch (Exception e) { + // Ignore, if cacerts cannot be loaded + } + return caks; + } + + private TrustAnchor findTrustAnchor(List chain) { + if (chain.isEmpty()) { + return null; + } + + X509Certificate last = chain.get(chain.size() - 1); + Optional trusted = + trustedCerts.stream() + .filter(c -> c.getSubjectX500Principal().equals(last.getIssuerX500Principal())) + .findFirst(); + return trusted.isPresent() ? new TrustAnchor(trusted.get(), null) : null; + } + + private X509Certificate[] convertCerts(Certificate[] certs) { + X509Certificate[] xcerts = new X509Certificate[certs.length]; + + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof X509Certificate) { + xcerts[i] = (X509Certificate) certs[i]; + } + } + return xcerts; + } + + private CertPathConstraintsParameters buildCertPathConstraint( + X509Certificate xcert, TrustAnchor anchor) throws Exception{ + List eku = xcert.getExtendedKeyUsage(); + if (eku == null) { + return new CertPathConstraintsParameters(xcert, null, + anchor, null); + } + + if (eku.contains(KnownOIDs.codeSigning.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_CODE_SIGNING, anchor, null); + } else if (eku.contains(KnownOIDs.clientAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_CLIENT, anchor, null); + } else if (eku.contains(KnownOIDs.serverAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_SERVER, anchor, null); + } else if (eku.contains(KnownOIDs.KP_TimeStamping.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TSA_SERVER, anchor, null); + } + return new CertPathConstraintsParameters(xcert, Validator.VAR_GENERIC, + anchor, null); + } + private void printWeakWarnings(boolean newLine) { if (!weakWarnings.isEmpty() && !nowarn) { System.err.println("\nWarning:"); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/Resources.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/Resources.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/tools/keytool/Resources.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/tools/keytool/Resources.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, 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 @@ -396,8 +396,8 @@ {".WARNING.WARNING.WARNING.", "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signer #%d:"}, + {"Certificate.d.", "Certificate #%d:"}, {"Timestamp.", "Timestamp:"}, - {"Signature.", "Signature:"}, {"Certificate.owner.", "Certificate owner: "}, {"Not.a.signed.jar.file", "Not a signed jar file"}, {"No.certificate.from.the.SSL.server", @@ -464,6 +464,9 @@ {"the.input", "The input"}, {"reply", "Reply"}, {"one.in.many", "%1$s #%2$d of %3$d"}, + {"one.in.many1", "%1$s #%2$d"}, + {"one.in.many2", "%1$s of signer #%2$d"}, + {"one.in.many3", "%1$s #%2$d of signer #%3$d"}, {"alias.in.cacerts", "Issuer <%s> in cacerts"}, {"alias.in.keystore", "Issuer <%s>"}, {"with.weak", "%s (weak)"}, @@ -479,6 +482,8 @@ "Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"}, {"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"}, {"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."}, + {"whose.sigalg.usagesignedjar", "%1$s uses the %2$s signature algorithm which is considered a security risk and cannot be used to sign JARs after %3$s."}, + {"Unable.to.parse.denyAfter.string.in.exception.message", "Unable to parse denyAfter date string in exception message"}, {"whose.sigalg.weak", "%1$s uses the %2$s signature algorithm which is considered a security risk. This algorithm will be disabled in a future update."}, {"whose.key.disabled", "%1$s uses a %2$s which is considered a security risk and is disabled."}, {"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. This key size will be disabled in a future update."}, diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2022, 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 @@ -40,9 +40,12 @@ import java.security.spec.MGF1ParameterSpec; import java.security.spec.NamedParameterSpec; import java.security.spec.PSSParameterSpec; +import java.time.DateTimeException; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -52,7 +55,6 @@ import java.util.Set; import java.util.Collection; import java.util.StringTokenizer; -import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; import java.util.regex.Matcher; @@ -700,41 +702,30 @@ * timezone. */ private static class DenyAfterConstraint extends Constraint { - private Date denyAfterDate; + private ZonedDateTime zdt; + private Instant denyAfterDate; DenyAfterConstraint(String algo, int year, int month, int day) { - Calendar c; algorithm = algo; if (debug != null) { - debug.println("DenyAfterConstraint read in as: year " + + debug.println("DenyAfterConstraint read in as: year " + year + ", month = " + month + ", day = " + day); } - c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT")) - .setDate(year, month - 1, day).build(); - - if (year > c.getActualMaximum(Calendar.YEAR) || - year < c.getActualMinimum(Calendar.YEAR)) { - throw new IllegalArgumentException( - "Invalid year given in constraint: " + year); - } - if ((month - 1) > c.getActualMaximum(Calendar.MONTH) || - (month - 1) < c.getActualMinimum(Calendar.MONTH)) { - throw new IllegalArgumentException( - "Invalid month given in constraint: " + month); - } - if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) || - day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) { + try { + zdt = ZonedDateTime + .of(year, month, day, 0, 0, 0, 0, ZoneId.of("GMT")); + denyAfterDate = zdt.toInstant(); + } catch (DateTimeException dte) { throw new IllegalArgumentException( - "Invalid Day of Month given in constraint: " + day); + "Invalid denyAfter date", dte); } - denyAfterDate = c.getTime(); if (debug != null) { debug.println("DenyAfterConstraint date set to: " + - denyAfterDate); + zdt.toLocalDate()); } } @@ -749,23 +740,22 @@ @Override public void permits(ConstraintsParameters cp) throws CertPathValidatorException { - Date currentDate; - String errmsg; + Instant currentDate; if (cp.getDate() != null) { - currentDate = cp.getDate(); + currentDate = cp.getDate().toInstant(); } else { - currentDate = new Date(); + currentDate = Instant.now(); } - if (!denyAfterDate.after(currentDate)) { + if (!denyAfterDate.isAfter(currentDate)) { if (next(cp)) { return; } throw new CertPathValidatorException( "denyAfter constraint check failed: " + algorithm + " used with Constraint date: " + - denyAfterDate + "; params date: " + + zdt.toLocalDate() + "; params date: " + currentDate + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } @@ -784,7 +774,7 @@ debug.println("DenyAfterConstraints.permits(): " + algorithm); } - return denyAfterDate.after(new Date()); + return denyAfterDate.isAfter(Instant.now()); } } diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/SafeDHParameterSpec.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/SafeDHParameterSpec.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/SafeDHParameterSpec.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/SafeDHParameterSpec.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.security.util; + +import java.math.BigInteger; +import javax.crypto.spec.DHParameterSpec; + +/** + * Internal marker class for well-known safe DH parameters. It should + * only be used with trusted callers since it does not have all the needed + * values for validation. + */ + +public final class SafeDHParameterSpec extends DHParameterSpec { + public SafeDHParameterSpec(BigInteger p, BigInteger g) { + super(p, g); + } + + public SafeDHParameterSpec(BigInteger p, BigInteger g, int l) { + super(p, g, l); + } +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ import java.util.regex.PatternSyntaxException; import java.security.InvalidParameterException; import java.security.ProviderException; +import javax.crypto.spec.DHParameterSpec; import sun.security.action.GetPropertyAction; /** @@ -105,6 +106,42 @@ } } + public static final int getDefDHPrivateExpSize(DHParameterSpec spec) { + + int dhGroupSize = spec.getP().bitLength(); + + if (spec instanceof SafeDHParameterSpec) { + // Known safe primes + // use 2*security strength as default private exponent size + // as in table 2 of NIST SP 800-57 part 1 rev 5, sec 5.6.1.1 + // and table 25 of NIST SP 800-56A rev 3, appendix D. + if (dhGroupSize >= 15360) { + return 512; + } else if (dhGroupSize >= 8192) { + return 400; + } else if (dhGroupSize >= 7680) { + return 384; + } else if (dhGroupSize >= 6144) { + return 352; + } else if (dhGroupSize >= 4096) { + return 304; + } else if (dhGroupSize >= 3072) { + return 256; + } else if (dhGroupSize >= 2048) { + return 224; + } else { + // min value for legacy key sizes + return 160; + } + } else { + // assume the worst and use groupSize/2 as private exp length + // up to 1024-bit and use the same minimum 384 as before + return Math.max((dhGroupSize >= 2048 ? 1024 : dhGroupSize >> 1), + 384); + } + + } + public static final int DEF_DSA_KEY_SIZE; public static final int DEF_RSA_KEY_SIZE; public static final int DEF_RSASSA_PSS_KEY_SIZE; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java 2023-01-10 13:21:55.000000000 +0000 @@ -574,12 +574,8 @@ // we can then pass in the dom = -1, dow > 0 into ZoneInfo // // hacking, assume the >=24 is the result of ZRB optimization for - // "last", it works for now. From tzdata2020d this hacking - // will not work for Asia/Gaza and Asia/Hebron which follow - // Palestine DST rules. - if (dom < 0 || dom >= 24 && - !(zoneId.equals("Asia/Gaza") || - zoneId.equals("Asia/Hebron"))) { + // "last", it works for now. + if (dom < 0 || dom >= 24) { params[1] = -1; params[2] = toCalendarDOW[dow]; } else { @@ -601,7 +597,6 @@ params[7] = 0; } else { // hacking: see comment above - // No need of hacking for Asia/Gaza and Asia/Hebron from tz2021e if (dom < 0 || dom >= 24) { params[6] = -1; params[7] = toCalendarDOW[dow]; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java openjdk-17-17.0.6+10/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java --- openjdk-17-17.0.5+8/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2022, 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 @@ -429,7 +429,8 @@ "French Guiana Summer Time", "GFST", "French Guiana Time", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -518,7 +519,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Suriname Time", "SRT", diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libjava/jni_util.c openjdk-17-17.0.6+10/src/java.base/share/native/libjava/jni_util.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libjava/jni_util.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libjava/jni_util.c 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -885,6 +885,13 @@ } } + // Check `jint` overflow + if (rlen < 0) { + (*env)->ReleasePrimitiveArrayCritical(env, value, str, 0); + JNU_ThrowOutOfMemoryError(env, "requested array size exceeds VM limit"); + return NULL; + } + result = MALLOC_MIN4(rlen); if (result == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, value, str, 0); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libverify/check_code.c openjdk-17-17.0.6+10/src/java.base/share/native/libverify/check_code.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libverify/check_code.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libverify/check_code.c 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2022, 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 @@ -468,7 +468,8 @@ /* Because we can longjmp any time, we need to be very careful about * remembering what needs to be freed. */ -static void check_and_push(context_type *context, const void *ptr, int kind); +static void check_and_push_malloc_block(context_type *context, void *ptr); +static void check_and_push_string_utf(context_type *context, const char *ptr); static void pop_and_free(context_type *context); static int signature_to_args_size(const char *method_signature); @@ -604,7 +605,7 @@ unsigned short *pID; const char *name = JVM_GetClassNameUTF(env, cb); - check_and_push(context, name, VM_STRING_UTF); + check_and_push_string_utf(context, name); hash = class_hash_fun(name); pID = &(class_hash->table[hash % HASH_TABLE_SIZE]); while (*pID) { @@ -939,10 +940,10 @@ int i; lengths = malloc(sizeof(int) * num_methods); - check_and_push(context, lengths, VM_MALLOC_BLK); + check_and_push_malloc_block(context, lengths); code = malloc(sizeof(unsigned char*) * num_methods); - check_and_push(context, code, VM_MALLOC_BLK); + check_and_push_malloc_block(context, code); *(lengths_addr) = lengths; *(code_addr) = code; @@ -951,7 +952,7 @@ lengths[i] = JVM_GetMethodIxByteCodeLength(context->env, cb, i); if (lengths[i] > 0) { code[i] = malloc(sizeof(unsigned char) * (lengths[i] + 1)); - check_and_push(context, code[i], VM_MALLOC_BLK); + check_and_push_malloc_block(context, code[i]); JVM_GetMethodIxByteCode(context->env, cb, i, code[i]); } else { code[i] = NULL; @@ -1305,7 +1306,7 @@ /* Make sure the constant pool item is the right type. */ verify_constant_pool_type(context, key, kind); methodname = JVM_GetCPMethodNameUTF(env, cb, key); - check_and_push(context, methodname, VM_STRING_UTF); + check_and_push_string_utf(context, methodname); is_constructor = !strcmp(methodname, ""); is_internal = methodname[0] == '<'; pop_and_free(context); @@ -1354,7 +1355,7 @@ unsigned int args2; const char *signature = JVM_GetCPMethodSignatureUTF(env, context->class, key); - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); args1 = signature_to_args_size(signature) + 1; args2 = code[offset + 3]; if (args1 != args2) { @@ -1652,7 +1653,7 @@ classname = JVM_GetCPClassNameUTF(env, context->class, einfo.catchType); - check_and_push(context, classname, VM_STRING_UTF); + check_and_push_string_utf(context, classname); stack_item->item = make_class_info_from_name(context, classname); if (!isAssignableTo(context, stack_item->item, @@ -1807,7 +1808,7 @@ } } signature = JVM_GetMethodIxSignatureUTF(env, cb, mi); - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); /* Fill in each of the arguments into the registers. */ for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) { char fieldchar = signature_to_fieldtype(context, &p, &full_info); @@ -2050,7 +2051,7 @@ context->class, operand); char *ip = buffer; - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); #ifdef DEBUG if (verify_verbose) { print_formatted_fieldname(context, operand); @@ -2076,7 +2077,7 @@ operand); char *ip = buffer; const char *p; - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); #ifdef DEBUG if (verify_verbose) { print_formatted_methodname(context, operand); @@ -2376,7 +2377,7 @@ operand); int item; const char *p; - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); if (opcode == JVM_OPC_invokestatic) { item = 0; } else if (opcode == JVM_OPC_invokeinit) { @@ -2758,7 +2759,7 @@ const char *signature = JVM_GetCPFieldSignatureUTF(context->env, context->class, operand); - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); #ifdef DEBUG if (verify_verbose) { print_formatted_fieldname(context, operand); @@ -2780,7 +2781,7 @@ context->class, operand); const char *result_signature; - check_and_push(context, signature, VM_STRING_UTF); + check_and_push_string_utf(context, signature); result_signature = get_result_signature(signature); if (result_signature++ == NULL) { CCerror(context, "Illegal signature %s", signature); @@ -3621,7 +3622,7 @@ CCerror(context, "Internal error #5"); } - check_and_push(context, classname, VM_STRING_UTF); + check_and_push_string_utf(context, classname); if (classname[0] == JVM_SIGNATURE_ARRAY) { /* This make recursively call us, in case of a class array */ signature_to_fieldtype(context, &classname, &result); @@ -3822,8 +3823,8 @@ assert(finish >= p); length = (int)(finish - p); if (length + 1 > (int)sizeof(buffer_space)) { - buffer = calloc(length + 1, sizeof(char)); - check_and_push(context, buffer, VM_MALLOC_BLK); + buffer = malloc(length + 1); + check_and_push_malloc_block(context, buffer); } memcpy(buffer, p, length); buffer[length] = '\0'; @@ -4142,7 +4143,7 @@ } } -static void check_and_push(context_type *context, const void *ptr, int kind) +static void check_and_push_common(context_type *context, void *ptr, int kind) { alloc_stack_type *p; if (ptr == 0) @@ -4154,16 +4155,24 @@ p = malloc(sizeof(alloc_stack_type)); if (p == 0) { /* Make sure we clean up. */ - free_block((void *)ptr, kind); + free_block(ptr, kind); CCout_of_memory(context); } } p->kind = kind; - p->ptr = (void *)ptr; + p->ptr = ptr; p->next = context->allocated_memory; context->allocated_memory = p; } +static void check_and_push_malloc_block(context_type *context, void *ptr) { + check_and_push_common(context, ptr, VM_MALLOC_BLK); +} + +static void check_and_push_string_utf(context_type *context, const char *ptr) { + check_and_push_common(context, (void *)ptr, VM_STRING_UTF); +} + static void pop_and_free(context_type *context) { alloc_stack_type *p = context->allocated_memory; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/ChangeLog openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/ChangeLog --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/ChangeLog 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,1515 @@ + + ChangeLog file for zlib + +Changes in 1.2.11 (15 Jan 2017) +- Fix deflate stored bug when pulling last block from window +- Permit immediate deflateParams changes before any deflate input + +Changes in 1.2.10 (2 Jan 2017) +- Avoid warnings on snprintf() return value +- Fix bug in deflate_stored() for zero-length input +- Fix bug in gzwrite.c that produced corrupt gzip files +- Remove files to be installed before copying them in Makefile.in +- Add warnings when compiling with assembler code + +Changes in 1.2.9 (31 Dec 2016) +- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] +- Improve contrib/blast to return unused bytes +- Assure that gzoffset() is correct when appending +- Improve compress() and uncompress() to support large lengths +- Fix bug in test/example.c where error code not saved +- Remedy Coverity warning [Randers-Pehrson] +- Improve speed of gzprintf() in transparent mode +- Fix inflateInit2() bug when windowBits is 16 or 32 +- Change DEBUG macro to ZLIB_DEBUG +- Avoid uninitialized access by gzclose_w() +- Allow building zlib outside of the source directory +- Fix bug that accepted invalid zlib header when windowBits is zero +- Fix gzseek() problem on MinGW due to buggy _lseeki64 there +- Loop on write() calls in gzwrite.c in case of non-blocking I/O +- Add --warn (-w) option to ./configure for more compiler warnings +- Reject a window size of 256 bytes if not using the zlib wrapper +- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE +- Add --debug (-d) option to ./configure to define ZLIB_DEBUG +- Fix bugs in creating a very large gzip header +- Add uncompress2() function, which returns the input size used +- Assure that deflateParams() will not switch functions mid-block +- Dramatically speed up deflation for level 0 (storing) +- Add gzfread(), duplicating the interface of fread() +- Add gzfwrite(), duplicating the interface of fwrite() +- Add deflateGetDictionary() function +- Use snprintf() for later versions of Microsoft C +- Fix *Init macros to use z_ prefix when requested +- Replace as400 with os400 for OS/400 support [Monnerat] +- Add crc32_z() and adler32_z() functions with size_t lengths +- Update Visual Studio project files [AraHaan] + +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Roß] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix uninitialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Suport i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no library use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generate bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/compress.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/compress.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/compress.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/compress.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + sourceLen -= stream.avail_in; + } + err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + deflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/crc32.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/crc32.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/crc32.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/crc32.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,465 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/deflate.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/deflate.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/deflate.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/deflate.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,2222 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local int deflateStateCheck OF((z_streamp strm)); +local void slide_hash OF((deflate_state *s)); +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV +# pragma message("Assembler code may have bugs -- use at your own risk") + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef ZLIB_DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to UPDATE_HASH are made with consecutive input + * characters, so that a running hash key can be computed from the previous + * key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to INSERT_STRING are made with consecutive input + * characters and the first MIN_MATCH bytes of str are valid (except for + * the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +local void slide_hash(s) + deflate_state *s; +{ + unsigned n, m; + Posf *p; + uInt wsize = s->w_size; + + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif +} + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = (uInt)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = (uInt)memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n-2) bits have been written, just + * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * symbols are written.) The closest the writing gets to what is unread is + * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf_size = (ulg)s->lit_bufsize * 4; + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +local int deflateStateCheck (strm) + z_streamp strm; +{ + deflate_state *s; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && +#endif + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) + z_streamp strm; + Bytef *dictionary; + uInt *dictLength; +{ + deflate_state *s; + uInt len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != Z_NULL && len) + zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != Z_NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (deflateStateCheck(strm)) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = -2; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + if (bits < 0 || bits > 16 || + s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + s->last_flush != -2) { + /* Flush the last buffer: */ + int err = deflate(strm, Z_BLOCK); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_out == 0) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) + slide_hash(s); + else + CLEAR_HASH(s); + s->matches = 0; + } + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (uInt)good_length; + s->max_lazy_match = (uInt)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (uInt)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (deflateStateCheck(strm)) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + Bytef *str; + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ + s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->avail_in != 0 && strm->next_in == Z_NULL) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE) { + /* zlib header */ + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + while (s->pending + left > s->pending_buf_size) { + uInt copy = s->pending_buf_size - s->pending; + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + zmemcpy(s->pending_buf + s->pending, + s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + ulg beg = s->pending; /* start of bytes to update crc */ + int val; + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + flush_pending(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + + + if (deflateStateCheck(source) || dest == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = (int)s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef ZLIB_DEBUG + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* ZLIB_DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = s->strstart - s->block_start; /* bytes left in window */ + if (len > (ulg)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + if (len > have) + len = have; /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || + flush == Z_NO_FLUSH || + len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + _tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending_buf[s->pending - 4] = len; + s->pending_buf[s->pending - 3] = len >> 8; + s->pending_buf[s->pending - 2] = ~len; + s->pending_buf[s->pending - 1] = ~len >> 8; + + /* Write the stored block header bytes. */ + flush_pending(s->strm); + +#ifdef ZLIB_DEBUG + /* Update debugging counts for the data about to be copied. */ + s->compressed_len += len << 3; + s->bits_sent += len << 3; +#endif + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + if (left > len) + left = len; + zmemcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + read_buf(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + } + else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + } + zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + } + s->block_start = s->strstart; + s->insert += MIN(used, s->w_size - s->insert); + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && + s->strm->avail_in == 0 && (long)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart - 1; + if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { + /* Slide the window down. */ + s->block_start -= s->w_size; + s->strstart -= s->w_size; + zmemcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + } + if (have > s->strm->avail_in) + have = s->strm->avail_in; + if (have) { + read_buf(s->strm, s->window + s->strstart, have); + s->strstart += have; + } + if (s->high_water < s->strstart) + s->high_water = s->strstart; + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = s->strstart - s->block_start; + if (left >= min_block || + ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && + s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && + len == left ? 1 : 0; + _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); + s->block_start += len; + flush_pending(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (uInt)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/deflate.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/deflate.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/deflate.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/deflate.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,370 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* deflate.h -- internal compression state + * Copyright (C) 1995-2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +#endif +#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + ulg pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + ulg gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *sym_buf; /* buffer for distances and literals/lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt sym_next; /* running index in sym_buf */ + uInt sym_end; /* symbol table full when sym_next reaches this */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef ZLIB_DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = 0; \ + s->sym_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->sym_buf[s->sym_next++] = (uch)dist; \ + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ + s->sym_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzclose.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzclose.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzclose.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzclose.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzguts.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzguts.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzguts.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzguts.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,242 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzlib.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzlib.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzlib.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzlib.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,661 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + z_size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (z_size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef WIDECHAR + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzread.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzread.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzread.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzread.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,678 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); +local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + unsigned get, max = ((unsigned)-1 >> 2) + 1; + + *have = 0; + do { + get = len - *have; + if (get > max) + get = max; + ret = read(state->fd, buf + *have, get); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +local z_size_t gz_read(state, buf, len) + gz_statep state; + voidp buf; + z_size_t len; +{ + z_size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = -1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfread(buf, size, nitems, file) + voidp buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + ret = (int)gz_read(state, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzwrite.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzwrite.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/gzwrite.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/gzwrite.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,689 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); +local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, writ; + unsigned have, put, max = ((unsigned)-1 >> 2) + 1; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + while (strm->avail_in) { + put = strm->avail_in > max ? max : strm->avail_in; + writ = write(state->fd, strm->next_in, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in -= (unsigned)writ; + strm->next_in += writ; + } + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + while (strm->next_out > state->x.next) { + put = strm->next_out - state->x.next > (int)max ? max : + (unsigned)(strm->next_out - state->x.next); + writ = write(state->fd, state->x.next, put); + if (writ < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + state->x.next += writ; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* Write len bytes from buf to file. Return the number of bytes written. If + the returned value is less than len, then there was an error. */ +local z_size_t gz_write(state, buf, len) + gz_statep state; + voidpc buf; + z_size_t len; +{ + z_size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const Bytef *)buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) + voidpc buf; + z_size_t size; + z_size_t nitems; + gzFile file; +{ + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (size && len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + z_size_t len; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(str); + ret = (int)gz_write(state, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int len; + unsigned left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(next, format, va); + for (len = 0; len < state->size; len++) + if (next[len] == 0) break; +# else + len = vsprintf(next, format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(next, state->size, format, va); + len = strlen(next); +# else + len = vsnprintf(next, state->size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + unsigned len, left; + char *next; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return Z_STREAM_ERROR; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->error; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->error; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(strm->next_in + strm->avail_in); + next[state->size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, + a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (next[len] == 0) + break; +# else + len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, + a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(next); +# else + len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len == 0 || len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memcpy(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return (int)len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/infback.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/infback.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/infback.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/infback.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,664 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = (uInt)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffast.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffast.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffast.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffast.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,347 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + *out++ = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = window; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + *out++ = *from++; + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + *out++ = *from++; + *out++ = *from++; + *out++ = *from++; + len -= 3; + } while (len > 2); + if (len) { + *out++ = *from++; + if (len > 1) + *out++ = *from++; + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffast.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffast.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffast.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffast.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,35 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffixed.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffixed.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inffixed.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inffixed.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inflate.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inflate.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inflate.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inflate.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,1585 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local int inflateStateCheck OF((z_streamp strm)); +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, + unsigned len)); + +local int inflateStateCheck(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, end, copy) +z_streamp strm; +const Bytef *end; +unsigned copy; +{ + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +const unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(strm, check) +z_streamp strm; +int check; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inflate.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inflate.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inflate.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inflate.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,149 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + z_streamp strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inftrees.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inftrees.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inftrees.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inftrees.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,328 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if (work[sym] >= match) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inftrees.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inftrees.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/inftrees.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/inftrees.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,98 @@ +(1) renamed adler32.c -> zadler32.c, zcrc32c -> zcrc32.c + +(2) zconf.h: + - added _LP64 to make uLong a 32-bit int on 64-bit platform + uLong -> 32-bit int + +-------------------------- +35,37d10 +< /* for _LP64 */ +< #include +< +421,424d393 +< +< #ifdef _LP64 +< typedef unsigned int uLong; /* 32 bits or more */ +< #else +426d394 +< #endif +-------------------------- + +(3) updated crc32.c/crc32(), crc32_z() + unsigned long -> uLong + +-------------------------- + +226,227c202,203 +< uLong ZEXPORT crc32_z(crc, buf, len) +< uLong crc; +--- +> unsigned long ZEXPORT crc32_z(crc, buf, len) +> unsigned long crc; +244c220 +< return (uLong)crc32_little(crc, buf, len); +--- +> return crc32_little(crc, buf, len); +246c222 +< return (uLong)crc32_big(crc, buf, len); +--- +> return crc32_big(crc, buf, len); +261,262c237,238 +< uLong ZEXPORT crc32(crc, buf, len) +< uLong crc; +--- +> unsigned long ZEXPORT crc32(crc, buf, len) +> unsigned long crc; + +-------------------------- + +(4) gzread.c + +-------------------------- +343c319 +< n = (unsigned)len; +--- +> n = len; +424c400 +< len = (unsigned)gz_read(state, buf, len); +--- +> len = gz_read(state, buf, len); +496c472 +< ret = (int)gz_read(state, buf, 1); +--- +> ret = gz_read(state, buf, 1); +-------------------------- + +(5) gzwrite.c + +-------------------------- +236c212 +< copy = (unsigned)len; +--- +> copy = len; +256c232 +< n = (unsigned)len; +--- +> n = len; +-------------------------- + +(6) deflate.c #8184306 + +*** 503,512 **** +--- 503,514 ---- + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + ++ s->high_water = 0; /* reset to its inital value 0 */ ++ + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = + #ifdef GZIP + +(7) deflate.c undo (6), replaced withe the official zlib repo fix see#305/#f969409 + + diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/README openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/README --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/README 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/README 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.11 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.11 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/trees.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/trees.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/trees.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/trees.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,1205 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2017 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local const static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local const static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local const static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef ZLIB_DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* !ZLIB_DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef ZLIB_DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !ZLIB_DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = (int)value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* ZLIB_DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (unsigned)(bits + xbits); + if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); + } + if (overflow == 0) return; + + Tracev((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ + bi_windup(s); /* align on byte boundary */ + put_short(s, (ush)stored_len); + put_short(s, (ush)~stored_len); + zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + s->pending += stored_len; +#ifdef ZLIB_DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; + s->bits_sent += 2*16; + s->bits_sent += stored_len<<3; +#endif +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef ZLIB_DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef ZLIB_DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef ZLIB_DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->sym_buf[s->sym_next++] = (uch)dist; + s->sym_buf[s->sym_next++] = (uch)(dist >> 8); + s->sym_buf[s->sym_next++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + return (s->sym_next == s->sym_end); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/trees.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/trees.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/trees.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/trees.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,152 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 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, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/uncompr.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/uncompr.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/uncompr.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/uncompr.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong *sourceLen; +{ + z_stream stream; + int err; + const uInt max = (uInt)-1; + uLong len, left; + Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } + else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = 0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (uLong)max ? max : (uInt)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (uLong)max ? max : (uInt)len; + len -= stream.avail_in; + } + err = inflate(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + inflateEnd(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return uncompress2(dest, destLen, source, &sourceLen); +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zadler32.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zadler32.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zadler32.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zadler32.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,210 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32_z(adler, buf, len) + uLong adler; + const Bytef *buf; + z_size_t len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + return adler32_z(adler, buf, len); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zconf.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zconf.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zconf.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zconf.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,566 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* for _LP64 */ +#include + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO + typedef unsigned long z_size_t; +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ + +#ifdef _LP64 +typedef unsigned int uLong; /* 32 bits or more */ +#else +typedef unsigned long uLong; /* 32 bits or more */ +#endif + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zcrc32.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zcrc32.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zcrc32.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zcrc32.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,466 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, z_size_t)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, z_size_t)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +uLong ZEXPORT crc32_z(crc, buf, len) + uLong crc; + const unsigned char FAR *buf; + z_size_t len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + z_crc_t endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return (uLong)crc32_little(crc, buf, len); + else + return (uLong)crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32(crc, buf, len) + uLong crc; + const unsigned char FAR *buf; + uInt len; +{ + return crc32_z(crc, buf, len); +} + +#ifdef BYFOUR + +/* + This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit + integer pointer type. This violates the strict aliasing rule, where a + compiler can assume, for optimization purposes, that two pointers to + fundamentally different types won't ever point to the same memory. This can + manifest as a problem only if one of the pointers is written to. This code + only reads from those pointers. So long as this code remains isolated in + this compilation unit, there won't be a problem. For this reason, this code + should not be copied and pasted into a compilation unit in which other code + writes to the buffer that is passed to these routines. + */ + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *buf4++; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + z_size_t len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zlib.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zlib.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zlib.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zlib.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,1936 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.11, January 15th, 2017 + + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.11" +#define ZLIB_VERNUM 0x12b0 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 11 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more ouput + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if any input has been consumed in a previous + deflate() call, then the input available so far is compressed with the old + level and strategy using deflate(strm, Z_BLOCK). There are three approaches + for the compression levels 0, 1..3, and 4..9 respectively. The new level + and strategy will take effect at the next call of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will not automatically decode concatenated gzip streams. + inflate() will return Z_STREAM_END at the end of the gzip stream. The state + would need to be reset to continue decoding a subsequent gzip stream. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen)); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Three times that size in buffer space is allocated. A larger buffer + size of, for example, 64K or 128K bytes will noticeably increase the speed + of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. Previously provided + data is flushed before the parameter change. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, + gzFile file)); +/* + Read up to nitems items of size size from file to buf, otherwise operating + as gzread() does. This duplicates the interface of stdio's fread(), with + size_t request and return types. If the library defines size_t, then + z_size_t is identical to size_t. If not, then z_size_t is an unsigned + integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevetheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, reseting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, + z_size_t nitems, gzFile file)); +/* + gzfwrite() writes nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, + z_size_t len)); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zutil.c openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zutil.c --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zutil.c 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zutil.c 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,350 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +z_const char * const z_errmsg[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +#include +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf; + ulg bsize = (ulg)items*size; + + (void)opaque; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + + (void)opaque; + + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + (void)opaque; + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + (void)opaque; + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + (void)opaque; + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + (void)opaque; + free(ptr); +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff -Nru openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zutil.h openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zutil.h --- openjdk-17-17.0.5+8/src/java.base/share/native/libzip/zlib/zutil.h 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/share/native/libzip/zlib/zutil.h 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,295 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* since "static" is used to mean two completely different things in C, we + define "local" for the non-static meaning of "static", for readability + (compile with -Dlocal if your debugger can't find static symbols) */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 2 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef _BEOS_ +# define OS_CODE 16 +#endif + +#ifdef __TOS_OS400__ +# define OS_CODE 18 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff -Nru openjdk-17-17.0.5+8/src/java.base/unix/native/libjava/TimeZone_md.c openjdk-17-17.0.6+10/src/java.base/unix/native/libjava/TimeZone_md.c --- openjdk-17-17.0.5+8/src/java.base/unix/native/libjava/TimeZone_md.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/unix/native/libjava/TimeZone_md.c 2023-01-10 13:21:55.000000000 +0000 @@ -379,12 +379,11 @@ size_t tz_len = 0; /* On AIX, the TZ environment variable may end with a comma - * followed by modifier fields. These are ignored here. */ - temp_tz = strchr(tz, ','); - tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz; - tz_buf = (char *)malloc(tz_len + 1); - memcpy(tz_buf, tz, tz_len); - tz_buf[tz_len] = 0; + * followed by modifier fields until early AIX6.1. + * This restriction has been removed from AIX7. */ + + tz_buf = strdup(tz); + tz_len = strlen(tz_buf); /* Open tzmappings file, with buffer overrun check */ if ((strlen(java_home_dir) + 15) > PATH_MAX) { @@ -525,58 +524,50 @@ /** * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00") */ - -#if defined(MACOSX) - char * getGMTOffsetID() { - time_t offset; - char sign, buf[32]; - struct tm local_tm; - time_t clock; + char buf[32]; + char offset[6]; + struct tm localtm; + time_t clock = time(NULL); + if (localtime_r(&clock, &localtm) == NULL) { + return strdup("GMT"); + } - clock = time(NULL); - if (localtime_r(&clock, &local_tm) == NULL) { +#if defined(MACOSX) + time_t gmt_offset; + gmt_offset = (time_t)localtm.tm_gmtoff; + if (gmt_offset == 0) { return strdup("GMT"); } - offset = (time_t)local_tm.tm_gmtoff; - if (offset == 0) { +#else + struct tm gmt; + if (gmtime_r(&clock, &gmt) == NULL) { return strdup("GMT"); } - if (offset > 0) { - sign = '+'; - } else { - offset = -offset; - sign = '-'; + + if(localtm.tm_hour == gmt.tm_hour && localtm.tm_min == gmt.tm_min) { + return strdup("GMT"); } - sprintf(buf, (const char *)"GMT%c%02d:%02d", - sign, (int)(offset/3600), (int)((offset%3600)/60)); - return strdup(buf); -} +#endif +#if defined(_AIX) + // strftime() with "%z" does not return ISO 8601 format by AIX default. + // XPG_SUS_ENV=ON environment variable is required. + // But Hotspot does not support XPG_SUS_ENV=ON. + // Ignore daylight saving settings to calculate current time difference + localtm.tm_isdst = 0; + int gmt_off = (int)(difftime(mktime(&localtm), mktime(&gmt)) / 60.0); + sprintf(buf, (const char *)"GMT%c%02.2d:%02.2d", + gmt_off < 0 ? '-' : '+' , abs(gmt_off / 60), gmt_off % 60); #else - -char * -getGMTOffsetID() -{ - time_t offset; - char sign, buf[32]; - offset = timezone; - - if (offset == 0) { + if (strftime(offset, 6, "%z", &localtm) != 5) { return strdup("GMT"); } - /* Note that the time offset direction is opposite. */ - if (offset > 0) { - sign = '-'; - } else { - offset = -offset; - sign = '+'; - } - sprintf(buf, (const char *)"GMT%c%02d:%02d", - sign, (int)(offset/3600), (int)((offset%3600)/60)); + sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2], + offset[3], offset[4]); +#endif return strdup(buf); } -#endif /* MACOSX */ diff -Nru openjdk-17-17.0.5+8/src/java.base/windows/native/libjava/java_props_md.c openjdk-17-17.0.6+10/src/java.base/windows/native/libjava/java_props_md.c --- openjdk-17-17.0.5+8/src/java.base/windows/native/libjava/java_props_md.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/windows/native/libjava/java_props_md.c 2023-01-10 13:21:55.000000000 +0000 @@ -558,7 +558,7 @@ /* Windows server 2022 build number is 20348 */ if (buildNumber > 20347) { sprops.os_name = "Windows Server 2022"; - } else if (buildNumber > 17676) { + } else if (buildNumber > 17762) { sprops.os_name = "Windows Server 2019"; } else { sprops.os_name = "Windows Server 2016"; diff -Nru openjdk-17-17.0.5+8/src/java.base/windows/native/libnet/NTLMAuthSequence.c openjdk-17-17.0.6+10/src/java.base/windows/native/libnet/NTLMAuthSequence.c --- openjdk-17-17.0.5+8/src/java.base/windows/native/libnet/NTLMAuthSequence.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.base/windows/native/libnet/NTLMAuthSequence.c 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -76,7 +76,7 @@ CredHandle *pCred; TimeStamp ltime; jboolean isCopy; - SECURITY_STATUS ss; + SECURITY_STATUS ss = SEC_E_INTERNAL_ERROR; if (user != 0) { pUser = JNU_GetStringPlatformChars(env, user, &isCopy); @@ -86,31 +86,19 @@ if (domain != 0) { pDomain = JNU_GetStringPlatformChars(env, domain, &isCopy); if (pDomain == NULL) { - if (pUser != NULL) - JNU_ReleaseStringPlatformChars(env, user, pUser); - return 0; // pending Exception + goto cleanup; } } if (password != 0) { pPassword = JNU_GetStringPlatformChars(env, password, &isCopy); if (pPassword == NULL) { - if(pUser != NULL) - JNU_ReleaseStringPlatformChars(env, user, pUser); - if(pDomain != NULL) - JNU_ReleaseStringPlatformChars(env, domain, pDomain); - return 0; // pending Exception + goto cleanup; } } pCred = (CredHandle *)malloc(sizeof (CredHandle)); if (pCred == NULL) { JNU_ThrowOutOfMemoryError(env, "native memory allocation failed"); - if (pUser != NULL) - JNU_ReleaseStringPlatformChars(env, user, pUser); - if (pPassword != NULL) - JNU_ReleaseStringPlatformChars(env, password, pPassword); - if (pDomain != NULL) - JNU_ReleaseStringPlatformChars(env, domain, pDomain); - return NULL; + goto cleanup; } if ( ((pUser != NULL) || (pPassword != NULL)) || (pDomain != NULL)) { @@ -145,6 +133,7 @@ ); /* Release resources held by JNU_GetStringPlatformChars */ +cleanup: if (pUser != NULL) JNU_ReleaseStringPlatformChars(env, user, pUser); if (pPassword != NULL) @@ -152,7 +141,7 @@ if (pDomain != NULL) JNU_ReleaseStringPlatformChars(env, domain, pDomain); - if (ss == 0) { + if (ss == SEC_E_OK) { return (jlong) pCred; } else { return 0; diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java openjdk-17-17.0.6+10/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java --- openjdk-17-17.0.5+8/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2021, 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 @@ -288,7 +288,9 @@ final AccessibleEditableText aet = ac.getAccessibleEditableText(); if (aet == null) return null; - return aet.getTextRange(location, location + length); + int currentLength = aet.getCharCount(); + return aet.getTextRange(Math.min(currentLength, location), + Math.min(currentLength, location + length)); } }, c); } diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ButtonAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ButtonAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ButtonAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ButtonAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -54,4 +54,15 @@ return [super accessibilityParent]; } +- (id _Nullable)accessibilityValue +{ + if ([self accessibilityRole] == NSAccessibilityButtonRole) { + // Only do it for buttons, radio buttons and checkbox buttons + // have a meaningful value to return + return NULL; + } else { + return [super accessibilityValue]; + } +} + @end diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CommonComponentAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -126,7 +126,7 @@ /* * Here we should keep all the mapping between the accessibility roles and implementing classes */ - rolesMap = [[NSMutableDictionary alloc] initWithCapacity:50]; + rolesMap = [[NSMutableDictionary alloc] initWithCapacity:51]; [rolesMap setObject:@"ButtonAccessibility" forKey:@"pushbutton"]; [rolesMap setObject:@"ImageAccessibility" forKey:@"icon"]; @@ -159,6 +159,7 @@ [rolesMap setObject:@"MenuBarAccessibility" forKey:@"menubar"]; [rolesMap setObject:@"MenuAccessibility" forKey:@"menu"]; [rolesMap setObject:@"MenuAccessibility" forKey:@"popupmenu"]; + [rolesMap setObject:@"MenuItemAccessibility" forKey:@"menuitem"]; [rolesMap setObject:@"ProgressIndicatorAccessibility" forKey:@"progressbar"]; /* @@ -614,8 +615,11 @@ [fActions setObject:action forKey:NSAccessibilityPickAction]; [fActionSelectors addObject:[sActionSelectors objectForKey:NSAccessibilityPickAction]]; } else { - [fActions setObject:action forKey:[sActions objectForKey:[action getDescription]]]; - [fActionSelectors addObject:[sActionSelectors objectForKey:[sActions objectForKey:[action getDescription]]]]; + NSString *nsActionName = [sActions objectForKey:[action getDescription]]; + if (nsActionName != nil) { + [fActions setObject:action forKey:nsActionName]; + [fActionSelectors addObject:[sActionSelectors objectForKey:nsActionName]]; + } } [action release]; } diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ImageAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ImageAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ImageAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ImageAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -49,4 +49,9 @@ return [super accessibilityParent]; } +- (id _Nullable)accessibilityValue +{ + return NULL; +} + @end diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -42,4 +42,9 @@ return YES; } +- (id _Nullable)accessibilityValue +{ + return NULL; +} + @end diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuItemAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuItemAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuItemAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/MenuItemAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -56,7 +56,7 @@ - (id _Nullable)accessibilityValue { - return [super accessibilityValue]; + return NULL; } @end diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m 2023-01-10 13:21:55.000000000 +0000 @@ -123,7 +123,14 @@ if ([accessibilityName isEqualToString:@""]) { accessibilityName = [cell accessibilityLabel]; } else { - accessibilityName = [accessibilityName stringByAppendingFormat:@", %@", [cell accessibilityLabel]]; + NSString *label = [cell accessibilityLabel]; + if (label == nil) { + id val = [cell accessibilityValue]; + if (val != nil) { + label = [NSString stringWithFormat:@"%@", val]; + } + } + accessibilityName = [accessibilityName stringByAppendingFormat:@", %@", label]; } } return accessibilityName; diff -Nru openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m --- openjdk-17-17.0.5+8/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m 2023-01-10 13:21:55.000000000 +0000 @@ -379,6 +379,9 @@ CTFontRef ctfont = (CTFontRef)nsFont; CFArrayRef tagsArray = CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions); + if (tagsArray == NULL) { + return NULL; + } CFIndex numTags = CFArrayGetCount(tagsArray); for (i=0; i a = new PrivilegedAction() { @Override public Boolean run() { - return Boolean.getBoolean("sun.imageio.plugins.bmp.disableLinkedProfiles"); + return Boolean. + getBoolean("sun.imageio.bmp.enableLinkedProfiles"); } }; - isLinkedProfileDisabled = AccessController.doPrivileged(a); - } - return !isLinkedProfileDisabled; - } - - private static Boolean isWindowsPlatform = null; - - /** - * Verifies whether the byte array contans a unc path. - * Non-UNC path examples: - * c:\path\to\file - simple notation - * \\?\c:\path\to\file - long notation - * - * UNC path examples: - * \\server\share - a UNC path in simple notation - * \\?\UNC\server\share - a UNC path in long notation - * \\.\some\device - a path to device. - */ - @SuppressWarnings("removal") - private static boolean isUncOrDevicePath(byte[] p) { - if (isWindowsPlatform == null) { - PrivilegedAction a = new PrivilegedAction() { - @Override - public Boolean run() { - String osname = System.getProperty("os.name"); - return (osname != null && - osname.toLowerCase().startsWith("win")); - } - }; - isWindowsPlatform = AccessController.doPrivileged(a); - } - - if (!isWindowsPlatform) { - /* no need for the check on platforms except windows */ - return false; - } - - /* normalize prefix of the path */ - if (p[0] == '/') p[0] = '\\'; - if (p[1] == '/') p[1] = '\\'; - if (p[3] == '/') p[3] = '\\'; - - - if ((p[0] == '\\') && (p[1] == '\\')) { - if ((p[2] == '?') && (p[3] == '\\')) { - // long path: whether unc or local - return ((p[4] == 'U' || p[4] == 'u') && - (p[5] == 'N' || p[5] == 'n') && - (p[6] == 'C' || p[6] == 'c')); - } else { - // device path or short unc notation - return true; - } - } else { - return false; + isLinkedProfileAllowed = AccessController.doPrivileged(a); } + return isLinkedProfileAllowed; } } - diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java openjdk-17-17.0.6+10/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java --- openjdk-17-17.0.5+8/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, 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 @@ -48,6 +48,13 @@ */ public final class JARSoundbankReader extends SoundbankReader { + /* + * Name of the system property that enables the Jar soundbank loading + * true if jar sound bank is allowed to be loaded + * default is false + */ + private final static String JAR_SOUNDBANK_ENABLED = "jdk.sound.jarsoundbank"; + private static boolean isZIP(URL url) { boolean ok = false; try { @@ -73,8 +80,10 @@ @SuppressWarnings("deprecation") public Soundbank getSoundbank(URL url) throws InvalidMidiDataException, IOException { - if (!isZIP(url)) + Objects.requireNonNull(url); + if (!Boolean.getBoolean(JAR_SOUNDBANK_ENABLED) || !isZIP(url)) return null; + ArrayList soundbanks = new ArrayList<>(); URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url}); InputStream stream = ucl.getResourceAsStream( @@ -124,6 +133,7 @@ @Override public Soundbank getSoundbank(File file) throws InvalidMidiDataException, IOException { + Objects.requireNonNull(file); return getSoundbank(file.toURI().toURL()); } } diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/classes/java/awt/SystemTray.java openjdk-17-17.0.6+10/src/java.desktop/share/classes/java/awt/SystemTray.java --- openjdk-17-17.0.5+8/src/java.desktop/share/classes/java/awt/SystemTray.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/share/classes/java/awt/SystemTray.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, 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 @@ -131,15 +131,7 @@ private static final TrayIcon[] EMPTY_TRAY_ARRAY = new TrayIcon[0]; static { - AWTAccessor.setSystemTrayAccessor( - new AWTAccessor.SystemTrayAccessor() { - public void firePropertyChange(SystemTray tray, - String propertyName, - Object oldValue, - Object newValue) { - tray.firePropertyChange(propertyName, oldValue, newValue); - } - }); + AWTAccessor.setSystemTrayAccessor(SystemTray::firePropertyChange); } /** @@ -257,15 +249,16 @@ if (trayIcon == null) { throw new NullPointerException("adding null TrayIcon"); } - TrayIcon[] oldArray = null, newArray = null; - Vector icons = null; + TrayIcon[] oldArray; + TrayIcon[] newArray; + Vector icons; synchronized (this) { oldArray = systemTray.getTrayIcons(); @SuppressWarnings("unchecked") Vector tmp = (Vector)AppContext.getAppContext().get(TrayIcon.class); icons = tmp; if (icons == null) { - icons = new Vector(3); + icons = new Vector<>(3); AppContext.getAppContext().put(TrayIcon.class, icons); } else if (icons.contains(trayIcon)) { @@ -305,7 +298,8 @@ if (trayIcon == null) { return; } - TrayIcon[] oldArray = null, newArray = null; + TrayIcon[] oldArray; + TrayIcon[] newArray; synchronized (this) { oldArray = systemTray.getTrayIcons(); @SuppressWarnings("unchecked") @@ -343,7 +337,7 @@ @SuppressWarnings("unchecked") Vector icons = (Vector)AppContext.getAppContext().get(TrayIcon.class); if (icons != null) { - return icons.toArray(new TrayIcon[icons.size()]); + return icons.toArray(EMPTY_TRAY_ARRAY); } return EMPTY_TRAY_ARRAY; } @@ -475,7 +469,7 @@ private void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - if (oldValue != null && newValue != null && oldValue.equals(newValue)) { + if (oldValue != null && oldValue.equals(newValue)) { return; } getCurrentChangeSupport().firePropertyChange(propertyName, oldValue, newValue); diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java openjdk-17-17.0.6+10/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java --- openjdk-17-17.0.5+8/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java 2023-01-10 13:21:55.000000000 +0000 @@ -91,13 +91,15 @@ String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); try { ReflectUtil.checkPackageAccess(classname); - Class c = Class.forName(classname, true,Thread.currentThread(). + Class c = Class.forName(classname, false,Thread.currentThread(). getContextClassLoader()); - Object o = c.newInstance(); - if (o instanceof Component) { - Component comp = (Component) o; - setParameters(comp, attr); - return comp; + if (Component.class.isAssignableFrom(c)) { + Object o = c.newInstance(); + if (o instanceof Component) { + Component comp = (Component) o; + setParameters(comp, attr); + return comp; + } } } catch (Throwable e) { // couldn't create a component... fall through to the diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/legal/freetype.md openjdk-17-17.0.6+10/src/java.desktop/share/legal/freetype.md --- openjdk-17-17.0.5+8/src/java.desktop/share/legal/freetype.md 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/share/legal/freetype.md 2023-01-10 13:21:55.000000000 +0000 @@ -20,6 +20,27 @@ ### FreeType License ``` + +Copyright (C) 1996-2022 by David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2007-2022 by Dereg Clegg and Michael Toftdal. +Copyright (C) 1996-2022 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2004-2022 by Masatake YAMATO and Redhat K.K. +Copyright (C) 2007-2022 by Derek Clegg and Michael Toftdal. +Copyright (C) 2007-2022 by David Turner. +Copyright (C) 2022 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. +Copyright (C) 2007-2022 by Rahul Bhalerao , . +Copyright (C) 2008-2022 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. +Copyright (C) 2019-2022 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright (C) 2009-2022 by Oran Agra and Mickey Gabel. +Copyright (C) 2004-2022 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. +Copyright (C) 2004-2022 by Masatake YAMATO, Red Hat K.K., +Copyright (C) 2003-2022 by Masatake YAMATO, Redhat K.K., +Copyright (C) 2013-2022 by Google, Inc. +Copyright (C) 2018-2022 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. +Copyright (C) 2005-2022 by David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright 2013 by Google, Inc. + + The FreeType Project LICENSE ---------------------------- @@ -533,46 +554,34 @@ library. If this is what you want to do, use the GNU Library General Public License instead of this License. -######################################################################### - ---- fthash.c and fthash.h are covered by the following notices --- - -/* - * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001-2015 - * Francesco Zappa Nardelli - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - /************************************************************************** - * - * This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 - * - * taken from Mark Leisher's xmbdfed package - * - */ - -######################################################################### +``` +### Additional Freetype Attributions +``` ---- FreeType 2 PSaux module is covered by the following notices --- +--------------------------------- +The below license applies to the following files: +libfreetype/src/psaux/psarrst.c +libfreetype/src/psaux/psarrst.h +libfreetype/src/psaux/psblues.c +libfreetype/src/psaux/psblues.h +libfreetype/src/psaux/pserror.c +libfreetype/src/psaux/pserror.h +libfreetype/src/psaux/psfixed.h +libfreetype/src/psaux/psfont.c +libfreetype/src/psaux/psfont.h +libfreetype/src/psaux/psft.c +libfreetype/src/psaux/psft.h +libfreetype/src/psaux/psglue.h +libfreetype/src/psaux/pshints.c +libfreetype/src/psaux/pshints.h +libfreetype/src/psaux/psintrp.c +libfreetype/src/psaux/psintrp.h +libfreetype/src/psaux/psread.c +libfreetype/src/psaux/psread.h +libfreetype/src/psaux/psstack.c +libfreetype/src/psaux/psstack.h +libfreetype/src/psaux/pstypes.h Copyright 2006-2014 Adobe Systems Incorporated. @@ -603,7 +612,39 @@ FreeType Project License as well as those provided in this section, and you accept them fully. -######################################################################### ``` +### MIT License +``` + +--------------------------------- +The below license applies to the following files: +libfreetype/include/freetype/internal/fthash.h +libfreetype/src/base/fthash.c + +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2015 + + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +``` diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/legal/harfbuzz.md openjdk-17-17.0.6+10/src/java.desktop/share/legal/harfbuzz.md --- openjdk-17-17.0.5+8/src/java.desktop/share/legal/harfbuzz.md 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/java.desktop/share/legal/harfbuzz.md 2023-01-10 13:21:55.000000000 +0000 @@ -2,7 +2,7 @@ ### Harfbuzz License -https://github.com/harfbuzz/harfbuzz/blob/master/COPYING +https://github.com/harfbuzz/harfbuzz/blob/4.4.1/COPYING

     
    @@ -10,19 +10,23 @@
     For parts of HarfBuzz that are licensed under different licenses see individual
     files names COPYING in subdirectories where applicable.
     
    -Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020  Google, Inc.
    -Copyright © 2018,2019,2020  Ebrahim Byagowi
    -Copyright © 2019,2020  Facebook, Inc. 
    -Copyright © 2012  Mozilla Foundation
    +Copyright © 2010-2022  Google, Inc.
    +Copyright © 2018-2020  Ebrahim Byagowi
    +Copyright © 2019-2020  Facebook, Inc.
    +Copyright © 2012-2015  Mozilla Foundation.
     Copyright © 2011  Codethink Limited
    -Copyright © 2008,2010  Nokia Corporation and/or its subsidiary(-ies)
    +Copyright © 2008-2010  Nokia Corporation and/or its subsidiary(-ies)
     Copyright © 2009  Keith Stribley
     Copyright © 2009  Martin Hosken and SIL International
     Copyright © 2007  Chris Wilson
    -Copyright © 2006  Behdad Esfahbod
    +Copyright © 2005-2022 Behdad Esfahbod
     Copyright © 2005  David Turner
    -Copyright © 2004,2007,2008,2009,2010  Red Hat, Inc.
    +Copyright © 2004-2013  Red Hat, Inc.
     Copyright © 1998-2004  David Turner and Werner Lemberg
    +Copyright © 2016  Elie Roux 
    +Copyright © 2018-2019 Adobe Inc.
    +Copyright © 2018  Khaled Hosny
    +Copyright © 2016  Igalia S.L.
     
     For full copyright notices consult the individual files in the package.
     
    @@ -49,6 +53,10 @@
     exception is licensed with a slightly different MIT variant:
     The contents of this directory are licensed under the following terms:
     
    +---------------------------------
    +The below license applies to the following files:
    +libharfbuzz/hb-ucd.cc
    +
     Copyright (C) 2012 Grigori Goronzy 
     
     Permission to use, copy, modify, and/or distribute this software for any
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/common/awt/utility/sizecalc.h openjdk-17-17.0.6+10/src/java.desktop/share/native/common/awt/utility/sizecalc.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/common/awt/utility/sizecalc.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/common/awt/utility/sizecalc.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,119 @@
    +/*
    + * Copyright (c) 2013, 2022, 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +#ifndef SIZECALC_H
    +#define SIZECALC_H
    +
    +/*
    + * A machinery for safe calculation of sizes used when allocating memory.
    + *
    + * All size checks are performed against the SIZE_MAX (the maximum value for
    + * size_t). All numerical arguments as well as the result of calculation must
    + * be non-negative integers less than or equal to SIZE_MAX, otherwise the
    + * calculated size is considered unsafe.
    + *
    + * If the SIZECALC_ALLOC_THROWING_BAD_ALLOC macro is defined, then _ALLOC_
    + * helper macros throw the std::bad_alloc instead of returning NULL.
    + */
    +
    +#include  /* SIZE_MAX for C99+ */
    +/* http://stackoverflow.com/questions/3472311/what-is-a-portable-method-to-find-the-maximum-value-of-size-t */
    +#ifndef SIZE_MAX
    +#define SIZE_MAX ((size_t)-1)
    +#endif
    +
    +#define IS_SAFE_SIZE_T(x) ((x) >= 0 && (unsigned long long)(x) <= SIZE_MAX)
    +
    +#define IS_SAFE_SIZE_MUL(m, n) \
    +    (IS_SAFE_SIZE_T(m) && IS_SAFE_SIZE_T(n) && \
    +     ((m) == 0 || (n) == 0 || (size_t)(n) <= (SIZE_MAX / (size_t)(m))))
    +
    +#define IS_SAFE_SIZE_ADD(a, b) \
    +    (IS_SAFE_SIZE_T(a) && IS_SAFE_SIZE_T(b) && (size_t)(b) <= (SIZE_MAX - (size_t)(a)))
    +
    +
    +
    +/* Helper macros */
    +
    +#ifdef SIZECALC_ALLOC_THROWING_BAD_ALLOC
    +#define FAILURE_RESULT throw std::bad_alloc()
    +#else
    +#define FAILURE_RESULT NULL
    +#endif
    +
    +/*
    + * A helper macro to safely allocate an array of size m*n.
    + * Example usage:
    + *    int* p = (int*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(int), n);
    + *    if (!p) throw OutOfMemory;
    + *    // Use the allocated array...
    + */
    +#define SAFE_SIZE_ARRAY_ALLOC(func, m, n) \
    +    (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((size_t)(m) * (size_t)(n))) : FAILURE_RESULT)
    +
    +#define SAFE_SIZE_ARRAY_REALLOC(func, p, m, n) \
    +    (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((p), (size_t)(m) * (size_t)(n))) : FAILURE_RESULT)
    +
    +/*
    + * A helper macro to safely allocate an array of type 'type' with 'n' items
    + * using the C++ new[] operator.
    + * Example usage:
    + *    MyClass* p = SAFE_SIZE_NEW_ARRAY(MyClass, n);
    + *    // Use the pointer.
    + * This macro throws the std::bad_alloc C++ exception to indicate
    + * a failure.
    + * NOTE: if 'n' is calculated, the calling code is responsible for using the
    + * IS_SAFE_... macros to check if the calculations are safe.
    + */
    +#define SAFE_SIZE_NEW_ARRAY(type, n) \
    +    (IS_SAFE_SIZE_MUL(sizeof(type), (n)) ? (new type[(size_t)(n)]) : throw std::bad_alloc())
    +
    +#define SAFE_SIZE_NEW_ARRAY2(type, n, m) \
    +    (IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_MUL(sizeof(type), (size_t)(n) * (size_t)(m)) ? \
    +     (new type[(size_t)(n) * (size_t)(m)]) : throw std::bad_alloc())
    +
    +/*
    + * Checks if a data structure of size (a + m*n) can be safely allocated
    + * w/o producing an integer overflow when calculating its size.
    + */
    +#define IS_SAFE_STRUCT_SIZE(a, m, n) \
    +    ( \
    +      IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_ADD((size_t)(m) * (size_t)(n), (a)) \
    +    )
    +
    +/*
    + * A helper macro for implementing safe memory allocation for a data structure
    + * of size (a + m * n).
    + * Example usage:
    + *    void * p = SAFE_SIZE_ALLOC(malloc, header, num, itemSize);
    + *    if (!p) throw OutOfMemory;
    + *    // Use the allocated memory...
    + */
    +#define SAFE_SIZE_STRUCT_ALLOC(func, a, m, n) \
    +    (IS_SAFE_STRUCT_SIZE((a), (m), (n)) ? ((func)((size_t)(a) + (size_t)(m) * (size_t)(n))) : FAILURE_RESULT)
    +
    +
    +#endif /* SIZECALC_H */
    +
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/include/sizecalc.h openjdk-17-17.0.6+10/src/java.desktop/share/native/include/sizecalc.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/include/sizecalc.h	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/include/sizecalc.h	1970-01-01 00:00:00.000000000 +0000
    @@ -1,123 +0,0 @@
    -/*
    - * Copyright (c) 2013, 2022, 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.  Oracle designates this
    - * particular file as subject to the "Classpath" exception as provided
    - * by Oracle in the LICENSE file that accompanied this code.
    - *
    - * 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.
    - */
    -
    -#ifndef SIZECALC_H
    -#define SIZECALC_H
    -
    -/*
    - * A machinery for safe calculation of sizes used when allocating memory.
    - *
    - * All size checks are performed against the SIZE_MAX (the maximum value for
    - * size_t). All numerical arguments as well as the result of calculation must
    - * be non-negative integers less than or equal to SIZE_MAX, otherwise the
    - * calculated size is considered unsafe.
    - *
    - * If the SIZECALC_ALLOC_THROWING_BAD_ALLOC macro is defined, then _ALLOC_
    - * helper macros throw the std::bad_alloc instead of returning NULL.
    - */
    -
    -#include  /* SIZE_MAX for C99+ */
    -/* http://stackoverflow.com/questions/3472311/what-is-a-portable-method-to-find-the-maximum-value-of-size-t */
    -#ifndef SIZE_MAX
    -#define SIZE_MAX ((size_t)-1)
    -#endif
    -
    -#define IS_SAFE_SIZE_T(x) ((x) >= 0 && (unsigned long long)(x) <= SIZE_MAX)
    -
    -#define IS_MUL_OVERFLOW(m, n) \
    -        ((m) != 0 && (n) != 0 && (((size_t)((m)*(n))) != (((size_t)(m)) * ((size_t)(n)))))
    -
    -#define IS_SAFE_SIZE_MUL(m, n) \
    -    (IS_SAFE_SIZE_T(m) && IS_SAFE_SIZE_T(n) && \
    -     ((m) == 0 || (n) == 0 || (size_t)(n) <= (SIZE_MAX / (size_t)(m))) && \
    -     !IS_MUL_OVERFLOW(m, n))
    -
    -#define IS_SAFE_SIZE_ADD(a, b) \
    -    (IS_SAFE_SIZE_T(a) && IS_SAFE_SIZE_T(b) && (size_t)(b) <= (SIZE_MAX - (size_t)(a)))
    -
    -
    -
    -/* Helper macros */
    -
    -#ifdef SIZECALC_ALLOC_THROWING_BAD_ALLOC
    -#define FAILURE_RESULT throw std::bad_alloc()
    -#else
    -#define FAILURE_RESULT NULL
    -#endif
    -
    -/*
    - * A helper macro to safely allocate an array of size m*n.
    - * Example usage:
    - *    int* p = (int*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(int), n);
    - *    if (!p) throw OutOfMemory;
    - *    // Use the allocated array...
    - */
    -#define SAFE_SIZE_ARRAY_ALLOC(func, m, n) \
    -    (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((m) * (n))) : FAILURE_RESULT)
    -
    -#define SAFE_SIZE_ARRAY_REALLOC(func, p, m, n) \
    -    (IS_SAFE_SIZE_MUL((m), (n)) ? ((func)((p), (m) * (n))) : FAILURE_RESULT)
    -
    -/*
    - * A helper macro to safely allocate an array of type 'type' with 'n' items
    - * using the C++ new[] operator.
    - * Example usage:
    - *    MyClass* p = SAFE_SIZE_NEW_ARRAY(MyClass, n);
    - *    // Use the pointer.
    - * This macro throws the std::bad_alloc C++ exception to indicate
    - * a failure.
    - * NOTE: if 'n' is calculated, the calling code is responsible for using the
    - * IS_SAFE_... macros to check if the calculations are safe.
    - */
    -#define SAFE_SIZE_NEW_ARRAY(type, n) \
    -    (IS_SAFE_SIZE_MUL(sizeof(type), (n)) ? (new type[(n)]) : throw std::bad_alloc())
    -
    -#define SAFE_SIZE_NEW_ARRAY2(type, n, m) \
    -    (IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_MUL(sizeof(type), (n) * (m)) ? \
    -     (new type[(n) * (m)]) : throw std::bad_alloc())
    -
    -/*
    - * Checks if a data structure of size (a + m*n) can be safely allocated
    - * w/o producing an integer overflow when calculating its size.
    - */
    -#define IS_SAFE_STRUCT_SIZE(a, m, n) \
    -    ( \
    -      IS_SAFE_SIZE_MUL((m), (n)) && IS_SAFE_SIZE_ADD((m) * (n), (a)) \
    -    )
    -
    -/*
    - * A helper macro for implementing safe memory allocation for a data structure
    - * of size (a + m * n).
    - * Example usage:
    - *    void * p = SAFE_SIZE_ALLOC(malloc, header, num, itemSize);
    - *    if (!p) throw OutOfMemory;
    - *    // Use the allocated memory...
    - */
    -#define SAFE_SIZE_STRUCT_ALLOC(func, a, m, n) \
    -    (IS_SAFE_STRUCT_SIZE((a), (m), (n)) ? ((func)((a) + (m) * (n))) : FAILURE_RESULT)
    -
    -
    -#endif /* SIZECALC_H */
    -
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcapimin.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcapimin.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcapimin.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcapimin.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,284 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcapimin.c
    + *
    + * Copyright (C) 1994-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains application interface code for the compression half
    + * of the JPEG library.  These are the "minimum" API routines that may be
    + * needed in either the normal full-compression case or the transcoding-only
    + * case.
    + *
    + * Most of the routines intended to be called directly by an application
    + * are in this file or in jcapistd.c.  But also see jcparam.c for
    + * parameter-setup helper routines, jcomapi.c for routines shared by
    + * compression and decompression, and jctrans.c for the transcoding case.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Initialization of a JPEG compression object.
    + * The error manager must already be set up (in case memory manager fails).
    + */
    +
    +GLOBAL(void)
    +jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
    +{
    +  int i;
    +
    +  /* Guard against version mismatches between library and caller. */
    +  cinfo->mem = NULL;            /* so jpeg_destroy knows mem mgr not called */
    +  if (version != JPEG_LIB_VERSION)
    +    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
    +  if (structsize != SIZEOF(struct jpeg_compress_struct))
    +    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
    +             (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
    +
    +  /* For debugging purposes, we zero the whole master structure.
    +   * But the application has already set the err pointer, and may have set
    +   * client_data, so we have to save and restore those fields.
    +   * Note: if application hasn't set client_data, tools like Purify may
    +   * complain here.
    +   */
    +  {
    +    struct jpeg_error_mgr * err = cinfo->err;
    +    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
    +    MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
    +    cinfo->err = err;
    +    cinfo->client_data = client_data;
    +  }
    +  cinfo->is_decompressor = FALSE;
    +
    +  /* Initialize a memory manager instance for this object */
    +  jinit_memory_mgr((j_common_ptr) cinfo);
    +
    +  /* Zero out pointers to permanent structures. */
    +  cinfo->progress = NULL;
    +  cinfo->dest = NULL;
    +
    +  cinfo->comp_info = NULL;
    +
    +  for (i = 0; i < NUM_QUANT_TBLS; i++)
    +    cinfo->quant_tbl_ptrs[i] = NULL;
    +
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    cinfo->dc_huff_tbl_ptrs[i] = NULL;
    +    cinfo->ac_huff_tbl_ptrs[i] = NULL;
    +  }
    +
    +  cinfo->script_space = NULL;
    +
    +  cinfo->input_gamma = 1.0;     /* in case application forgets */
    +
    +  /* OK, I'm ready */
    +  cinfo->global_state = CSTATE_START;
    +}
    +
    +
    +/*
    + * Destruction of a JPEG compression object
    + */
    +
    +GLOBAL(void)
    +jpeg_destroy_compress (j_compress_ptr cinfo)
    +{
    +  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
    +}
    +
    +
    +/*
    + * Abort processing of a JPEG compression operation,
    + * but don't destroy the object itself.
    + */
    +
    +GLOBAL(void)
    +jpeg_abort_compress (j_compress_ptr cinfo)
    +{
    +  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
    +}
    +
    +
    +/*
    + * Forcibly suppress or un-suppress all quantization and Huffman tables.
    + * Marks all currently defined tables as already written (if suppress)
    + * or not written (if !suppress).  This will control whether they get emitted
    + * by a subsequent jpeg_start_compress call.
    + *
    + * This routine is exported for use by applications that want to produce
    + * abbreviated JPEG datastreams.  It logically belongs in jcparam.c, but
    + * since it is called by jpeg_start_compress, we put it here --- otherwise
    + * jcparam.o would be linked whether the application used it or not.
    + */
    +
    +GLOBAL(void)
    +jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
    +{
    +  int i;
    +  JQUANT_TBL * qtbl;
    +  JHUFF_TBL * htbl;
    +
    +  for (i = 0; i < NUM_QUANT_TBLS; i++) {
    +    if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
    +      qtbl->sent_table = suppress;
    +  }
    +
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
    +      htbl->sent_table = suppress;
    +    if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
    +      htbl->sent_table = suppress;
    +  }
    +}
    +
    +
    +/*
    + * Finish JPEG compression.
    + *
    + * If a multipass operating mode was selected, this may do a great deal of
    + * work including most of the actual output.
    + */
    +
    +GLOBAL(void)
    +jpeg_finish_compress (j_compress_ptr cinfo)
    +{
    +  JDIMENSION iMCU_row;
    +
    +  if (cinfo->global_state == CSTATE_SCANNING ||
    +      cinfo->global_state == CSTATE_RAW_OK) {
    +    /* Terminate first pass */
    +    if (cinfo->next_scanline < cinfo->image_height)
    +      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
    +    (*cinfo->master->finish_pass) (cinfo);
    +  } else if (cinfo->global_state != CSTATE_WRCOEFS)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  /* Perform any remaining passes */
    +  while (! cinfo->master->is_last_pass) {
    +    (*cinfo->master->prepare_for_pass) (cinfo);
    +    for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
    +      if (cinfo->progress != NULL) {
    +        cinfo->progress->pass_counter = (long) iMCU_row;
    +        cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
    +        (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +      }
    +      /* We bypass the main controller and invoke coef controller directly;
    +       * all work is being done from the coefficient buffer.
    +       */
    +      if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
    +        ERREXIT(cinfo, JERR_CANT_SUSPEND);
    +    }
    +    (*cinfo->master->finish_pass) (cinfo);
    +  }
    +  /* Write EOI, do final cleanup */
    +  (*cinfo->marker->write_file_trailer) (cinfo);
    +  (*cinfo->dest->term_destination) (cinfo);
    +  /* We can use jpeg_abort to release memory and reset global_state */
    +  jpeg_abort((j_common_ptr) cinfo);
    +}
    +
    +
    +/*
    + * Write a special marker.
    + * This is only recommended for writing COM or APPn markers.
    + * Must be called after jpeg_start_compress() and before
    + * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
    + */
    +
    +GLOBAL(void)
    +jpeg_write_marker (j_compress_ptr cinfo, int marker,
    +                   const JOCTET *dataptr, unsigned int datalen)
    +{
    +  JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
    +
    +  if (cinfo->next_scanline != 0 ||
    +      (cinfo->global_state != CSTATE_SCANNING &&
    +       cinfo->global_state != CSTATE_RAW_OK &&
    +       cinfo->global_state != CSTATE_WRCOEFS))
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
    +  write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
    +  while (datalen--) {
    +    (*write_marker_byte) (cinfo, *dataptr);
    +    dataptr++;
    +  }
    +}
    +
    +/* Same, but piecemeal. */
    +
    +GLOBAL(void)
    +jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
    +{
    +  if (cinfo->next_scanline != 0 ||
    +      (cinfo->global_state != CSTATE_SCANNING &&
    +       cinfo->global_state != CSTATE_RAW_OK &&
    +       cinfo->global_state != CSTATE_WRCOEFS))
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
    +}
    +
    +GLOBAL(void)
    +jpeg_write_m_byte (j_compress_ptr cinfo, int val)
    +{
    +  (*cinfo->marker->write_marker_byte) (cinfo, val);
    +}
    +
    +
    +/*
    + * Alternate compression function: just write an abbreviated table file.
    + * Before calling this, all parameters and a data destination must be set up.
    + *
    + * To produce a pair of files containing abbreviated tables and abbreviated
    + * image data, one would proceed as follows:
    + *
    + *              initialize JPEG object
    + *              set JPEG parameters
    + *              set destination to table file
    + *              jpeg_write_tables(cinfo);
    + *              set destination to image file
    + *              jpeg_start_compress(cinfo, FALSE);
    + *              write data...
    + *              jpeg_finish_compress(cinfo);
    + *
    + * jpeg_write_tables has the side effect of marking all tables written
    + * (same as jpeg_suppress_tables(..., TRUE)).  Thus a subsequent start_compress
    + * will not re-emit the tables unless it is passed write_all_tables=TRUE.
    + */
    +
    +GLOBAL(void)
    +jpeg_write_tables (j_compress_ptr cinfo)
    +{
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  /* (Re)initialize error mgr and destination modules */
    +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
    +  (*cinfo->dest->init_destination) (cinfo);
    +  /* Initialize the marker writer ... bit of a crock to do it here. */
    +  jinit_marker_writer(cinfo);
    +  /* Write them tables! */
    +  (*cinfo->marker->write_tables_only) (cinfo);
    +  /* And clean up. */
    +  (*cinfo->dest->term_destination) (cinfo);
    +  /*
    +   * In library releases up through v6a, we called jpeg_abort() here to free
    +   * any working memory allocated by the destination manager and marker
    +   * writer.  Some applications had a problem with that: they allocated space
    +   * of their own from the library memory manager, and didn't want it to go
    +   * away during write_tables.  So now we do nothing.  This will cause a
    +   * memory leak if an app calls write_tables repeatedly without doing a full
    +   * compression cycle or otherwise resetting the JPEG object.  However, that
    +   * seems less bad than unexpectedly freeing memory in the normal case.
    +   * An app that prefers the old behavior can call jpeg_abort for itself after
    +   * each call to jpeg_write_tables().
    +   */
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcapistd.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcapistd.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcapistd.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcapistd.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,165 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcapistd.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains application interface code for the compression half
    + * of the JPEG library.  These are the "standard" API routines that are
    + * used in the normal full-compression case.  They are not used by a
    + * transcoding-only application.  Note that if an application links in
    + * jpeg_start_compress, it will end up linking in the entire compressor.
    + * We thus must separate this file from jcapimin.c to avoid linking the
    + * whole compression library into a transcoder.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Compression initialization.
    + * Before calling this, all parameters and a data destination must be set up.
    + *
    + * We require a write_all_tables parameter as a failsafe check when writing
    + * multiple datastreams from the same compression object.  Since prior runs
    + * will have left all the tables marked sent_table=TRUE, a subsequent run
    + * would emit an abbreviated stream (no tables) by default.  This may be what
    + * is wanted, but for safety's sake it should not be the default behavior:
    + * programmers should have to make a deliberate choice to emit abbreviated
    + * images.  Therefore the documentation and examples should encourage people
    + * to pass write_all_tables=TRUE; then it will take active thought to do the
    + * wrong thing.
    + */
    +
    +GLOBAL(void)
    +jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
    +{
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  if (write_all_tables)
    +    jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
    +
    +  /* (Re)initialize error mgr and destination modules */
    +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
    +  (*cinfo->dest->init_destination) (cinfo);
    +  /* Perform master selection of active modules */
    +  jinit_compress_master(cinfo);
    +  /* Set up for the first pass */
    +  (*cinfo->master->prepare_for_pass) (cinfo);
    +  /* Ready for application to drive first pass through jpeg_write_scanlines
    +   * or jpeg_write_raw_data.
    +   */
    +  cinfo->next_scanline = 0;
    +  cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
    +}
    +
    +
    +/*
    + * Write some scanlines of data to the JPEG compressor.
    + *
    + * The return value will be the number of lines actually written.
    + * This should be less than the supplied num_lines only in case that
    + * the data destination module has requested suspension of the compressor,
    + * or if more than image_height scanlines are passed in.
    + *
    + * Note: we warn about excess calls to jpeg_write_scanlines() since
    + * this likely signals an application programmer error.  However,
    + * excess scanlines passed in the last valid call are *silently* ignored,
    + * so that the application need not adjust num_lines for end-of-image
    + * when using a multiple-scanline buffer.
    + */
    +
    +GLOBAL(JDIMENSION)
    +jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
    +                      JDIMENSION num_lines)
    +{
    +  JDIMENSION row_ctr, rows_left;
    +
    +  if (cinfo->global_state != CSTATE_SCANNING)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  if (cinfo->next_scanline >= cinfo->image_height)
    +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
    +
    +  /* Call progress monitor hook if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
    +    cinfo->progress->pass_limit = (long) cinfo->image_height;
    +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +  }
    +
    +  /* Give master control module another chance if this is first call to
    +   * jpeg_write_scanlines.  This lets output of the frame/scan headers be
    +   * delayed so that application can write COM, etc, markers between
    +   * jpeg_start_compress and jpeg_write_scanlines.
    +   */
    +  if (cinfo->master->call_pass_startup)
    +    (*cinfo->master->pass_startup) (cinfo);
    +
    +  /* Ignore any extra scanlines at bottom of image. */
    +  rows_left = cinfo->image_height - cinfo->next_scanline;
    +  if (num_lines > rows_left)
    +    num_lines = rows_left;
    +
    +  row_ctr = 0;
    +  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
    +  cinfo->next_scanline += row_ctr;
    +  return row_ctr;
    +}
    +
    +
    +/*
    + * Alternate entry point to write raw data.
    + * Processes exactly one iMCU row per call, unless suspended.
    + */
    +
    +GLOBAL(JDIMENSION)
    +jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
    +                     JDIMENSION num_lines)
    +{
    +  JDIMENSION lines_per_iMCU_row;
    +
    +  if (cinfo->global_state != CSTATE_RAW_OK)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  if (cinfo->next_scanline >= cinfo->image_height) {
    +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
    +    return 0;
    +  }
    +
    +  /* Call progress monitor hook if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->pass_counter = (long) cinfo->next_scanline;
    +    cinfo->progress->pass_limit = (long) cinfo->image_height;
    +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +  }
    +
    +  /* Give master control module another chance if this is first call to
    +   * jpeg_write_raw_data.  This lets output of the frame/scan headers be
    +   * delayed so that application can write COM, etc, markers between
    +   * jpeg_start_compress and jpeg_write_raw_data.
    +   */
    +  if (cinfo->master->call_pass_startup)
    +    (*cinfo->master->pass_startup) (cinfo);
    +
    +  /* Verify that at least one iMCU row has been passed. */
    +  lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
    +  if (num_lines < lines_per_iMCU_row)
    +    ERREXIT(cinfo, JERR_BUFFER_SIZE);
    +
    +  /* Directly compress the row. */
    +  if (! (*cinfo->coef->compress_data) (cinfo, data)) {
    +    /* If compressor did not consume the whole row, suspend processing. */
    +    return 0;
    +  }
    +
    +  /* OK, we processed one iMCU row. */
    +  cinfo->next_scanline += lines_per_iMCU_row;
    +  return lines_per_iMCU_row;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jccoefct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jccoefct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jccoefct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jccoefct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,453 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jccoefct.c
    + *
    + * Copyright (C) 1994-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the coefficient buffer controller for compression.
    + * This controller is the top level of the JPEG compressor proper.
    + * The coefficient buffer lies between forward-DCT and entropy encoding steps.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* We use a full-image coefficient buffer when doing Huffman optimization,
    + * and also for writing multiple-scan JPEG files.  In all cases, the DCT
    + * step is run during the first pass, and subsequent passes need only read
    + * the buffered coefficients.
    + */
    +#ifdef ENTROPY_OPT_SUPPORTED
    +#define FULL_COEF_BUFFER_SUPPORTED
    +#else
    +#ifdef C_MULTISCAN_FILES_SUPPORTED
    +#define FULL_COEF_BUFFER_SUPPORTED
    +#endif
    +#endif
    +
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_c_coef_controller pub; /* public fields */
    +
    +  JDIMENSION iMCU_row_num;      /* iMCU row # within image */
    +  JDIMENSION mcu_ctr;           /* counts MCUs processed in current row */
    +  int MCU_vert_offset;          /* counts MCU rows within iMCU row */
    +  int MCU_rows_per_iMCU_row;    /* number of such rows needed */
    +
    +  /* For single-pass compression, it's sufficient to buffer just one MCU
    +   * (although this may prove a bit slow in practice).  We allocate a
    +   * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
    +   * MCU constructed and sent.  (On 80x86, the workspace is FAR even though
    +   * it's not really very big; this is to keep the module interfaces unchanged
    +   * when a large coefficient buffer is necessary.)
    +   * In multi-pass modes, this array points to the current MCU's blocks
    +   * within the virtual arrays.
    +   */
    +  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
    +
    +  /* In multi-pass modes, we need a virtual block array for each component. */
    +  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
    +} my_coef_controller;
    +
    +typedef my_coef_controller * my_coef_ptr;
    +
    +
    +/* Forward declarations */
    +METHODDEF(boolean) compress_data
    +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
    +#ifdef FULL_COEF_BUFFER_SUPPORTED
    +METHODDEF(boolean) compress_first_pass
    +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
    +METHODDEF(boolean) compress_output
    +    JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
    +#endif
    +
    +
    +LOCAL(void)
    +start_iMCU_row (j_compress_ptr cinfo)
    +/* Reset within-iMCU-row counters for a new row */
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
    +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
    +   * But at the bottom of the image, process only what's left.
    +   */
    +  if (cinfo->comps_in_scan > 1) {
    +    coef->MCU_rows_per_iMCU_row = 1;
    +  } else {
    +    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
    +    else
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
    +  }
    +
    +  coef->mcu_ctr = 0;
    +  coef->MCU_vert_offset = 0;
    +}
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  coef->iMCU_row_num = 0;
    +  start_iMCU_row(cinfo);
    +
    +  switch (pass_mode) {
    +  case JBUF_PASS_THRU:
    +    if (coef->whole_image[0] != NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    coef->pub.compress_data = compress_data;
    +    break;
    +#ifdef FULL_COEF_BUFFER_SUPPORTED
    +  case JBUF_SAVE_AND_PASS:
    +    if (coef->whole_image[0] == NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    coef->pub.compress_data = compress_first_pass;
    +    break;
    +  case JBUF_CRANK_DEST:
    +    if (coef->whole_image[0] == NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    coef->pub.compress_data = compress_output;
    +    break;
    +#endif
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    break;
    +  }
    +}
    +
    +
    +/*
    + * Process some data in the single-pass case.
    + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
    + * per call, ie, v_samp_factor block rows for each component in the image.
    + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
    + *
    + * NB: input_buf contains a plane for each component in image,
    + * which we index according to the component's SOF position.
    + */
    +
    +METHODDEF(boolean)
    +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  int blkn, bi, ci, yindex, yoffset, blockcnt;
    +  JDIMENSION ypos, xpos;
    +  jpeg_component_info *compptr;
    +
    +  /* Loop to write as much as one whole iMCU row */
    +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    +       yoffset++) {
    +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
    +         MCU_col_num++) {
    +      /* Determine where data comes from in input_buf and do the DCT thing.
    +       * Each call on forward_DCT processes a horizontal row of DCT blocks
    +       * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
    +       * sequentially.  Dummy blocks at the right or bottom edge are filled in
    +       * specially.  The data in them does not matter for image reconstruction,
    +       * so we fill them with values that will encode to the smallest amount of
    +       * data, viz: all zeroes in the AC entries, DC entries equal to previous
    +       * block's DC value.  (Thanks to Thomas Kinsman for this idea.)
    +       */
    +      blkn = 0;
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +        compptr = cinfo->cur_comp_info[ci];
    +        blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
    +                                                : compptr->last_col_width;
    +        xpos = MCU_col_num * compptr->MCU_sample_width;
    +        ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
    +        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    +          if (coef->iMCU_row_num < last_iMCU_row ||
    +              yoffset+yindex < compptr->last_row_height) {
    +            (*cinfo->fdct->forward_DCT) (cinfo, compptr,
    +                                         input_buf[compptr->component_index],
    +                                         coef->MCU_buffer[blkn],
    +                                         ypos, xpos, (JDIMENSION) blockcnt);
    +            if (blockcnt < compptr->MCU_width) {
    +              /* Create some dummy blocks at the right edge of the image. */
    +              jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
    +                        (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
    +              for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
    +                coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
    +              }
    +            }
    +          } else {
    +            /* Create a row of dummy blocks at the bottom of the image. */
    +            jzero_far((void FAR *) coef->MCU_buffer[blkn],
    +                      compptr->MCU_width * SIZEOF(JBLOCK));
    +            for (bi = 0; bi < compptr->MCU_width; bi++) {
    +              coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
    +            }
    +          }
    +          blkn += compptr->MCU_width;
    +          ypos += DCTSIZE;
    +        }
    +      }
    +      /* Try to write the MCU.  In event of a suspension failure, we will
    +       * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
    +       */
    +      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
    +        /* Suspension forced; update state counters and exit */
    +        coef->MCU_vert_offset = yoffset;
    +        coef->mcu_ctr = MCU_col_num;
    +        return FALSE;
    +      }
    +    }
    +    /* Completed an MCU row, but perhaps not an iMCU row */
    +    coef->mcu_ctr = 0;
    +  }
    +  /* Completed the iMCU row, advance counters for next one */
    +  coef->iMCU_row_num++;
    +  start_iMCU_row(cinfo);
    +  return TRUE;
    +}
    +
    +
    +#ifdef FULL_COEF_BUFFER_SUPPORTED
    +
    +/*
    + * Process some data in the first pass of a multi-pass case.
    + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
    + * per call, ie, v_samp_factor block rows for each component in the image.
    + * This amount of data is read from the source buffer, DCT'd and quantized,
    + * and saved into the virtual arrays.  We also generate suitable dummy blocks
    + * as needed at the right and lower edges.  (The dummy blocks are constructed
    + * in the virtual arrays, which have been padded appropriately.)  This makes
    + * it possible for subsequent passes not to worry about real vs. dummy blocks.
    + *
    + * We must also emit the data to the entropy encoder.  This is conveniently
    + * done by calling compress_output() after we've loaded the current strip
    + * of the virtual arrays.
    + *
    + * NB: input_buf contains a plane for each component in image.  All
    + * components are DCT'd and loaded into the virtual arrays in this pass.
    + * However, it may be that only a subset of the components are emitted to
    + * the entropy encoder during this first pass; be careful about looking
    + * at the scan-dependent variables (MCU dimensions, etc).
    + */
    +
    +METHODDEF(boolean)
    +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  JDIMENSION blocks_across, MCUs_across, MCUindex;
    +  int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
    +  JCOEF lastDC;
    +  jpeg_component_info *compptr;
    +  JBLOCKARRAY buffer;
    +  JBLOCKROW thisblockrow, lastblockrow;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Align the virtual buffer for this component. */
    +    buffer = (*cinfo->mem->access_virt_barray)
    +      ((j_common_ptr) cinfo, coef->whole_image[ci],
    +       coef->iMCU_row_num * compptr->v_samp_factor,
    +       (JDIMENSION) compptr->v_samp_factor, TRUE);
    +    /* Count non-dummy DCT block rows in this iMCU row. */
    +    if (coef->iMCU_row_num < last_iMCU_row)
    +      block_rows = compptr->v_samp_factor;
    +    else {
    +      /* NB: can't use last_row_height here, since may not be set! */
    +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
    +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    +    }
    +    blocks_across = compptr->width_in_blocks;
    +    h_samp_factor = compptr->h_samp_factor;
    +    /* Count number of dummy blocks to be added at the right margin. */
    +    ndummy = (int) (blocks_across % h_samp_factor);
    +    if (ndummy > 0)
    +      ndummy = h_samp_factor - ndummy;
    +    /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call
    +     * on forward_DCT processes a complete horizontal row of DCT blocks.
    +     */
    +    for (block_row = 0; block_row < block_rows; block_row++) {
    +      thisblockrow = buffer[block_row];
    +      (*cinfo->fdct->forward_DCT) (cinfo, compptr,
    +                                   input_buf[ci], thisblockrow,
    +                                   (JDIMENSION) (block_row * DCTSIZE),
    +                                   (JDIMENSION) 0, blocks_across);
    +      if (ndummy > 0) {
    +        /* Create dummy blocks at the right edge of the image. */
    +        thisblockrow += blocks_across; /* => first dummy block */
    +        jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
    +        lastDC = thisblockrow[-1][0];
    +        for (bi = 0; bi < ndummy; bi++) {
    +          thisblockrow[bi][0] = lastDC;
    +        }
    +      }
    +    }
    +    /* If at end of image, create dummy block rows as needed.
    +     * The tricky part here is that within each MCU, we want the DC values
    +     * of the dummy blocks to match the last real block's DC value.
    +     * This squeezes a few more bytes out of the resulting file...
    +     */
    +    if (coef->iMCU_row_num == last_iMCU_row) {
    +      blocks_across += ndummy;  /* include lower right corner */
    +      MCUs_across = blocks_across / h_samp_factor;
    +      for (block_row = block_rows; block_row < compptr->v_samp_factor;
    +           block_row++) {
    +        thisblockrow = buffer[block_row];
    +        lastblockrow = buffer[block_row-1];
    +        jzero_far((void FAR *) thisblockrow,
    +                  (size_t) (blocks_across * SIZEOF(JBLOCK)));
    +        for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
    +          lastDC = lastblockrow[h_samp_factor-1][0];
    +          for (bi = 0; bi < h_samp_factor; bi++) {
    +            thisblockrow[bi][0] = lastDC;
    +          }
    +          thisblockrow += h_samp_factor; /* advance to next MCU in row */
    +          lastblockrow += h_samp_factor;
    +        }
    +      }
    +    }
    +  }
    +  /* NB: compress_output will increment iMCU_row_num if successful.
    +   * A suspension return will result in redoing all the work above next time.
    +   */
    +
    +  /* Emit data to the entropy encoder, sharing code with subsequent passes */
    +  return compress_output(cinfo, input_buf);
    +}
    +
    +
    +/*
    + * Process some data in subsequent passes of a multi-pass case.
    + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
    + * per call, ie, v_samp_factor block rows for each component in the scan.
    + * The data is obtained from the virtual arrays and fed to the entropy coder.
    + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
    + *
    + * NB: input_buf is ignored; it is likely to be a NULL pointer.
    + */
    +
    +METHODDEF(boolean)
    +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    +  int blkn, ci, xindex, yindex, yoffset;
    +  JDIMENSION start_col;
    +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    +  JBLOCKROW buffer_ptr;
    +  jpeg_component_info *compptr;
    +
    +  /* Align the virtual buffers for the components used in this scan.
    +   * NB: during first pass, this is safe only because the buffers will
    +   * already be aligned properly, so jmemmgr.c won't need to do any I/O.
    +   */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    buffer[ci] = (*cinfo->mem->access_virt_barray)
    +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
    +       coef->iMCU_row_num * compptr->v_samp_factor,
    +       (JDIMENSION) compptr->v_samp_factor, FALSE);
    +  }
    +
    +  /* Loop to process one whole iMCU row */
    +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    +       yoffset++) {
    +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
    +         MCU_col_num++) {
    +      /* Construct list of pointers to DCT blocks belonging to this MCU */
    +      blkn = 0;                 /* index of current DCT block within MCU */
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +        compptr = cinfo->cur_comp_info[ci];
    +        start_col = MCU_col_num * compptr->MCU_width;
    +        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    +          buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
    +          for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
    +            coef->MCU_buffer[blkn++] = buffer_ptr++;
    +          }
    +        }
    +      }
    +      /* Try to write the MCU. */
    +      if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
    +        /* Suspension forced; update state counters and exit */
    +        coef->MCU_vert_offset = yoffset;
    +        coef->mcu_ctr = MCU_col_num;
    +        return FALSE;
    +      }
    +    }
    +    /* Completed an MCU row, but perhaps not an iMCU row */
    +    coef->mcu_ctr = 0;
    +  }
    +  /* Completed the iMCU row, advance counters for next one */
    +  coef->iMCU_row_num++;
    +  start_iMCU_row(cinfo);
    +  return TRUE;
    +}
    +
    +#endif /* FULL_COEF_BUFFER_SUPPORTED */
    +
    +
    +/*
    + * Initialize coefficient buffer controller.
    + */
    +
    +GLOBAL(void)
    +jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_coef_ptr coef;
    +
    +  coef = (my_coef_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_coef_controller));
    +  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
    +  coef->pub.start_pass = start_pass_coef;
    +
    +  /* Create the coefficient buffer. */
    +  if (need_full_buffer) {
    +#ifdef FULL_COEF_BUFFER_SUPPORTED
    +    /* Allocate a full-image virtual array for each component, */
    +    /* padded to a multiple of samp_factor DCT blocks in each direction. */
    +    int ci;
    +    jpeg_component_info *compptr;
    +
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
    +         (JDIMENSION) jround_up((long) compptr->width_in_blocks,
    +                                (long) compptr->h_samp_factor),
    +         (JDIMENSION) jround_up((long) compptr->height_in_blocks,
    +                                (long) compptr->v_samp_factor),
    +         (JDIMENSION) compptr->v_samp_factor);
    +    }
    +#else
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +#endif
    +  } else {
    +    /* We only need a single-MCU buffer. */
    +    JBLOCKROW buffer;
    +    int i;
    +
    +    buffer = (JBLOCKROW)
    +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
    +    for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
    +      coef->MCU_buffer[i] = buffer + i;
    +    }
    +    coef->whole_image[0] = NULL; /* flag for no virtual arrays */
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jccolor.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jccolor.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jccolor.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jccolor.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,462 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jccolor.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains input colorspace conversion routines.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private subobject */
    +
    +typedef struct {
    +  struct jpeg_color_converter pub; /* public fields */
    +
    +  /* Private state for RGB->YCC conversion */
    +  INT32 * rgb_ycc_tab;          /* => table for RGB to YCbCr conversion */
    +} my_color_converter;
    +
    +typedef my_color_converter * my_cconvert_ptr;
    +
    +
    +/**************** RGB -> YCbCr conversion: most common case **************/
    +
    +/*
    + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
    + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
    + * The conversion equations to be implemented are therefore
    + *      Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
    + *      Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + CENTERJSAMPLE
    + *      Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + CENTERJSAMPLE
    + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
    + * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
    + * rather than CENTERJSAMPLE, for Cb and Cr.  This gave equal positive and
    + * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
    + * were not represented exactly.  Now we sacrifice exact representation of
    + * maximum red and maximum blue in order to get exact grayscales.
    + *
    + * To avoid floating-point arithmetic, we represent the fractional constants
    + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
    + * the products by 2^16, with appropriate rounding, to get the correct answer.
    + *
    + * For even more speed, we avoid doing any multiplications in the inner loop
    + * by precalculating the constants times R,G,B for all possible values.
    + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
    + * for 12-bit samples it is still acceptable.  It's not very reasonable for
    + * 16-bit samples, but if you want lossless storage you shouldn't be changing
    + * colorspace anyway.
    + * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
    + * in the tables to save adding them separately in the inner loop.
    + */
    +
    +#define SCALEBITS       16      /* speediest right-shift on some machines */
    +#define CBCR_OFFSET     ((INT32) CENTERJSAMPLE << SCALEBITS)
    +#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
    +#define FIX(x)          ((INT32) ((x) * (1L< Y section */
    +#define G_Y_OFF         (1*(MAXJSAMPLE+1))      /* offset to G => Y section */
    +#define B_Y_OFF         (2*(MAXJSAMPLE+1))      /* etc. */
    +#define R_CB_OFF        (3*(MAXJSAMPLE+1))
    +#define G_CB_OFF        (4*(MAXJSAMPLE+1))
    +#define B_CB_OFF        (5*(MAXJSAMPLE+1))
    +#define R_CR_OFF        B_CB_OFF                /* B=>Cb, R=>Cr are the same */
    +#define G_CR_OFF        (6*(MAXJSAMPLE+1))
    +#define B_CR_OFF        (7*(MAXJSAMPLE+1))
    +#define TABLE_SIZE      (8*(MAXJSAMPLE+1))
    +
    +
    +/*
    + * Initialize for RGB->YCC colorspace conversion.
    + */
    +
    +METHODDEF(void)
    +rgb_ycc_start (j_compress_ptr cinfo)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  INT32 * rgb_ycc_tab;
    +  INT32 i;
    +
    +  /* Allocate and fill in the conversion tables. */
    +  cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (TABLE_SIZE * SIZEOF(INT32)));
    +
    +  for (i = 0; i <= MAXJSAMPLE; i++) {
    +    rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
    +    rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
    +    rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
    +    rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
    +    rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
    +    /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
    +     * This ensures that the maximum output will round to MAXJSAMPLE
    +     * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
    +     */
    +    rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
    +/*  B=>Cb and R=>Cr tables are the same
    +    rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
    +*/
    +    rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
    +    rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
    +  }
    +}
    +
    +
    +/*
    + * Convert some rows of samples to the JPEG colorspace.
    + *
    + * Note that we change from the application's interleaved-pixel format
    + * to our internal noninterleaved, one-plane-per-component format.
    + * The input buffer is therefore three times as wide as the output buffer.
    + *
    + * A starting row offset is provided only for the output buffer.  The caller
    + * can easily adjust the passed input_buf value to accommodate any row
    + * offset required on that side.
    + */
    +
    +METHODDEF(void)
    +rgb_ycc_convert (j_compress_ptr cinfo,
    +                 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +                 JDIMENSION output_row, int num_rows)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  register int r, g, b;
    +  register INT32 * ctab = cconvert->rgb_ycc_tab;
    +  register JSAMPROW inptr;
    +  register JSAMPROW outptr0, outptr1, outptr2;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->image_width;
    +
    +  while (--num_rows >= 0) {
    +    inptr = *input_buf++;
    +    outptr0 = output_buf[0][output_row];
    +    outptr1 = output_buf[1][output_row];
    +    outptr2 = output_buf[2][output_row];
    +    output_row++;
    +    for (col = 0; col < num_cols; col++) {
    +      r = GETJSAMPLE(inptr[RGB_RED]);
    +      g = GETJSAMPLE(inptr[RGB_GREEN]);
    +      b = GETJSAMPLE(inptr[RGB_BLUE]);
    +      inptr += RGB_PIXELSIZE;
    +      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
    +       * must be too; we do not need an explicit range-limiting operation.
    +       * Hence the value being shifted is never negative, and we don't
    +       * need the general RIGHT_SHIFT macro.
    +       */
    +      /* Y */
    +      outptr0[col] = (JSAMPLE)
    +                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
    +                 >> SCALEBITS);
    +      /* Cb */
    +      outptr1[col] = (JSAMPLE)
    +                ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
    +                 >> SCALEBITS);
    +      /* Cr */
    +      outptr2[col] = (JSAMPLE)
    +                ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
    +                 >> SCALEBITS);
    +    }
    +  }
    +}
    +
    +
    +/**************** Cases other than RGB -> YCbCr **************/
    +
    +
    +/*
    + * Convert some rows of samples to the JPEG colorspace.
    + * This version handles RGB->grayscale conversion, which is the same
    + * as the RGB->Y portion of RGB->YCbCr.
    + * We assume rgb_ycc_start has been called (we only use the Y tables).
    + */
    +
    +METHODDEF(void)
    +rgb_gray_convert (j_compress_ptr cinfo,
    +                  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +                  JDIMENSION output_row, int num_rows)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  register int r, g, b;
    +  register INT32 * ctab = cconvert->rgb_ycc_tab;
    +  register JSAMPROW inptr;
    +  register JSAMPROW outptr;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->image_width;
    +
    +  while (--num_rows >= 0) {
    +    inptr = *input_buf++;
    +    outptr = output_buf[0][output_row];
    +    output_row++;
    +    for (col = 0; col < num_cols; col++) {
    +      r = GETJSAMPLE(inptr[RGB_RED]);
    +      g = GETJSAMPLE(inptr[RGB_GREEN]);
    +      b = GETJSAMPLE(inptr[RGB_BLUE]);
    +      inptr += RGB_PIXELSIZE;
    +      /* Y */
    +      outptr[col] = (JSAMPLE)
    +                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
    +                 >> SCALEBITS);
    +    }
    +  }
    +}
    +
    +/*
    + * Convert some rows of samples to the JPEG colorspace.
    + * This version handles Adobe-style CMYK->YCCK conversion,
    + * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
    + * conversion as above, while passing K (black) unchanged.
    + * We assume rgb_ycc_start has been called.
    + */
    +
    +METHODDEF(void)
    +cmyk_ycck_convert (j_compress_ptr cinfo,
    +                   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +                   JDIMENSION output_row, int num_rows)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  register int r, g, b;
    +  register INT32 * ctab = cconvert->rgb_ycc_tab;
    +  register JSAMPROW inptr;
    +  register JSAMPROW outptr0, outptr1, outptr2, outptr3;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->image_width;
    +
    +  while (--num_rows >= 0) {
    +    inptr = *input_buf++;
    +    outptr0 = output_buf[0][output_row];
    +    outptr1 = output_buf[1][output_row];
    +    outptr2 = output_buf[2][output_row];
    +    outptr3 = output_buf[3][output_row];
    +    output_row++;
    +    for (col = 0; col < num_cols; col++) {
    +      r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
    +      g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
    +      b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
    +      /* K passes through as-is */
    +      outptr3[col] = inptr[3];  /* don't need GETJSAMPLE here */
    +      inptr += 4;
    +      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
    +       * must be too; we do not need an explicit range-limiting operation.
    +       * Hence the value being shifted is never negative, and we don't
    +       * need the general RIGHT_SHIFT macro.
    +       */
    +      /* Y */
    +      outptr0[col] = (JSAMPLE)
    +                ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
    +                 >> SCALEBITS);
    +      /* Cb */
    +      outptr1[col] = (JSAMPLE)
    +                ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
    +                 >> SCALEBITS);
    +      /* Cr */
    +      outptr2[col] = (JSAMPLE)
    +                ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
    +                 >> SCALEBITS);
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Convert some rows of samples to the JPEG colorspace.
    + * This version handles grayscale output with no conversion.
    + * The source can be either plain grayscale or YCbCr (since Y == gray).
    + */
    +
    +METHODDEF(void)
    +grayscale_convert (j_compress_ptr cinfo,
    +                   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +                   JDIMENSION output_row, int num_rows)
    +{
    +  register JSAMPROW inptr;
    +  register JSAMPROW outptr;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->image_width;
    +  int instride = cinfo->input_components;
    +
    +  while (--num_rows >= 0) {
    +    inptr = *input_buf++;
    +    outptr = output_buf[0][output_row];
    +    output_row++;
    +    for (col = 0; col < num_cols; col++) {
    +      outptr[col] = inptr[0];   /* don't need GETJSAMPLE() here */
    +      inptr += instride;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Convert some rows of samples to the JPEG colorspace.
    + * This version handles multi-component colorspaces without conversion.
    + * We assume input_components == num_components.
    + */
    +
    +METHODDEF(void)
    +null_convert (j_compress_ptr cinfo,
    +              JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +              JDIMENSION output_row, int num_rows)
    +{
    +  register JSAMPROW inptr;
    +  register JSAMPROW outptr;
    +  register JDIMENSION col;
    +  register int ci;
    +  int nc = cinfo->num_components;
    +  JDIMENSION num_cols = cinfo->image_width;
    +
    +  while (--num_rows >= 0) {
    +    /* It seems fastest to make a separate pass for each component. */
    +    for (ci = 0; ci < nc; ci++) {
    +      inptr = *input_buf;
    +      outptr = output_buf[ci][output_row];
    +      for (col = 0; col < num_cols; col++) {
    +        outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
    +        inptr += nc;
    +      }
    +    }
    +    input_buf++;
    +    output_row++;
    +  }
    +}
    +
    +
    +/*
    + * Empty method for start_pass.
    + */
    +
    +METHODDEF(void)
    +null_method (j_compress_ptr cinfo)
    +{
    +  /* no work needed */
    +}
    +
    +
    +/*
    + * Module initialization routine for input colorspace conversion.
    + */
    +
    +GLOBAL(void)
    +jinit_color_converter (j_compress_ptr cinfo)
    +{
    +  my_cconvert_ptr cconvert;
    +
    +  cconvert = (my_cconvert_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_color_converter));
    +  cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
    +  /* set start_pass to null method until we find out differently */
    +  cconvert->pub.start_pass = null_method;
    +
    +  /* Make sure input_components agrees with in_color_space */
    +  switch (cinfo->in_color_space) {
    +  case JCS_GRAYSCALE:
    +    if (cinfo->input_components != 1)
    +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +    break;
    +
    +  case JCS_RGB:
    +#if RGB_PIXELSIZE != 3
    +    if (cinfo->input_components != RGB_PIXELSIZE)
    +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +    break;
    +#endif /* else share code with YCbCr */
    +
    +  case JCS_YCbCr:
    +    if (cinfo->input_components != 3)
    +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +    break;
    +
    +  case JCS_CMYK:
    +  case JCS_YCCK:
    +    if (cinfo->input_components != 4)
    +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +    break;
    +
    +  default:                      /* JCS_UNKNOWN can be anything */
    +    if (cinfo->input_components < 1)
    +      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +    break;
    +  }
    +
    +  /* Check num_components, set conversion method based on requested space */
    +  switch (cinfo->jpeg_color_space) {
    +  case JCS_GRAYSCALE:
    +    if (cinfo->num_components != 1)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    if (cinfo->in_color_space == JCS_GRAYSCALE)
    +      cconvert->pub.color_convert = grayscale_convert;
    +    else if (cinfo->in_color_space == JCS_RGB) {
    +      cconvert->pub.start_pass = rgb_ycc_start;
    +      cconvert->pub.color_convert = rgb_gray_convert;
    +    } else if (cinfo->in_color_space == JCS_YCbCr)
    +      cconvert->pub.color_convert = grayscale_convert;
    +    else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_RGB:
    +    if (cinfo->num_components != 3)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
    +      cconvert->pub.color_convert = null_convert;
    +    else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_YCbCr:
    +    if (cinfo->num_components != 3)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    if (cinfo->in_color_space == JCS_RGB) {
    +      cconvert->pub.start_pass = rgb_ycc_start;
    +      cconvert->pub.color_convert = rgb_ycc_convert;
    +    } else if (cinfo->in_color_space == JCS_YCbCr)
    +      cconvert->pub.color_convert = null_convert;
    +    else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_CMYK:
    +    if (cinfo->num_components != 4)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    if (cinfo->in_color_space == JCS_CMYK)
    +      cconvert->pub.color_convert = null_convert;
    +    else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_YCCK:
    +    if (cinfo->num_components != 4)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    if (cinfo->in_color_space == JCS_CMYK) {
    +      cconvert->pub.start_pass = rgb_ycc_start;
    +      cconvert->pub.color_convert = cmyk_ycck_convert;
    +    } else if (cinfo->in_color_space == JCS_YCCK)
    +      cconvert->pub.color_convert = null_convert;
    +    else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  default:                      /* allow null conversion of JCS_UNKNOWN */
    +    if (cinfo->jpeg_color_space != cinfo->in_color_space ||
    +        cinfo->num_components != cinfo->input_components)
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    cconvert->pub.color_convert = null_convert;
    +    break;
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcdctmgr.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcdctmgr.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcdctmgr.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcdctmgr.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,391 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcdctmgr.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the forward-DCT management logic.
    + * This code selects a particular DCT implementation to be used,
    + * and it performs related housekeeping chores including coefficient
    + * quantization.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +
    +/* Private subobject for this module */
    +
    +typedef struct {
    +  struct jpeg_forward_dct pub;  /* public fields */
    +
    +  /* Pointer to the DCT routine actually in use */
    +  forward_DCT_method_ptr do_dct;
    +
    +  /* The actual post-DCT divisors --- not identical to the quant table
    +   * entries, because of scaling (especially for an unnormalized DCT).
    +   * Each table is given in normal array order.
    +   */
    +  DCTELEM * divisors[NUM_QUANT_TBLS];
    +
    +#ifdef DCT_FLOAT_SUPPORTED
    +  /* Same as above for the floating-point case. */
    +  float_DCT_method_ptr do_float_dct;
    +  FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
    +#endif
    +} my_fdct_controller;
    +
    +typedef my_fdct_controller * my_fdct_ptr;
    +
    +
    +/*
    + * Initialize for a processing pass.
    + * Verify that all referenced Q-tables are present, and set up
    + * the divisor table for each one.
    + * In the current implementation, DCT of all components is done during
    + * the first pass, even if only some components will be output in the
    + * first scan.  Hence all components should be examined here.
    + */
    +
    +METHODDEF(void)
    +start_pass_fdctmgr (j_compress_ptr cinfo)
    +{
    +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
    +  int ci, qtblno, i;
    +  jpeg_component_info *compptr;
    +  JQUANT_TBL * qtbl;
    +  DCTELEM * dtbl;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    qtblno = compptr->quant_tbl_no;
    +    /* Make sure specified quantization table is present */
    +    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
    +        cinfo->quant_tbl_ptrs[qtblno] == NULL)
    +      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
    +    qtbl = cinfo->quant_tbl_ptrs[qtblno];
    +    /* Compute divisors for this quant table */
    +    /* We may do this more than once for same table, but it's not a big deal */
    +    switch (cinfo->dct_method) {
    +#ifdef DCT_ISLOW_SUPPORTED
    +    case JDCT_ISLOW:
    +      /* For LL&M IDCT method, divisors are equal to raw quantization
    +       * coefficients multiplied by 8 (to counteract scaling).
    +       */
    +      if (fdct->divisors[qtblno] == NULL) {
    +        fdct->divisors[qtblno] = (DCTELEM *)
    +          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                      DCTSIZE2 * SIZEOF(DCTELEM));
    +      }
    +      dtbl = fdct->divisors[qtblno];
    +      for (i = 0; i < DCTSIZE2; i++) {
    +        dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
    +      }
    +      break;
    +#endif
    +#ifdef DCT_IFAST_SUPPORTED
    +    case JDCT_IFAST:
    +      {
    +        /* For AA&N IDCT method, divisors are equal to quantization
    +         * coefficients scaled by scalefactor[row]*scalefactor[col], where
    +         *   scalefactor[0] = 1
    +         *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
    +         * We apply a further scale factor of 8.
    +         */
    +#define CONST_BITS 14
    +        static const INT16 aanscales[DCTSIZE2] = {
    +          /* precomputed values scaled up by 14 bits */
    +          16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
    +          22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
    +          21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
    +          19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
    +          16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
    +          12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
    +           8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
    +           4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
    +        };
    +        SHIFT_TEMPS
    +
    +        if (fdct->divisors[qtblno] == NULL) {
    +          fdct->divisors[qtblno] = (DCTELEM *)
    +            (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                        DCTSIZE2 * SIZEOF(DCTELEM));
    +        }
    +        dtbl = fdct->divisors[qtblno];
    +        for (i = 0; i < DCTSIZE2; i++) {
    +          dtbl[i] = (DCTELEM)
    +            DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
    +                                  (INT32) aanscales[i]),
    +                    CONST_BITS-3);
    +        }
    +      }
    +      break;
    +#endif
    +#ifdef DCT_FLOAT_SUPPORTED
    +    case JDCT_FLOAT:
    +      {
    +        /* For float AA&N IDCT method, divisors are equal to quantization
    +         * coefficients scaled by scalefactor[row]*scalefactor[col], where
    +         *   scalefactor[0] = 1
    +         *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
    +         * We apply a further scale factor of 8.
    +         * What's actually stored is 1/divisor so that the inner loop can
    +         * use a multiplication rather than a division.
    +         */
    +        FAST_FLOAT * fdtbl;
    +        int row, col;
    +        static const double aanscalefactor[DCTSIZE] = {
    +          1.0, 1.387039845, 1.306562965, 1.175875602,
    +          1.0, 0.785694958, 0.541196100, 0.275899379
    +        };
    +
    +        if (fdct->float_divisors[qtblno] == NULL) {
    +          fdct->float_divisors[qtblno] = (FAST_FLOAT *)
    +            (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                        DCTSIZE2 * SIZEOF(FAST_FLOAT));
    +        }
    +        fdtbl = fdct->float_divisors[qtblno];
    +        i = 0;
    +        for (row = 0; row < DCTSIZE; row++) {
    +          for (col = 0; col < DCTSIZE; col++) {
    +            fdtbl[i] = (FAST_FLOAT)
    +              (1.0 / (((double) qtbl->quantval[i] *
    +                       aanscalefactor[row] * aanscalefactor[col] * 8.0)));
    +            i++;
    +          }
    +        }
    +      }
    +      break;
    +#endif
    +    default:
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +      break;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Perform forward DCT on one or more blocks of a component.
    + *
    + * The input samples are taken from the sample_data[] array starting at
    + * position start_row/start_col, and moving to the right for any additional
    + * blocks. The quantized coefficients are returned in coef_blocks[].
    + */
    +
    +METHODDEF(void)
    +forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +             JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
    +             JDIMENSION start_row, JDIMENSION start_col,
    +             JDIMENSION num_blocks)
    +/* This version is used for integer DCT implementations. */
    +{
    +  /* This routine is heavily used, so it's worth coding it tightly. */
    +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
    +  forward_DCT_method_ptr do_dct = fdct->do_dct;
    +  DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
    +  DCTELEM workspace[DCTSIZE2];  /* work area for FDCT subroutine */
    +  JDIMENSION bi;
    +
    +  sample_data += start_row;     /* fold in the vertical offset once */
    +
    +  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
    +    /* Load data into workspace, applying unsigned->signed conversion */
    +    { register DCTELEM *workspaceptr;
    +      register JSAMPROW elemptr;
    +      register int elemr;
    +
    +      workspaceptr = workspace;
    +      for (elemr = 0; elemr < DCTSIZE; elemr++) {
    +        elemptr = sample_data[elemr] + start_col;
    +#if DCTSIZE == 8                /* unroll the inner loop */
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +        *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +#else
    +        { register int elemc;
    +          for (elemc = DCTSIZE; elemc > 0; elemc--) {
    +            *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
    +          }
    +        }
    +#endif
    +      }
    +    }
    +
    +    /* Perform the DCT */
    +    (*do_dct) (workspace);
    +
    +    /* Quantize/descale the coefficients, and store into coef_blocks[] */
    +    { register DCTELEM temp, qval;
    +      register int i;
    +      register JCOEFPTR output_ptr = coef_blocks[bi];
    +
    +      for (i = 0; i < DCTSIZE2; i++) {
    +        qval = divisors[i];
    +        temp = workspace[i];
    +        /* Divide the coefficient value by qval, ensuring proper rounding.
    +         * Since C does not specify the direction of rounding for negative
    +         * quotients, we have to force the dividend positive for portability.
    +         *
    +         * In most files, at least half of the output values will be zero
    +         * (at default quantization settings, more like three-quarters...)
    +         * so we should ensure that this case is fast.  On many machines,
    +         * a comparison is enough cheaper than a divide to make a special test
    +         * a win.  Since both inputs will be nonnegative, we need only test
    +         * for a < b to discover whether a/b is 0.
    +         * If your machine's division is fast enough, define FAST_DIVIDE.
    +         */
    +#ifdef FAST_DIVIDE
    +#define DIVIDE_BY(a,b)  a /= b
    +#else
    +#define DIVIDE_BY(a,b)  if (a >= b) a /= b; else a = 0
    +#endif
    +        if (temp < 0) {
    +          temp = -temp;
    +          temp += qval>>1;      /* for rounding */
    +          DIVIDE_BY(temp, qval);
    +          temp = -temp;
    +        } else {
    +          temp += qval>>1;      /* for rounding */
    +          DIVIDE_BY(temp, qval);
    +        }
    +        output_ptr[i] = (JCOEF) temp;
    +      }
    +    }
    +  }
    +}
    +
    +
    +#ifdef DCT_FLOAT_SUPPORTED
    +
    +METHODDEF(void)
    +forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                   JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
    +                   JDIMENSION start_row, JDIMENSION start_col,
    +                   JDIMENSION num_blocks)
    +/* This version is used for floating-point DCT implementations. */
    +{
    +  /* This routine is heavily used, so it's worth coding it tightly. */
    +  my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
    +  float_DCT_method_ptr do_dct = fdct->do_float_dct;
    +  FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
    +  FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
    +  JDIMENSION bi;
    +
    +  sample_data += start_row;     /* fold in the vertical offset once */
    +
    +  for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
    +    /* Load data into workspace, applying unsigned->signed conversion */
    +    { register FAST_FLOAT *workspaceptr;
    +      register JSAMPROW elemptr;
    +      register int elemr;
    +
    +      workspaceptr = workspace;
    +      for (elemr = 0; elemr < DCTSIZE; elemr++) {
    +        elemptr = sample_data[elemr] + start_col;
    +#if DCTSIZE == 8                /* unroll the inner loop */
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +        *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +#else
    +        { register int elemc;
    +          for (elemc = DCTSIZE; elemc > 0; elemc--) {
    +            *workspaceptr++ = (FAST_FLOAT)
    +              (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
    +          }
    +        }
    +#endif
    +      }
    +    }
    +
    +    /* Perform the DCT */
    +    (*do_dct) (workspace);
    +
    +    /* Quantize/descale the coefficients, and store into coef_blocks[] */
    +    { register FAST_FLOAT temp;
    +      register int i;
    +      register JCOEFPTR output_ptr = coef_blocks[bi];
    +
    +      for (i = 0; i < DCTSIZE2; i++) {
    +        /* Apply the quantization and scaling factor */
    +        temp = workspace[i] * divisors[i];
    +        /* Round to nearest integer.
    +         * Since C does not specify the direction of rounding for negative
    +         * quotients, we have to force the dividend positive for portability.
    +         * The maximum coefficient size is +-16K (for 12-bit data), so this
    +         * code should work for either 16-bit or 32-bit ints.
    +         */
    +        output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
    +      }
    +    }
    +  }
    +}
    +
    +#endif /* DCT_FLOAT_SUPPORTED */
    +
    +
    +/*
    + * Initialize FDCT manager.
    + */
    +
    +GLOBAL(void)
    +jinit_forward_dct (j_compress_ptr cinfo)
    +{
    +  my_fdct_ptr fdct;
    +  int i;
    +
    +  fdct = (my_fdct_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_fdct_controller));
    +  cinfo->fdct = (struct jpeg_forward_dct *) fdct;
    +  fdct->pub.start_pass = start_pass_fdctmgr;
    +
    +  switch (cinfo->dct_method) {
    +#ifdef DCT_ISLOW_SUPPORTED
    +  case JDCT_ISLOW:
    +    fdct->pub.forward_DCT = forward_DCT;
    +    fdct->do_dct = jpeg_fdct_islow;
    +    break;
    +#endif
    +#ifdef DCT_IFAST_SUPPORTED
    +  case JDCT_IFAST:
    +    fdct->pub.forward_DCT = forward_DCT;
    +    fdct->do_dct = jpeg_fdct_ifast;
    +    break;
    +#endif
    +#ifdef DCT_FLOAT_SUPPORTED
    +  case JDCT_FLOAT:
    +    fdct->pub.forward_DCT = forward_DCT_float;
    +    fdct->do_float_dct = jpeg_fdct_float;
    +    break;
    +#endif
    +  default:
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +    break;
    +  }
    +
    +  /* Mark divisor tables unallocated */
    +  for (i = 0; i < NUM_QUANT_TBLS; i++) {
    +    fdct->divisors[i] = NULL;
    +#ifdef DCT_FLOAT_SUPPORTED
    +    fdct->float_divisors[i] = NULL;
    +#endif
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jchuff.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jchuff.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jchuff.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jchuff.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,916 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jchuff.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains Huffman entropy encoding routines.
    + *
    + * Much of the complexity here has to do with supporting output suspension.
    + * If the data destination module demands suspension, we want to be able to
    + * back up to the start of the current MCU.  To do this, we copy state
    + * variables into local working storage, and update them back to the
    + * permanent JPEG objects only upon successful completion of an MCU.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jchuff.h"             /* Declarations shared with jcphuff.c */
    +
    +
    +/* Expanded entropy encoder object for Huffman encoding.
    + *
    + * The savable_state subrecord contains fields that change within an MCU,
    + * but must not be updated permanently until we complete the MCU.
    + */
    +
    +typedef struct {
    +  INT32 put_buffer;             /* current bit-accumulation buffer */
    +  int put_bits;                 /* # of bits now in it */
    +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
    +} savable_state;
    +
    +/* This macro is to work around compilers with missing or broken
    + * structure assignment.  You'll need to fix this code if you have
    + * such a compiler and you change MAX_COMPS_IN_SCAN.
    + */
    +
    +#ifndef NO_STRUCT_ASSIGN
    +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
    +#else
    +#if MAX_COMPS_IN_SCAN == 4
    +#define ASSIGN_STATE(dest,src)  \
    +        ((dest).put_buffer = (src).put_buffer, \
    +         (dest).put_bits = (src).put_bits, \
    +         (dest).last_dc_val[0] = (src).last_dc_val[0], \
    +         (dest).last_dc_val[1] = (src).last_dc_val[1], \
    +         (dest).last_dc_val[2] = (src).last_dc_val[2], \
    +         (dest).last_dc_val[3] = (src).last_dc_val[3])
    +#endif
    +#endif
    +
    +
    +typedef struct {
    +  struct jpeg_entropy_encoder pub; /* public fields */
    +
    +  savable_state saved;          /* Bit buffer & DC state at start of MCU */
    +
    +  /* These fields are NOT loaded into local working state. */
    +  unsigned int restarts_to_go;  /* MCUs left in this restart interval */
    +  int next_restart_num;         /* next restart number to write (0-7) */
    +
    +  /* Pointers to derived tables (these workspaces have image lifespan) */
    +  c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
    +  c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
    +
    +#ifdef ENTROPY_OPT_SUPPORTED    /* Statistics tables for optimization */
    +  long * dc_count_ptrs[NUM_HUFF_TBLS];
    +  long * ac_count_ptrs[NUM_HUFF_TBLS];
    +#endif
    +} huff_entropy_encoder;
    +
    +typedef huff_entropy_encoder * huff_entropy_ptr;
    +
    +/* Working state while writing an MCU.
    + * This struct contains all the fields that are needed by subroutines.
    + */
    +
    +typedef struct {
    +  JOCTET * next_output_byte;    /* => next byte to write in buffer */
    +  size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
    +  savable_state cur;            /* Current bit buffer & DC state */
    +  j_compress_ptr cinfo;         /* dump_buffer needs access to this */
    +} working_state;
    +
    +
    +/* Forward declarations */
    +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
    +                                        JBLOCKROW *MCU_data));
    +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
    +#ifdef ENTROPY_OPT_SUPPORTED
    +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
    +                                          JBLOCKROW *MCU_data));
    +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
    +#endif
    +
    +
    +/*
    + * Initialize for a Huffman-compressed scan.
    + * If gather_statistics is TRUE, we do not output anything during the scan,
    + * just count the Huffman symbols used and generate Huffman code tables.
    + */
    +
    +METHODDEF(void)
    +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int ci, dctbl, actbl;
    +  jpeg_component_info * compptr;
    +
    +  if (gather_statistics) {
    +#ifdef ENTROPY_OPT_SUPPORTED
    +    entropy->pub.encode_mcu = encode_mcu_gather;
    +    entropy->pub.finish_pass = finish_pass_gather;
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +  } else {
    +    entropy->pub.encode_mcu = encode_mcu_huff;
    +    entropy->pub.finish_pass = finish_pass_huff;
    +  }
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    dctbl = compptr->dc_tbl_no;
    +    actbl = compptr->ac_tbl_no;
    +    if (gather_statistics) {
    +#ifdef ENTROPY_OPT_SUPPORTED
    +      /* Check for invalid table indexes */
    +      /* (make_c_derived_tbl does this in the other path) */
    +      if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
    +        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
    +      if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
    +        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
    +      /* Allocate and zero the statistics tables */
    +      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
    +      if (entropy->dc_count_ptrs[dctbl] == NULL)
    +        entropy->dc_count_ptrs[dctbl] = (long *)
    +          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                      257 * SIZEOF(long));
    +      MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
    +      if (entropy->ac_count_ptrs[actbl] == NULL)
    +        entropy->ac_count_ptrs[actbl] = (long *)
    +          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                      257 * SIZEOF(long));
    +      MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
    +#endif
    +    } else {
    +      /* Compute derived values for Huffman tables */
    +      /* We may do this more than once for a table, but it's not expensive */
    +      jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
    +                              & entropy->dc_derived_tbls[dctbl]);
    +      jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
    +                              & entropy->ac_derived_tbls[actbl]);
    +    }
    +    /* Initialize DC predictions to 0 */
    +    entropy->saved.last_dc_val[ci] = 0;
    +  }
    +
    +  /* Initialize bit buffer to empty */
    +  entropy->saved.put_buffer = 0;
    +  entropy->saved.put_bits = 0;
    +
    +  /* Initialize restart stuff */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +  entropy->next_restart_num = 0;
    +}
    +
    +
    +/*
    + * Compute the derived values for a Huffman table.
    + * This routine also performs some validation checks on the table.
    + *
    + * Note this is also used by jcphuff.c.
    + */
    +
    +GLOBAL(void)
    +jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
    +                         c_derived_tbl ** pdtbl)
    +{
    +  JHUFF_TBL *htbl;
    +  c_derived_tbl *dtbl;
    +  int p, i, l, lastp, si, maxsymbol;
    +  char huffsize[257];
    +  unsigned int huffcode[257];
    +  unsigned int code;
    +
    +  /* Note that huffsize[] and huffcode[] are filled in code-length order,
    +   * paralleling the order of the symbols themselves in htbl->huffval[].
    +   */
    +
    +  /* Find the input Huffman table */
    +  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
    +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
    +  htbl =
    +    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
    +  if (htbl == NULL)
    +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
    +
    +  /* Allocate a workspace if we haven't already done so. */
    +  if (*pdtbl == NULL)
    +    *pdtbl = (c_derived_tbl *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(c_derived_tbl));
    +  dtbl = *pdtbl;
    +
    +  /* Figure C.1: make table of Huffman code length for each symbol */
    +
    +  p = 0;
    +  for (l = 1; l <= 16; l++) {
    +    i = (int) htbl->bits[l];
    +    if (i < 0 || p + i > 256)   /* protect against table overrun */
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    while (i--)
    +      huffsize[p++] = (char) l;
    +  }
    +  huffsize[p] = 0;
    +  lastp = p;
    +
    +  /* Figure C.2: generate the codes themselves */
    +  /* We also validate that the counts represent a legal Huffman code tree. */
    +
    +  code = 0;
    +  si = huffsize[0];
    +  p = 0;
    +  while (huffsize[p]) {
    +    while (((int) huffsize[p]) == si) {
    +      huffcode[p++] = code;
    +      code++;
    +    }
    +    /* code is now 1 more than the last code used for codelength si; but
    +     * it must still fit in si bits, since no code is allowed to be all ones.
    +     */
    +    if (((INT32) code) >= (((INT32) 1) << si))
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    code <<= 1;
    +    si++;
    +  }
    +
    +  /* Figure C.3: generate encoding tables */
    +  /* These are code and size indexed by symbol value */
    +
    +  /* Set all codeless symbols to have code length 0;
    +   * this lets us detect duplicate VAL entries here, and later
    +   * allows emit_bits to detect any attempt to emit such symbols.
    +   */
    +  MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
    +
    +  /* This is also a convenient place to check for out-of-range
    +   * and duplicated VAL entries.  We allow 0..255 for AC symbols
    +   * but only 0..15 for DC.  (We could constrain them further
    +   * based on data depth and mode, but this seems enough.)
    +   */
    +  maxsymbol = isDC ? 15 : 255;
    +
    +  for (p = 0; p < lastp; p++) {
    +    i = htbl->huffval[p];
    +    if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    dtbl->ehufco[i] = huffcode[p];
    +    dtbl->ehufsi[i] = huffsize[p];
    +  }
    +}
    +
    +
    +/* Outputting bytes to the file */
    +
    +/* Emit a byte, taking 'action' if must suspend. */
    +#define emit_byte(state,val,action)  \
    +        { *(state)->next_output_byte++ = (JOCTET) (val);  \
    +          if (--(state)->free_in_buffer == 0)  \
    +            if (! dump_buffer(state))  \
    +              { action; } }
    +
    +
    +LOCAL(boolean)
    +dump_buffer (working_state * state)
    +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
    +{
    +  struct jpeg_destination_mgr * dest = state->cinfo->dest;
    +
    +  if (! (*dest->empty_output_buffer) (state->cinfo))
    +    return FALSE;
    +  /* After a successful buffer dump, must reset buffer pointers */
    +  state->next_output_byte = dest->next_output_byte;
    +  state->free_in_buffer = dest->free_in_buffer;
    +  return TRUE;
    +}
    +
    +
    +/* Outputting bits to the file */
    +
    +/* Only the right 24 bits of put_buffer are used; the valid bits are
    + * left-justified in this part.  At most 16 bits can be passed to emit_bits
    + * in one call, and we never retain more than 7 bits in put_buffer
    + * between calls, so 24 bits are sufficient.
    + */
    +
    +INLINE
    +LOCAL(boolean)
    +emit_bits (working_state * state, unsigned int code, int size)
    +/* Emit some bits; return TRUE if successful, FALSE if must suspend */
    +{
    +  /* This routine is heavily used, so it's worth coding tightly. */
    +  register INT32 put_buffer = (INT32) code;
    +  register int put_bits = state->cur.put_bits;
    +
    +  /* if size is 0, caller used an invalid Huffman table entry */
    +  if (size == 0)
    +    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
    +
    +  put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */
    +
    +  while (put_bits >= 8) {
    +    int c = (int) ((put_buffer >> 16) & 0xFF);
    +
    +    emit_byte(state, c, return FALSE);
    +    if (c == 0xFF) {            /* need to stuff a zero byte? */
    +      emit_byte(state, 0, return FALSE);
    +    }
    +    put_buffer <<= 8;
    +    put_bits -= 8;
    +  }
    +
    +  state->cur.put_buffer = put_buffer; /* update state variables */
    +  state->cur.put_bits = put_bits;
    +
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +flush_bits (working_state * state)
    +{
    +  if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
    +    return FALSE;
    +  state->cur.put_buffer = 0;    /* and reset bit-buffer to empty */
    +  state->cur.put_bits = 0;
    +  return TRUE;
    +}
    +
    +
    +/* Encode a single block's worth of coefficients */
    +
    +LOCAL(boolean)
    +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
    +                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
    +{
    +  register int temp, temp2;
    +  register int nbits;
    +  register int k, r, i;
    +
    +  /* Encode the DC coefficient difference per section F.1.2.1 */
    +
    +  temp = temp2 = block[0] - last_dc_val;
    +
    +  if (temp < 0) {
    +    temp = -temp;               /* temp is abs value of input */
    +    /* For a negative input, want temp2 = bitwise complement of abs(input) */
    +    /* This code assumes we are on a two's complement machine */
    +    temp2--;
    +  }
    +
    +  /* Find the number of bits needed for the magnitude of the coefficient */
    +  nbits = 0;
    +  while (temp) {
    +    nbits++;
    +    temp >>= 1;
    +  }
    +  /* Check for out-of-range coefficient values.
    +   * Since we're encoding a difference, the range limit is twice as much.
    +   */
    +  if (nbits > MAX_COEF_BITS+1)
    +    ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
    +
    +  /* Emit the Huffman-coded symbol for the number of bits */
    +  if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
    +    return FALSE;
    +
    +  /* Emit that number of bits of the value, if positive, */
    +  /* or the complement of its magnitude, if negative. */
    +  if (nbits)                    /* emit_bits rejects calls with size 0 */
    +    if (! emit_bits(state, (unsigned int) temp2, nbits))
    +      return FALSE;
    +
    +  /* Encode the AC coefficients per section F.1.2.2 */
    +
    +  r = 0;                        /* r = run length of zeros */
    +
    +  for (k = 1; k < DCTSIZE2; k++) {
    +    if ((temp = block[jpeg_natural_order[k]]) == 0) {
    +      r++;
    +    } else {
    +      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
    +      while (r > 15) {
    +        if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
    +          return FALSE;
    +        r -= 16;
    +      }
    +
    +      temp2 = temp;
    +      if (temp < 0) {
    +        temp = -temp;           /* temp is abs value of input */
    +        /* This code assumes we are on a two's complement machine */
    +        temp2--;
    +      }
    +
    +      /* Find the number of bits needed for the magnitude of the coefficient */
    +      nbits = 1;                /* there must be at least one 1 bit */
    +      while ((temp >>= 1))
    +        nbits++;
    +      /* Check for out-of-range coefficient values */
    +      if (nbits > MAX_COEF_BITS)
    +        ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
    +
    +      /* Emit Huffman symbol for run length / number of bits */
    +      i = (r << 4) + nbits;
    +      if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
    +        return FALSE;
    +
    +      /* Emit that number of bits of the value, if positive, */
    +      /* or the complement of its magnitude, if negative. */
    +      if (! emit_bits(state, (unsigned int) temp2, nbits))
    +        return FALSE;
    +
    +      r = 0;
    +    }
    +  }
    +
    +  /* If the last coef(s) were zero, emit an end-of-block code */
    +  if (r > 0)
    +    if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
    +      return FALSE;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Emit a restart marker & resynchronize predictions.
    + */
    +
    +LOCAL(boolean)
    +emit_restart (working_state * state, int restart_num)
    +{
    +  int ci;
    +
    +  if (! flush_bits(state))
    +    return FALSE;
    +
    +  emit_byte(state, 0xFF, return FALSE);
    +  emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
    +
    +  /* Re-initialize DC predictions to 0 */
    +  for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
    +    state->cur.last_dc_val[ci] = 0;
    +
    +  /* The restart counter is not updated until we successfully write the MCU. */
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Encode and output one MCU's worth of Huffman-compressed coefficients.
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  working_state state;
    +  int blkn, ci;
    +  jpeg_component_info * compptr;
    +
    +  /* Load up working state */
    +  state.next_output_byte = cinfo->dest->next_output_byte;
    +  state.free_in_buffer = cinfo->dest->free_in_buffer;
    +  ASSIGN_STATE(state.cur, entropy->saved);
    +  state.cinfo = cinfo;
    +
    +  /* Emit restart marker if needed */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! emit_restart(&state, entropy->next_restart_num))
    +        return FALSE;
    +  }
    +
    +  /* Encode the MCU data blocks */
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    ci = cinfo->MCU_membership[blkn];
    +    compptr = cinfo->cur_comp_info[ci];
    +    if (! encode_one_block(&state,
    +                           MCU_data[blkn][0], state.cur.last_dc_val[ci],
    +                           entropy->dc_derived_tbls[compptr->dc_tbl_no],
    +                           entropy->ac_derived_tbls[compptr->ac_tbl_no]))
    +      return FALSE;
    +    /* Update last_dc_val */
    +    state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
    +  }
    +
    +  /* Completed MCU, so update state */
    +  cinfo->dest->next_output_byte = state.next_output_byte;
    +  cinfo->dest->free_in_buffer = state.free_in_buffer;
    +  ASSIGN_STATE(entropy->saved, state.cur);
    +
    +  /* Update restart-interval state too */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +      entropy->next_restart_num++;
    +      entropy->next_restart_num &= 7;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Finish up at the end of a Huffman-compressed scan.
    + */
    +
    +METHODDEF(void)
    +finish_pass_huff (j_compress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  working_state state;
    +
    +  /* Load up working state ... flush_bits needs it */
    +  state.next_output_byte = cinfo->dest->next_output_byte;
    +  state.free_in_buffer = cinfo->dest->free_in_buffer;
    +  ASSIGN_STATE(state.cur, entropy->saved);
    +  state.cinfo = cinfo;
    +
    +  /* Flush out the last data */
    +  if (! flush_bits(&state))
    +    ERREXIT(cinfo, JERR_CANT_SUSPEND);
    +
    +  /* Update state */
    +  cinfo->dest->next_output_byte = state.next_output_byte;
    +  cinfo->dest->free_in_buffer = state.free_in_buffer;
    +  ASSIGN_STATE(entropy->saved, state.cur);
    +}
    +
    +
    +/*
    + * Huffman coding optimization.
    + *
    + * We first scan the supplied data and count the number of uses of each symbol
    + * that is to be Huffman-coded. (This process MUST agree with the code above.)
    + * Then we build a Huffman coding tree for the observed counts.
    + * Symbols which are not needed at all for the particular image are not
    + * assigned any code, which saves space in the DHT marker as well as in
    + * the compressed data.
    + */
    +
    +#ifdef ENTROPY_OPT_SUPPORTED
    +
    +
    +/* Process a single block's worth of coefficients */
    +
    +LOCAL(void)
    +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
    +                 long dc_counts[], long ac_counts[])
    +{
    +  register int temp;
    +  register int nbits;
    +  register int k, r;
    +
    +  /* Encode the DC coefficient difference per section F.1.2.1 */
    +
    +  temp = block[0] - last_dc_val;
    +  if (temp < 0)
    +    temp = -temp;
    +
    +  /* Find the number of bits needed for the magnitude of the coefficient */
    +  nbits = 0;
    +  while (temp) {
    +    nbits++;
    +    temp >>= 1;
    +  }
    +  /* Check for out-of-range coefficient values.
    +   * Since we're encoding a difference, the range limit is twice as much.
    +   */
    +  if (nbits > MAX_COEF_BITS+1)
    +    ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    +
    +  /* Count the Huffman symbol for the number of bits */
    +  dc_counts[nbits]++;
    +
    +  /* Encode the AC coefficients per section F.1.2.2 */
    +
    +  r = 0;                        /* r = run length of zeros */
    +
    +  for (k = 1; k < DCTSIZE2; k++) {
    +    if ((temp = block[jpeg_natural_order[k]]) == 0) {
    +      r++;
    +    } else {
    +      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
    +      while (r > 15) {
    +        ac_counts[0xF0]++;
    +        r -= 16;
    +      }
    +
    +      /* Find the number of bits needed for the magnitude of the coefficient */
    +      if (temp < 0)
    +        temp = -temp;
    +
    +      /* Find the number of bits needed for the magnitude of the coefficient */
    +      nbits = 1;                /* there must be at least one 1 bit */
    +      while ((temp >>= 1))
    +        nbits++;
    +      /* Check for out-of-range coefficient values */
    +      if (nbits > MAX_COEF_BITS)
    +        ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    +
    +      /* Count Huffman symbol for run length / number of bits */
    +      ac_counts[(r << 4) + nbits]++;
    +
    +      r = 0;
    +    }
    +  }
    +
    +  /* If the last coef(s) were zero, emit an end-of-block code */
    +  if (r > 0)
    +    ac_counts[0]++;
    +}
    +
    +
    +/*
    + * Trial-encode one MCU's worth of Huffman-compressed coefficients.
    + * No data is actually output, so no suspension return is possible.
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int blkn, ci;
    +  jpeg_component_info * compptr;
    +
    +  /* Take care of restart intervals if needed */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      /* Re-initialize DC predictions to 0 */
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++)
    +        entropy->saved.last_dc_val[ci] = 0;
    +      /* Update restart state */
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    ci = cinfo->MCU_membership[blkn];
    +    compptr = cinfo->cur_comp_info[ci];
    +    htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
    +                    entropy->dc_count_ptrs[compptr->dc_tbl_no],
    +                    entropy->ac_count_ptrs[compptr->ac_tbl_no]);
    +    entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Generate the best Huffman code table for the given counts, fill htbl.
    + * Note this is also used by jcphuff.c.
    + *
    + * The JPEG standard requires that no symbol be assigned a codeword of all
    + * one bits (so that padding bits added at the end of a compressed segment
    + * can't look like a valid code).  Because of the canonical ordering of
    + * codewords, this just means that there must be an unused slot in the
    + * longest codeword length category.  Section K.2 of the JPEG spec suggests
    + * reserving such a slot by pretending that symbol 256 is a valid symbol
    + * with count 1.  In theory that's not optimal; giving it count zero but
    + * including it in the symbol set anyway should give a better Huffman code.
    + * But the theoretically better code actually seems to come out worse in
    + * practice, because it produces more all-ones bytes (which incur stuffed
    + * zero bytes in the final file).  In any case the difference is tiny.
    + *
    + * The JPEG standard requires Huffman codes to be no more than 16 bits long.
    + * If some symbols have a very small but nonzero probability, the Huffman tree
    + * must be adjusted to meet the code length restriction.  We currently use
    + * the adjustment method suggested in JPEG section K.2.  This method is *not*
    + * optimal; it may not choose the best possible limited-length code.  But
    + * typically only very-low-frequency symbols will be given less-than-optimal
    + * lengths, so the code is almost optimal.  Experimental comparisons against
    + * an optimal limited-length-code algorithm indicate that the difference is
    + * microscopic --- usually less than a hundredth of a percent of total size.
    + * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
    + */
    +
    +GLOBAL(void)
    +jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
    +{
    +#define MAX_CLEN 32             /* assumed maximum initial code length */
    +  UINT8 bits[MAX_CLEN+1];       /* bits[k] = # of symbols with code length k */
    +  int codesize[257];            /* codesize[k] = code length of symbol k */
    +  int others[257];              /* next symbol in current branch of tree */
    +  int c1, c2;
    +  int p, i, j;
    +  long v;
    +
    +  /* This algorithm is explained in section K.2 of the JPEG standard */
    +
    +  MEMZERO(bits, SIZEOF(bits));
    +  MEMZERO(codesize, SIZEOF(codesize));
    +  for (i = 0; i < 257; i++)
    +    others[i] = -1;             /* init links to empty */
    +
    +  freq[256] = 1;                /* make sure 256 has a nonzero count */
    +  /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
    +   * that no real symbol is given code-value of all ones, because 256
    +   * will be placed last in the largest codeword category.
    +   */
    +
    +  /* Huffman's basic algorithm to assign optimal code lengths to symbols */
    +
    +  for (;;) {
    +    /* Find the smallest nonzero frequency, set c1 = its symbol */
    +    /* In case of ties, take the larger symbol number */
    +    c1 = -1;
    +    v = 1000000000L;
    +    for (i = 0; i <= 256; i++) {
    +      if (freq[i] && freq[i] <= v) {
    +        v = freq[i];
    +        c1 = i;
    +      }
    +    }
    +
    +    /* Find the next smallest nonzero frequency, set c2 = its symbol */
    +    /* In case of ties, take the larger symbol number */
    +    c2 = -1;
    +    v = 1000000000L;
    +    for (i = 0; i <= 256; i++) {
    +      if (freq[i] && freq[i] <= v && i != c1) {
    +        v = freq[i];
    +        c2 = i;
    +      }
    +    }
    +
    +    /* Done if we've merged everything into one frequency */
    +    if (c2 < 0)
    +      break;
    +
    +    /* Else merge the two counts/trees */
    +    freq[c1] += freq[c2];
    +    freq[c2] = 0;
    +
    +    /* Increment the codesize of everything in c1's tree branch */
    +    codesize[c1]++;
    +    while (others[c1] >= 0) {
    +      c1 = others[c1];
    +      codesize[c1]++;
    +    }
    +
    +    others[c1] = c2;            /* chain c2 onto c1's tree branch */
    +
    +    /* Increment the codesize of everything in c2's tree branch */
    +    codesize[c2]++;
    +    while (others[c2] >= 0) {
    +      c2 = others[c2];
    +      codesize[c2]++;
    +    }
    +  }
    +
    +  /* Now count the number of symbols of each code length */
    +  for (i = 0; i <= 256; i++) {
    +    if (codesize[i]) {
    +      /* The JPEG standard seems to think that this can't happen, */
    +      /* but I'm paranoid... */
    +      if (codesize[i] > MAX_CLEN)
    +        ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
    +
    +      bits[codesize[i]]++;
    +    }
    +  }
    +
    +  /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
    +   * Huffman procedure assigned any such lengths, we must adjust the coding.
    +   * Here is what the JPEG spec says about how this next bit works:
    +   * Since symbols are paired for the longest Huffman code, the symbols are
    +   * removed from this length category two at a time.  The prefix for the pair
    +   * (which is one bit shorter) is allocated to one of the pair; then,
    +   * skipping the BITS entry for that prefix length, a code word from the next
    +   * shortest nonzero BITS entry is converted into a prefix for two code words
    +   * one bit longer.
    +   */
    +
    +  for (i = MAX_CLEN; i > 16; i--) {
    +    while (bits[i] > 0) {
    +      j = i - 2;                /* find length of new prefix to be used */
    +      while (bits[j] == 0) {
    +        if (j == 0)
    +          ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
    +        j--;
    +      }
    +
    +      bits[i] -= 2;             /* remove two symbols */
    +      bits[i-1]++;              /* one goes in this length */
    +      bits[j+1] += 2;           /* two new symbols in this length */
    +      bits[j]--;                /* symbol of this length is now a prefix */
    +    }
    +  }
    +
    +  /* Remove the count for the pseudo-symbol 256 from the largest codelength */
    +  while (bits[i] == 0)          /* find largest codelength still in use */
    +    i--;
    +  bits[i]--;
    +
    +  /* Return final symbol counts (only for lengths 0..16) */
    +  MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
    +
    +  /* Return a list of the symbols sorted by code length */
    +  /* It's not real clear to me why we don't need to consider the codelength
    +   * changes made above, but the JPEG spec seems to think this works.
    +   */
    +  p = 0;
    +  for (i = 1; i <= MAX_CLEN; i++) {
    +    for (j = 0; j <= 255; j++) {
    +      if (codesize[j] == i) {
    +        htbl->huffval[p] = (UINT8) j;
    +        p++;
    +      }
    +    }
    +  }
    +
    +  /* Set sent_table FALSE so updated table will be written to JPEG file. */
    +  htbl->sent_table = FALSE;
    +}
    +
    +
    +/*
    + * Finish up a statistics-gathering pass and create the new Huffman tables.
    + */
    +
    +METHODDEF(void)
    +finish_pass_gather (j_compress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int ci, dctbl, actbl;
    +  jpeg_component_info * compptr;
    +  JHUFF_TBL **htblptr;
    +  boolean did_dc[NUM_HUFF_TBLS];
    +  boolean did_ac[NUM_HUFF_TBLS];
    +
    +  /* It's important not to apply jpeg_gen_optimal_table more than once
    +   * per table, because it clobbers the input frequency counts!
    +   */
    +  MEMZERO(did_dc, SIZEOF(did_dc));
    +  MEMZERO(did_ac, SIZEOF(did_ac));
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    dctbl = compptr->dc_tbl_no;
    +    actbl = compptr->ac_tbl_no;
    +    if (! did_dc[dctbl]) {
    +      htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
    +      if (*htblptr == NULL)
    +        *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
    +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
    +      did_dc[dctbl] = TRUE;
    +    }
    +    if (! did_ac[actbl]) {
    +      htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
    +      if (*htblptr == NULL)
    +        *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
    +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
    +      did_ac[actbl] = TRUE;
    +    }
    +  }
    +}
    +
    +
    +#endif /* ENTROPY_OPT_SUPPORTED */
    +
    +
    +/*
    + * Module initialization routine for Huffman entropy encoding.
    + */
    +
    +GLOBAL(void)
    +jinit_huff_encoder (j_compress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy;
    +  int i;
    +
    +  entropy = (huff_entropy_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(huff_entropy_encoder));
    +  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
    +  entropy->pub.start_pass = start_pass_huff;
    +
    +  /* Mark tables unallocated */
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
    +#ifdef ENTROPY_OPT_SUPPORTED
    +    entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
    +#endif
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jchuff.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jchuff.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jchuff.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jchuff.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,51 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jchuff.h
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains declarations for Huffman entropy encoding routines
    + * that are shared between the sequential encoder (jchuff.c) and the
    + * progressive encoder (jcphuff.c).  No other modules need to see these.
    + */
    +
    +/* The legal range of a DCT coefficient is
    + *  -1024 .. +1023  for 8-bit data;
    + * -16384 .. +16383 for 12-bit data.
    + * Hence the magnitude should always fit in 10 or 14 bits respectively.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define MAX_COEF_BITS 10
    +#else
    +#define MAX_COEF_BITS 14
    +#endif
    +
    +/* Derived data constructed for each Huffman table */
    +
    +typedef struct {
    +  unsigned int ehufco[256];     /* code for each symbol */
    +  char ehufsi[256];             /* length of code for each symbol */
    +  /* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
    +} c_derived_tbl;
    +
    +/* Short forms of external names for systems with brain-damaged linkers. */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_make_c_derived_tbl jMkCDerived
    +#define jpeg_gen_optimal_table  jGenOptTbl
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +/* Expand a Huffman table definition into the derived format */
    +EXTERN(void) jpeg_make_c_derived_tbl
    +        JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
    +             c_derived_tbl ** pdtbl));
    +
    +/* Generate an optimal table definition given the specified counts */
    +EXTERN(void) jpeg_gen_optimal_table
    +        JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcinit.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcinit.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcinit.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcinit.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,76 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcinit.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains initialization logic for the JPEG compressor.
    + * This routine is in charge of selecting the modules to be executed and
    + * making an initialization call to each one.
    + *
    + * Logically, this code belongs in jcmaster.c.  It's split out because
    + * linking this routine implies linking the entire compression library.
    + * For a transcoding-only application, we want to be able to use jcmaster.c
    + * without linking in the whole library.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Master selection of compression modules.
    + * This is done once at the start of processing an image.  We determine
    + * which modules will be used and give them appropriate initialization calls.
    + */
    +
    +GLOBAL(void)
    +jinit_compress_master (j_compress_ptr cinfo)
    +{
    +  /* Initialize master control (includes parameter checking/processing) */
    +  jinit_c_master_control(cinfo, FALSE /* full compression */);
    +
    +  /* Preprocessing */
    +  if (! cinfo->raw_data_in) {
    +    jinit_color_converter(cinfo);
    +    jinit_downsampler(cinfo);
    +    jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
    +  }
    +  /* Forward DCT */
    +  jinit_forward_dct(cinfo);
    +  /* Entropy encoding: either Huffman or arithmetic coding. */
    +  if (cinfo->arith_code) {
    +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
    +  } else {
    +    if (cinfo->progressive_mode) {
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +      jinit_phuff_encoder(cinfo);
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    } else
    +      jinit_huff_encoder(cinfo);
    +  }
    +
    +  /* Need a full-image coefficient buffer in any multi-pass mode. */
    +  jinit_c_coef_controller(cinfo,
    +                (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
    +  jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
    +
    +  jinit_marker_writer(cinfo);
    +
    +  /* We can now tell the memory manager to allocate virtual arrays. */
    +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
    +
    +  /* Write the datastream header (SOI) immediately.
    +   * Frame and scan headers are postponed till later.
    +   * This lets application insert special markers after the SOI.
    +   */
    +  (*cinfo->marker->write_file_header) (cinfo);
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmainct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmainct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmainct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmainct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,297 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcmainct.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the main buffer controller for compression.
    + * The main buffer lies between the pre-processor and the JPEG
    + * compressor proper; it holds downsampled data in the JPEG colorspace.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Note: currently, there is no operating mode in which a full-image buffer
    + * is needed at this step.  If there were, that mode could not be used with
    + * "raw data" input, since this module is bypassed in that case.  However,
    + * we've left the code here for possible use in special applications.
    + */
    +#undef FULL_MAIN_BUFFER_SUPPORTED
    +
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_c_main_controller pub; /* public fields */
    +
    +  JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
    +  JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
    +  boolean suspended;            /* remember if we suspended output */
    +  J_BUF_MODE pass_mode;         /* current operating mode */
    +
    +  /* If using just a strip buffer, this points to the entire set of buffers
    +   * (we allocate one for each component).  In the full-image case, this
    +   * points to the currently accessible strips of the virtual arrays.
    +   */
    +  JSAMPARRAY buffer[MAX_COMPONENTS];
    +
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +  /* If using full-image storage, this array holds pointers to virtual-array
    +   * control blocks for each component.  Unused if not full-image storage.
    +   */
    +  jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
    +#endif
    +} my_main_controller;
    +
    +typedef my_main_controller * my_main_ptr;
    +
    +
    +/* Forward declarations */
    +METHODDEF(void) process_data_simple_main
    +        JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
    +             JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +METHODDEF(void) process_data_buffer_main
    +        JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
    +             JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
    +#endif
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +
    +  /* Do nothing in raw-data mode. */
    +  if (cinfo->raw_data_in)
    +    return;
    +
    +  _main->cur_iMCU_row = 0;      /* initialize counters */
    +  _main->rowgroup_ctr = 0;
    +  _main->suspended = FALSE;
    +  _main->pass_mode = pass_mode; /* save mode for use by process_data */
    +
    +  switch (pass_mode) {
    +  case JBUF_PASS_THRU:
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +    if (_main->whole_image[0] != NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +#endif
    +    _main->pub.process_data = process_data_simple_main;
    +    break;
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +  case JBUF_SAVE_SOURCE:
    +  case JBUF_CRANK_DEST:
    +  case JBUF_SAVE_AND_PASS:
    +    if (_main->whole_image[0] == NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    _main->pub.process_data = process_data_buffer_main;
    +    break;
    +#endif
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    break;
    +  }
    +}
    +
    +
    +/*
    + * Process some data.
    + * This routine handles the simple pass-through mode,
    + * where we have only a strip buffer.
    + */
    +
    +METHODDEF(void)
    +process_data_simple_main (j_compress_ptr cinfo,
    +                          JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
    +                          JDIMENSION in_rows_avail)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +
    +  while (_main->cur_iMCU_row < cinfo->total_iMCU_rows) {
    +    /* Read input data if we haven't filled the main buffer yet */
    +    if (_main->rowgroup_ctr < DCTSIZE)
    +      (*cinfo->prep->pre_process_data) (cinfo,
    +                                        input_buf, in_row_ctr, in_rows_avail,
    +                                        _main->buffer, &_main->rowgroup_ctr,
    +                                        (JDIMENSION) DCTSIZE);
    +
    +    /* If we don't have a full iMCU row buffered, return to application for
    +     * more data.  Note that preprocessor will always pad to fill the iMCU row
    +     * at the bottom of the image.
    +     */
    +    if (_main->rowgroup_ctr != DCTSIZE)
    +      return;
    +
    +    /* Send the completed row to the compressor */
    +    if (! (*cinfo->coef->compress_data) (cinfo, _main->buffer)) {
    +      /* If compressor did not consume the whole row, then we must need to
    +       * suspend processing and return to the application.  In this situation
    +       * we pretend we didn't yet consume the last input row; otherwise, if
    +       * it happened to be the last row of the image, the application would
    +       * think we were done.
    +       */
    +      if (! _main->suspended) {
    +        (*in_row_ctr)--;
    +        _main->suspended = TRUE;
    +      }
    +      return;
    +    }
    +    /* We did finish the row.  Undo our little suspension hack if a previous
    +     * call suspended; then mark the main buffer empty.
    +     */
    +    if (_main->suspended) {
    +      (*in_row_ctr)++;
    +      _main->suspended = FALSE;
    +    }
    +    _main->rowgroup_ctr = 0;
    +    _main->cur_iMCU_row++;
    +  }
    +}
    +
    +
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +
    +/*
    + * Process some data.
    + * This routine handles all of the modes that use a full-size buffer.
    + */
    +
    +METHODDEF(void)
    +process_data_buffer_main (j_compress_ptr cinfo,
    +                          JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
    +                          JDIMENSION in_rows_avail)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  int ci;
    +  jpeg_component_info *compptr;
    +  boolean writing = (_main->pass_mode != JBUF_CRANK_DEST);
    +
    +  while (_main->cur_iMCU_row < cinfo->total_iMCU_rows) {
    +    /* Realign the virtual buffers if at the start of an iMCU row. */
    +    if (_main->rowgroup_ctr == 0) {
    +      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +           ci++, compptr++) {
    +        _main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
    +          ((j_common_ptr) cinfo, _main->whole_image[ci],
    +           _main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
    +           (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
    +      }
    +      /* In a read pass, pretend we just read some source data. */
    +      if (! writing) {
    +        *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
    +        _main->rowgroup_ctr = DCTSIZE;
    +      }
    +    }
    +
    +    /* If a write pass, read input data until the current iMCU row is full. */
    +    /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
    +    if (writing) {
    +      (*cinfo->prep->pre_process_data) (cinfo,
    +                                        input_buf, in_row_ctr, in_rows_avail,
    +                                        _main->buffer, &_main->rowgroup_ctr,
    +                                        (JDIMENSION) DCTSIZE);
    +      /* Return to application if we need more data to fill the iMCU row. */
    +      if (_main->rowgroup_ctr < DCTSIZE)
    +        return;
    +    }
    +
    +    /* Emit data, unless this is a sink-only pass. */
    +    if (_main->pass_mode != JBUF_SAVE_SOURCE) {
    +      if (! (*cinfo->coef->compress_data) (cinfo, _main->buffer)) {
    +        /* If compressor did not consume the whole row, then we must need to
    +         * suspend processing and return to the application.  In this situation
    +         * we pretend we didn't yet consume the last input row; otherwise, if
    +         * it happened to be the last row of the image, the application would
    +         * think we were done.
    +         */
    +        if (! _main->suspended) {
    +          (*in_row_ctr)--;
    +          _main->suspended = TRUE;
    +        }
    +        return;
    +      }
    +      /* We did finish the row.  Undo our little suspension hack if a previous
    +       * call suspended; then mark the main buffer empty.
    +       */
    +      if (_main->suspended) {
    +        (*in_row_ctr)++;
    +        _main->suspended = FALSE;
    +      }
    +    }
    +
    +    /* If get here, we are done with this iMCU row.  Mark buffer empty. */
    +    _main->rowgroup_ctr = 0;
    +    _main->cur_iMCU_row++;
    +  }
    +}
    +
    +#endif /* FULL_MAIN_BUFFER_SUPPORTED */
    +
    +
    +/*
    + * Initialize main buffer controller.
    + */
    +
    +GLOBAL(void)
    +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_main_ptr _main;
    +  int ci;
    +  jpeg_component_info *compptr;
    +
    +  _main = (my_main_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_main_controller));
    +  cinfo->main = (struct jpeg_c_main_controller *) _main;
    +  _main->pub.start_pass = start_pass_main;
    +
    +  /* We don't need to create a buffer in raw-data mode. */
    +  if (cinfo->raw_data_in)
    +    return;
    +
    +  /* Create the buffer.  It holds downsampled data, so each component
    +   * may be of a different size.
    +   */
    +  if (need_full_buffer) {
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +    /* Allocate a full-image virtual array for each component */
    +    /* Note we pad the bottom to a multiple of the iMCU height */
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      _main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
    +         compptr->width_in_blocks * DCTSIZE,
    +         (JDIMENSION) jround_up((long) compptr->height_in_blocks,
    +                                (long) compptr->v_samp_factor) * DCTSIZE,
    +         (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
    +    }
    +#else
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +#endif
    +  } else {
    +#ifdef FULL_MAIN_BUFFER_SUPPORTED
    +    _main->whole_image[0] = NULL; /* flag for no virtual arrays */
    +#endif
    +    /* Allocate a strip buffer for each component */
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      _main->buffer[ci] = (*cinfo->mem->alloc_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +         compptr->width_in_blocks * DCTSIZE,
    +         (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
    +    }
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmarker.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmarker.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmarker.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmarker.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,682 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcmarker.c
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains routines to write JPEG datastream markers.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +typedef enum {                  /* JPEG marker codes */
    +  M_SOF0  = 0xc0,
    +  M_SOF1  = 0xc1,
    +  M_SOF2  = 0xc2,
    +  M_SOF3  = 0xc3,
    +
    +  M_SOF5  = 0xc5,
    +  M_SOF6  = 0xc6,
    +  M_SOF7  = 0xc7,
    +
    +  M_JPG   = 0xc8,
    +  M_SOF9  = 0xc9,
    +  M_SOF10 = 0xca,
    +  M_SOF11 = 0xcb,
    +
    +  M_SOF13 = 0xcd,
    +  M_SOF14 = 0xce,
    +  M_SOF15 = 0xcf,
    +
    +  M_DHT   = 0xc4,
    +
    +  M_DAC   = 0xcc,
    +
    +  M_RST0  = 0xd0,
    +  M_RST1  = 0xd1,
    +  M_RST2  = 0xd2,
    +  M_RST3  = 0xd3,
    +  M_RST4  = 0xd4,
    +  M_RST5  = 0xd5,
    +  M_RST6  = 0xd6,
    +  M_RST7  = 0xd7,
    +
    +  M_SOI   = 0xd8,
    +  M_EOI   = 0xd9,
    +  M_SOS   = 0xda,
    +  M_DQT   = 0xdb,
    +  M_DNL   = 0xdc,
    +  M_DRI   = 0xdd,
    +  M_DHP   = 0xde,
    +  M_EXP   = 0xdf,
    +
    +  M_APP0  = 0xe0,
    +  M_APP1  = 0xe1,
    +  M_APP2  = 0xe2,
    +  M_APP3  = 0xe3,
    +  M_APP4  = 0xe4,
    +  M_APP5  = 0xe5,
    +  M_APP6  = 0xe6,
    +  M_APP7  = 0xe7,
    +  M_APP8  = 0xe8,
    +  M_APP9  = 0xe9,
    +  M_APP10 = 0xea,
    +  M_APP11 = 0xeb,
    +  M_APP12 = 0xec,
    +  M_APP13 = 0xed,
    +  M_APP14 = 0xee,
    +  M_APP15 = 0xef,
    +
    +  M_JPG0  = 0xf0,
    +  M_JPG13 = 0xfd,
    +  M_COM   = 0xfe,
    +
    +  M_TEM   = 0x01,
    +
    +  M_ERROR = 0x100
    +} JPEG_MARKER;
    +
    +
    +/* Private state */
    +
    +typedef struct {
    +  struct jpeg_marker_writer pub; /* public fields */
    +
    +  unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
    +} my_marker_writer;
    +
    +typedef my_marker_writer * my_marker_ptr;
    +
    +
    +/*
    + * Basic output routines.
    + *
    + * Note that we do not support suspension while writing a marker.
    + * Therefore, an application using suspension must ensure that there is
    + * enough buffer space for the initial markers (typ. 600-700 bytes) before
    + * calling jpeg_start_compress, and enough space to write the trailing EOI
    + * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
    + * modes are not supported at all with suspension, so those two are the only
    + * points where markers will be written.
    + */
    +
    +LOCAL(void)
    +emit_byte (j_compress_ptr cinfo, int val)
    +/* Emit a byte */
    +{
    +  struct jpeg_destination_mgr * dest = cinfo->dest;
    +
    +  *(dest->next_output_byte)++ = (JOCTET) val;
    +  if (--dest->free_in_buffer == 0) {
    +    if (! (*dest->empty_output_buffer) (cinfo))
    +      ERREXIT(cinfo, JERR_CANT_SUSPEND);
    +  }
    +}
    +
    +
    +LOCAL(void)
    +emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
    +/* Emit a marker code */
    +{
    +  emit_byte(cinfo, 0xFF);
    +  emit_byte(cinfo, (int) mark);
    +}
    +
    +
    +LOCAL(void)
    +emit_2bytes (j_compress_ptr cinfo, int value)
    +/* Emit a 2-byte integer; these are always MSB first in JPEG files */
    +{
    +  emit_byte(cinfo, (value >> 8) & 0xFF);
    +  emit_byte(cinfo, value & 0xFF);
    +}
    +
    +
    +/*
    + * Routines to write specific marker types.
    + */
    +
    +LOCAL(int)
    +emit_dqt (j_compress_ptr cinfo, int index)
    +/* Emit a DQT marker */
    +/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
    +{
    +  JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
    +  int prec;
    +  int i;
    +
    +  if (qtbl == NULL)
    +    ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
    +
    +  prec = 0;
    +  for (i = 0; i < DCTSIZE2; i++) {
    +    if (qtbl->quantval[i] > 255)
    +      prec = 1;
    +  }
    +
    +  if (! qtbl->sent_table) {
    +    emit_marker(cinfo, M_DQT);
    +
    +    emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
    +
    +    emit_byte(cinfo, index + (prec<<4));
    +
    +    for (i = 0; i < DCTSIZE2; i++) {
    +      /* The table entries must be emitted in zigzag order. */
    +      unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
    +      if (prec)
    +        emit_byte(cinfo, (int) (qval >> 8));
    +      emit_byte(cinfo, (int) (qval & 0xFF));
    +    }
    +
    +    qtbl->sent_table = TRUE;
    +  }
    +
    +  return prec;
    +}
    +
    +
    +LOCAL(void)
    +emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
    +/* Emit a DHT marker */
    +{
    +  JHUFF_TBL * htbl;
    +  int length, i;
    +
    +  if (is_ac) {
    +    htbl = cinfo->ac_huff_tbl_ptrs[index];
    +    index += 0x10;              /* output index has AC bit set */
    +  } else {
    +    htbl = cinfo->dc_huff_tbl_ptrs[index];
    +  }
    +
    +  if (htbl == NULL)
    +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
    +
    +  if (! htbl->sent_table) {
    +    emit_marker(cinfo, M_DHT);
    +
    +    length = 0;
    +    for (i = 1; i <= 16; i++)
    +      length += htbl->bits[i];
    +
    +    emit_2bytes(cinfo, length + 2 + 1 + 16);
    +    emit_byte(cinfo, index);
    +
    +    for (i = 1; i <= 16; i++)
    +      emit_byte(cinfo, htbl->bits[i]);
    +
    +    for (i = 0; i < length; i++)
    +      emit_byte(cinfo, htbl->huffval[i]);
    +
    +    htbl->sent_table = TRUE;
    +  }
    +}
    +
    +
    +LOCAL(void)
    +emit_dac (j_compress_ptr cinfo)
    +/* Emit a DAC marker */
    +/* Since the useful info is so small, we want to emit all the tables in */
    +/* one DAC marker.  Therefore this routine does its own scan of the table. */
    +{
    +#ifdef C_ARITH_CODING_SUPPORTED
    +  char dc_in_use[NUM_ARITH_TBLS];
    +  char ac_in_use[NUM_ARITH_TBLS];
    +  int length, i;
    +  jpeg_component_info *compptr;
    +
    +  for (i = 0; i < NUM_ARITH_TBLS; i++)
    +    dc_in_use[i] = ac_in_use[i] = 0;
    +
    +  for (i = 0; i < cinfo->comps_in_scan; i++) {
    +    compptr = cinfo->cur_comp_info[i];
    +    dc_in_use[compptr->dc_tbl_no] = 1;
    +    ac_in_use[compptr->ac_tbl_no] = 1;
    +  }
    +
    +  length = 0;
    +  for (i = 0; i < NUM_ARITH_TBLS; i++)
    +    length += dc_in_use[i] + ac_in_use[i];
    +
    +  emit_marker(cinfo, M_DAC);
    +
    +  emit_2bytes(cinfo, length*2 + 2);
    +
    +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
    +    if (dc_in_use[i]) {
    +      emit_byte(cinfo, i);
    +      emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
    +    }
    +    if (ac_in_use[i]) {
    +      emit_byte(cinfo, i + 0x10);
    +      emit_byte(cinfo, cinfo->arith_ac_K[i]);
    +    }
    +  }
    +#endif /* C_ARITH_CODING_SUPPORTED */
    +}
    +
    +
    +LOCAL(void)
    +emit_dri (j_compress_ptr cinfo)
    +/* Emit a DRI marker */
    +{
    +  emit_marker(cinfo, M_DRI);
    +
    +  emit_2bytes(cinfo, 4);        /* fixed length */
    +
    +  emit_2bytes(cinfo, (int) cinfo->restart_interval);
    +}
    +
    +
    +LOCAL(void)
    +emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
    +/* Emit a SOF marker */
    +{
    +  int ci;
    +  jpeg_component_info *compptr;
    +
    +  emit_marker(cinfo, code);
    +
    +  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
    +
    +  /* Make sure image isn't bigger than SOF field can handle */
    +  if ((long) cinfo->image_height > 65535L ||
    +      (long) cinfo->image_width > 65535L)
    +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
    +
    +  emit_byte(cinfo, cinfo->data_precision);
    +  emit_2bytes(cinfo, (int) cinfo->image_height);
    +  emit_2bytes(cinfo, (int) cinfo->image_width);
    +
    +  emit_byte(cinfo, cinfo->num_components);
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    emit_byte(cinfo, compptr->component_id);
    +    emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
    +    emit_byte(cinfo, compptr->quant_tbl_no);
    +  }
    +}
    +
    +
    +LOCAL(void)
    +emit_sos (j_compress_ptr cinfo)
    +/* Emit a SOS marker */
    +{
    +  int i, td, ta;
    +  jpeg_component_info *compptr;
    +
    +  emit_marker(cinfo, M_SOS);
    +
    +  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
    +
    +  emit_byte(cinfo, cinfo->comps_in_scan);
    +
    +  for (i = 0; i < cinfo->comps_in_scan; i++) {
    +    compptr = cinfo->cur_comp_info[i];
    +    emit_byte(cinfo, compptr->component_id);
    +    td = compptr->dc_tbl_no;
    +    ta = compptr->ac_tbl_no;
    +    if (cinfo->progressive_mode) {
    +      /* Progressive mode: only DC or only AC tables are used in one scan;
    +       * furthermore, Huffman coding of DC refinement uses no table at all.
    +       * We emit 0 for unused field(s); this is recommended by the P&M text
    +       * but does not seem to be specified in the standard.
    +       */
    +      if (cinfo->Ss == 0) {
    +        ta = 0;                 /* DC scan */
    +        if (cinfo->Ah != 0 && !cinfo->arith_code)
    +          td = 0;               /* no DC table either */
    +      } else {
    +        td = 0;                 /* AC scan */
    +      }
    +    }
    +    emit_byte(cinfo, (td << 4) + ta);
    +  }
    +
    +  emit_byte(cinfo, cinfo->Ss);
    +  emit_byte(cinfo, cinfo->Se);
    +  emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
    +}
    +
    +
    +LOCAL(void)
    +emit_jfif_app0 (j_compress_ptr cinfo)
    +/* Emit a JFIF-compliant APP0 marker */
    +{
    +  /*
    +   * Length of APP0 block       (2 bytes)
    +   * Block ID                   (4 bytes - ASCII "JFIF")
    +   * Zero byte                  (1 byte to terminate the ID string)
    +   * Version Major, Minor       (2 bytes - major first)
    +   * Units                      (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
    +   * Xdpu                       (2 bytes - dots per unit horizontal)
    +   * Ydpu                       (2 bytes - dots per unit vertical)
    +   * Thumbnail X size           (1 byte)
    +   * Thumbnail Y size           (1 byte)
    +   */
    +
    +  emit_marker(cinfo, M_APP0);
    +
    +  emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
    +
    +  emit_byte(cinfo, 0x4A);       /* Identifier: ASCII "JFIF" */
    +  emit_byte(cinfo, 0x46);
    +  emit_byte(cinfo, 0x49);
    +  emit_byte(cinfo, 0x46);
    +  emit_byte(cinfo, 0);
    +  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
    +  emit_byte(cinfo, cinfo->JFIF_minor_version);
    +  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
    +  emit_2bytes(cinfo, (int) cinfo->X_density);
    +  emit_2bytes(cinfo, (int) cinfo->Y_density);
    +  emit_byte(cinfo, 0);          /* No thumbnail image */
    +  emit_byte(cinfo, 0);
    +}
    +
    +
    +LOCAL(void)
    +emit_adobe_app14 (j_compress_ptr cinfo)
    +/* Emit an Adobe APP14 marker */
    +{
    +  /*
    +   * Length of APP14 block      (2 bytes)
    +   * Block ID                   (5 bytes - ASCII "Adobe")
    +   * Version Number             (2 bytes - currently 100)
    +   * Flags0                     (2 bytes - currently 0)
    +   * Flags1                     (2 bytes - currently 0)
    +   * Color transform            (1 byte)
    +   *
    +   * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
    +   * now in circulation seem to use Version = 100, so that's what we write.
    +   *
    +   * We write the color transform byte as 1 if the JPEG color space is
    +   * YCbCr, 2 if it's YCCK, 0 otherwise.  Adobe's definition has to do with
    +   * whether the encoder performed a transformation, which is pretty useless.
    +   */
    +
    +  emit_marker(cinfo, M_APP14);
    +
    +  emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
    +
    +  emit_byte(cinfo, 0x41);       /* Identifier: ASCII "Adobe" */
    +  emit_byte(cinfo, 0x64);
    +  emit_byte(cinfo, 0x6F);
    +  emit_byte(cinfo, 0x62);
    +  emit_byte(cinfo, 0x65);
    +  emit_2bytes(cinfo, 100);      /* Version */
    +  emit_2bytes(cinfo, 0);        /* Flags0 */
    +  emit_2bytes(cinfo, 0);        /* Flags1 */
    +  switch (cinfo->jpeg_color_space) {
    +  case JCS_YCbCr:
    +    emit_byte(cinfo, 1);        /* Color transform = 1 */
    +    break;
    +  case JCS_YCCK:
    +    emit_byte(cinfo, 2);        /* Color transform = 2 */
    +    break;
    +  default:
    +    emit_byte(cinfo, 0);        /* Color transform = 0 */
    +    break;
    +  }
    +}
    +
    +
    +/*
    + * These routines allow writing an arbitrary marker with parameters.
    + * The only intended use is to emit COM or APPn markers after calling
    + * write_file_header and before calling write_frame_header.
    + * Other uses are not guaranteed to produce desirable results.
    + * Counting the parameter bytes properly is the caller's responsibility.
    + */
    +
    +METHODDEF(void)
    +write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
    +/* Emit an arbitrary marker header */
    +{
    +  if (datalen > (unsigned int) 65533)           /* safety check */
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  emit_marker(cinfo, (JPEG_MARKER) marker);
    +
    +  emit_2bytes(cinfo, (int) (datalen + 2));      /* total length */
    +}
    +
    +METHODDEF(void)
    +write_marker_byte (j_compress_ptr cinfo, int val)
    +/* Emit one byte of marker parameters following write_marker_header */
    +{
    +  emit_byte(cinfo, val);
    +}
    +
    +
    +/*
    + * Write datastream header.
    + * This consists of an SOI and optional APPn markers.
    + * We recommend use of the JFIF marker, but not the Adobe marker,
    + * when using YCbCr or grayscale data.  The JFIF marker should NOT
    + * be used for any other JPEG colorspace.  The Adobe marker is helpful
    + * to distinguish RGB, CMYK, and YCCK colorspaces.
    + * Note that an application can write additional header markers after
    + * jpeg_start_compress returns.
    + */
    +
    +METHODDEF(void)
    +write_file_header (j_compress_ptr cinfo)
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +
    +  emit_marker(cinfo, M_SOI);    /* first the SOI */
    +
    +  /* SOI is defined to reset restart interval to 0 */
    +  marker->last_restart_interval = 0;
    +
    +  if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
    +    emit_jfif_app0(cinfo);
    +  if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
    +    emit_adobe_app14(cinfo);
    +}
    +
    +
    +/*
    + * Write frame header.
    + * This consists of DQT and SOFn markers.
    + * Note that we do not emit the SOF until we have emitted the DQT(s).
    + * This avoids compatibility problems with incorrect implementations that
    + * try to error-check the quant table numbers as soon as they see the SOF.
    + */
    +
    +METHODDEF(void)
    +write_frame_header (j_compress_ptr cinfo)
    +{
    +  int ci, prec;
    +  boolean is_baseline;
    +  jpeg_component_info *compptr;
    +
    +  /* Emit DQT for each quantization table.
    +   * Note that emit_dqt() suppresses any duplicate tables.
    +   */
    +  prec = 0;
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    prec += emit_dqt(cinfo, compptr->quant_tbl_no);
    +  }
    +  /* now prec is nonzero iff there are any 16-bit quant tables. */
    +
    +  /* Check for a non-baseline specification.
    +   * Note we assume that Huffman table numbers won't be changed later.
    +   */
    +  if (cinfo->arith_code || cinfo->progressive_mode ||
    +      cinfo->data_precision != 8) {
    +    is_baseline = FALSE;
    +  } else {
    +    is_baseline = TRUE;
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
    +        is_baseline = FALSE;
    +    }
    +    if (prec && is_baseline) {
    +      is_baseline = FALSE;
    +      /* If it's baseline except for quantizer size, warn the user */
    +      TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
    +    }
    +  }
    +
    +  /* Emit the proper SOF marker */
    +  if (cinfo->arith_code) {
    +    emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
    +  } else {
    +    if (cinfo->progressive_mode)
    +      emit_sof(cinfo, M_SOF2);  /* SOF code for progressive Huffman */
    +    else if (is_baseline)
    +      emit_sof(cinfo, M_SOF0);  /* SOF code for baseline implementation */
    +    else
    +      emit_sof(cinfo, M_SOF1);  /* SOF code for non-baseline Huffman file */
    +  }
    +}
    +
    +
    +/*
    + * Write scan header.
    + * This consists of DHT or DAC markers, optional DRI, and SOS.
    + * Compressed data will be written following the SOS.
    + */
    +
    +METHODDEF(void)
    +write_scan_header (j_compress_ptr cinfo)
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +  int i;
    +  jpeg_component_info *compptr;
    +
    +  if (cinfo->arith_code) {
    +    /* Emit arith conditioning info.  We may have some duplication
    +     * if the file has multiple scans, but it's so small it's hardly
    +     * worth worrying about.
    +     */
    +    emit_dac(cinfo);
    +  } else {
    +    /* Emit Huffman tables.
    +     * Note that emit_dht() suppresses any duplicate tables.
    +     */
    +    for (i = 0; i < cinfo->comps_in_scan; i++) {
    +      compptr = cinfo->cur_comp_info[i];
    +      if (cinfo->progressive_mode) {
    +        /* Progressive mode: only DC or only AC tables are used in one scan */
    +        if (cinfo->Ss == 0) {
    +          if (cinfo->Ah == 0)   /* DC needs no table for refinement scan */
    +            emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
    +        } else {
    +          emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
    +        }
    +      } else {
    +        /* Sequential mode: need both DC and AC tables */
    +        emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
    +        emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
    +      }
    +    }
    +  }
    +
    +  /* Emit DRI if required --- note that DRI value could change for each scan.
    +   * We avoid wasting space with unnecessary DRIs, however.
    +   */
    +  if (cinfo->restart_interval != marker->last_restart_interval) {
    +    emit_dri(cinfo);
    +    marker->last_restart_interval = cinfo->restart_interval;
    +  }
    +
    +  emit_sos(cinfo);
    +}
    +
    +
    +/*
    + * Write datastream trailer.
    + */
    +
    +METHODDEF(void)
    +write_file_trailer (j_compress_ptr cinfo)
    +{
    +  emit_marker(cinfo, M_EOI);
    +}
    +
    +
    +/*
    + * Write an abbreviated table-specification datastream.
    + * This consists of SOI, DQT and DHT tables, and EOI.
    + * Any table that is defined and not marked sent_table = TRUE will be
    + * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
    + */
    +
    +METHODDEF(void)
    +write_tables_only (j_compress_ptr cinfo)
    +{
    +  int i;
    +
    +  emit_marker(cinfo, M_SOI);
    +
    +  /* Emit DQT for each quantization table.
    +   * Only emit those tables that are actually associated with image components,
    +   * if there are any image components, which will usually not be the case.
    +   * Note that emit_dqt() suppresses any duplicate tables.
    +   */
    +  if (cinfo->num_components > 0) {
    +      int ci;
    +      jpeg_component_info *compptr;
    +      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +           ci++, compptr++) {
    +          (void) emit_dqt(cinfo, compptr->quant_tbl_no);
    +      }
    +  } else {
    +      for (i = 0; i < NUM_QUANT_TBLS; i++) {
    +          if (cinfo->quant_tbl_ptrs[i] != NULL)
    +              (void) emit_dqt(cinfo, i);
    +      }
    +  }
    +
    +  if (! cinfo->arith_code) {
    +    for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +      if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
    +        emit_dht(cinfo, i, FALSE);
    +      if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
    +        emit_dht(cinfo, i, TRUE);
    +    }
    +  }
    +
    +  emit_marker(cinfo, M_EOI);
    +}
    +
    +
    +/*
    + * Initialize the marker writer module.
    + */
    +
    +GLOBAL(void)
    +jinit_marker_writer (j_compress_ptr cinfo)
    +{
    +  my_marker_ptr marker;
    +
    +  /* Create the subobject */
    +  marker = (my_marker_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_marker_writer));
    +  cinfo->marker = (struct jpeg_marker_writer *) marker;
    +  /* Initialize method pointers */
    +  marker->pub.write_file_header = write_file_header;
    +  marker->pub.write_frame_header = write_frame_header;
    +  marker->pub.write_scan_header = write_scan_header;
    +  marker->pub.write_file_trailer = write_file_trailer;
    +  marker->pub.write_tables_only = write_tables_only;
    +  marker->pub.write_marker_header = write_marker_header;
    +  marker->pub.write_marker_byte = write_marker_byte;
    +  /* Initialize private state */
    +  marker->last_restart_interval = 0;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmaster.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmaster.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcmaster.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcmaster.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,594 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcmaster.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains master control logic for the JPEG compressor.
    + * These routines are concerned with parameter validation, initial setup,
    + * and inter-pass control (determining the number of passes and the work
    + * to be done in each pass).
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private state */
    +
    +typedef enum {
    +        main_pass,              /* input data, also do first output step */
    +        huff_opt_pass,          /* Huffman code optimization pass */
    +        output_pass             /* data output pass */
    +} c_pass_type;
    +
    +typedef struct {
    +  struct jpeg_comp_master pub;  /* public fields */
    +
    +  c_pass_type pass_type;        /* the type of the current pass */
    +
    +  int pass_number;              /* # of passes completed */
    +  int total_passes;             /* total # of passes needed */
    +
    +  int scan_number;              /* current index in scan_info[] */
    +} my_comp_master;
    +
    +typedef my_comp_master * my_master_ptr;
    +
    +
    +/*
    + * Support routines that do various essential calculations.
    + */
    +
    +LOCAL(void)
    +initial_setup (j_compress_ptr cinfo)
    +/* Do computations that are needed before master selection phase */
    +{
    +  int ci;
    +  jpeg_component_info *compptr;
    +  long samplesperrow;
    +  JDIMENSION jd_samplesperrow;
    +
    +  /* Sanity check on image dimensions */
    +  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
    +      || cinfo->num_components <= 0 || cinfo->input_components <= 0)
    +    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
    +
    +  /* Make sure image isn't bigger than I can handle */
    +  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
    +      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
    +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
    +
    +  /* Width of an input scanline must be representable as JDIMENSION. */
    +  samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
    +  jd_samplesperrow = (JDIMENSION) samplesperrow;
    +  if ((long) jd_samplesperrow != samplesperrow)
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +
    +  /* For now, precision must match compiled-in value... */
    +  if (cinfo->data_precision != BITS_IN_JSAMPLE)
    +    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    +
    +  /* Check that number of components won't exceed internal array sizes */
    +  if (cinfo->num_components > MAX_COMPONENTS)
    +    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
    +             MAX_COMPONENTS);
    +
    +  /* Compute maximum sampling factors; check factor validity */
    +  cinfo->max_h_samp_factor = 1;
    +  cinfo->max_v_samp_factor = 1;
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
    +        compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
    +      ERREXIT(cinfo, JERR_BAD_SAMPLING);
    +    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
    +                                   compptr->h_samp_factor);
    +    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
    +                                   compptr->v_samp_factor);
    +  }
    +
    +  /* Compute dimensions of components */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Fill in the correct component_index value; don't rely on application */
    +    compptr->component_index = ci;
    +    /* For compression, we never do DCT scaling. */
    +    compptr->DCT_scaled_size = DCTSIZE;
    +    /* Size in DCT blocks */
    +    compptr->width_in_blocks = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
    +                    (long) (cinfo->max_h_samp_factor * DCTSIZE));
    +    compptr->height_in_blocks = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
    +                    (long) (cinfo->max_v_samp_factor * DCTSIZE));
    +    /* Size in samples */
    +    compptr->downsampled_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
    +                    (long) cinfo->max_h_samp_factor);
    +    compptr->downsampled_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
    +                    (long) cinfo->max_v_samp_factor);
    +    /* Mark component needed (this flag isn't actually used for compression) */
    +    compptr->component_needed = TRUE;
    +  }
    +
    +  /* Compute number of fully interleaved MCU rows (number of times that
    +   * main controller will call coefficient controller).
    +   */
    +  cinfo->total_iMCU_rows = (JDIMENSION)
    +    jdiv_round_up((long) cinfo->image_height,
    +                  (long) (cinfo->max_v_samp_factor*DCTSIZE));
    +}
    +
    +
    +#ifdef C_MULTISCAN_FILES_SUPPORTED
    +
    +LOCAL(void)
    +validate_script (j_compress_ptr cinfo)
    +/* Verify that the scan script in cinfo->scan_info[] is valid; also
    + * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
    + */
    +{
    +  const jpeg_scan_info * scanptr;
    +  int scanno, ncomps, ci, coefi, thisi;
    +  int Ss, Se, Ah, Al;
    +  boolean component_sent[MAX_COMPONENTS];
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +  int * last_bitpos_ptr;
    +  int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
    +  /* -1 until that coefficient has been seen; then last Al for it */
    +#endif
    +
    +  if (cinfo->num_scans <= 0)
    +    ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
    +
    +  /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
    +   * for progressive JPEG, no scan can have this.
    +   */
    +  scanptr = cinfo->scan_info;
    +  if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +    cinfo->progressive_mode = TRUE;
    +    last_bitpos_ptr = & last_bitpos[0][0];
    +    for (ci = 0; ci < cinfo->num_components; ci++)
    +      for (coefi = 0; coefi < DCTSIZE2; coefi++)
    +        *last_bitpos_ptr++ = -1;
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +  } else {
    +    cinfo->progressive_mode = FALSE;
    +    for (ci = 0; ci < cinfo->num_components; ci++)
    +      component_sent[ci] = FALSE;
    +  }
    +
    +  for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
    +    /* Validate component indexes */
    +    ncomps = scanptr->comps_in_scan;
    +    if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
    +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
    +    for (ci = 0; ci < ncomps; ci++) {
    +      thisi = scanptr->component_index[ci];
    +      if (thisi < 0 || thisi >= cinfo->num_components)
    +        ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
    +      /* Components must appear in SOF order within each scan */
    +      if (ci > 0 && thisi <= scanptr->component_index[ci-1])
    +        ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
    +    }
    +    /* Validate progression parameters */
    +    Ss = scanptr->Ss;
    +    Se = scanptr->Se;
    +    Ah = scanptr->Ah;
    +    Al = scanptr->Al;
    +    if (cinfo->progressive_mode) {
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +      /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
    +       * seems wrong: the upper bound ought to depend on data precision.
    +       * Perhaps they really meant 0..N+1 for N-bit precision.
    +       * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
    +       * out-of-range reconstructed DC values during the first DC scan,
    +       * which might cause problems for some decoders.
    +       */
    +#if BITS_IN_JSAMPLE == 8
    +#define MAX_AH_AL 10
    +#else
    +#define MAX_AH_AL 13
    +#endif
    +      if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
    +          Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
    +        ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +      if (Ss == 0) {
    +        if (Se != 0)            /* DC and AC together not OK */
    +          ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +      } else {
    +        if (ncomps != 1)        /* AC scans must be for only one component */
    +          ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +      }
    +      for (ci = 0; ci < ncomps; ci++) {
    +        last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
    +        if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
    +          ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +        for (coefi = Ss; coefi <= Se; coefi++) {
    +          if (last_bitpos_ptr[coefi] < 0) {
    +            /* first scan of this coefficient */
    +            if (Ah != 0)
    +              ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +          } else {
    +            /* not first scan */
    +            if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
    +              ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +          }
    +          last_bitpos_ptr[coefi] = Al;
    +        }
    +      }
    +#endif
    +    } else {
    +      /* For sequential JPEG, all progression parameters must be these: */
    +      if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
    +        ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
    +      /* Make sure components are not sent twice */
    +      for (ci = 0; ci < ncomps; ci++) {
    +        thisi = scanptr->component_index[ci];
    +        if (component_sent[thisi])
    +          ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
    +        component_sent[thisi] = TRUE;
    +      }
    +    }
    +  }
    +
    +  /* Now verify that everything got sent. */
    +  if (cinfo->progressive_mode) {
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +    /* For progressive mode, we only check that at least some DC data
    +     * got sent for each component; the spec does not require that all bits
    +     * of all coefficients be transmitted.  Would it be wiser to enforce
    +     * transmission of all coefficient bits??
    +     */
    +    for (ci = 0; ci < cinfo->num_components; ci++) {
    +      if (last_bitpos[ci][0] < 0)
    +        ERREXIT(cinfo, JERR_MISSING_DATA);
    +    }
    +#endif
    +  } else {
    +    for (ci = 0; ci < cinfo->num_components; ci++) {
    +      if (! component_sent[ci])
    +        ERREXIT(cinfo, JERR_MISSING_DATA);
    +    }
    +  }
    +}
    +
    +#endif /* C_MULTISCAN_FILES_SUPPORTED */
    +
    +
    +LOCAL(void)
    +select_scan_parameters (j_compress_ptr cinfo)
    +/* Set up the scan parameters for the current scan */
    +{
    +  int ci;
    +
    +#ifdef C_MULTISCAN_FILES_SUPPORTED
    +  if (cinfo->scan_info != NULL) {
    +    /* Prepare for current scan --- the script is already validated */
    +    my_master_ptr master = (my_master_ptr) cinfo->master;
    +    const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
    +
    +    cinfo->comps_in_scan = scanptr->comps_in_scan;
    +    for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
    +      cinfo->cur_comp_info[ci] =
    +        &cinfo->comp_info[scanptr->component_index[ci]];
    +    }
    +    cinfo->Ss = scanptr->Ss;
    +    cinfo->Se = scanptr->Se;
    +    cinfo->Ah = scanptr->Ah;
    +    cinfo->Al = scanptr->Al;
    +  }
    +  else
    +#endif
    +  {
    +    /* Prepare for single sequential-JPEG scan containing all components */
    +    if (cinfo->num_components > MAX_COMPS_IN_SCAN)
    +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
    +               MAX_COMPS_IN_SCAN);
    +    cinfo->comps_in_scan = cinfo->num_components;
    +    for (ci = 0; ci < cinfo->num_components; ci++) {
    +      cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
    +    }
    +    cinfo->Ss = 0;
    +    cinfo->Se = DCTSIZE2-1;
    +    cinfo->Ah = 0;
    +    cinfo->Al = 0;
    +  }
    +}
    +
    +
    +LOCAL(void)
    +per_scan_setup (j_compress_ptr cinfo)
    +/* Do computations that are needed before processing a JPEG scan */
    +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
    +{
    +  int ci, mcublks, tmp;
    +  jpeg_component_info *compptr;
    +
    +  if (cinfo->comps_in_scan == 1) {
    +
    +    /* Noninterleaved (single-component) scan */
    +    compptr = cinfo->cur_comp_info[0];
    +
    +    /* Overall image size in MCUs */
    +    cinfo->MCUs_per_row = compptr->width_in_blocks;
    +    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
    +
    +    /* For noninterleaved scan, always one block per MCU */
    +    compptr->MCU_width = 1;
    +    compptr->MCU_height = 1;
    +    compptr->MCU_blocks = 1;
    +    compptr->MCU_sample_width = DCTSIZE;
    +    compptr->last_col_width = 1;
    +    /* For noninterleaved scans, it is convenient to define last_row_height
    +     * as the number of block rows present in the last iMCU row.
    +     */
    +    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
    +    if (tmp == 0) tmp = compptr->v_samp_factor;
    +    compptr->last_row_height = tmp;
    +
    +    /* Prepare array describing MCU composition */
    +    cinfo->blocks_in_MCU = 1;
    +    cinfo->MCU_membership[0] = 0;
    +
    +  } else {
    +
    +    /* Interleaved (multi-component) scan */
    +    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
    +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
    +               MAX_COMPS_IN_SCAN);
    +
    +    /* Overall image size in MCUs */
    +    cinfo->MCUs_per_row = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width,
    +                    (long) (cinfo->max_h_samp_factor*DCTSIZE));
    +    cinfo->MCU_rows_in_scan = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height,
    +                    (long) (cinfo->max_v_samp_factor*DCTSIZE));
    +
    +    cinfo->blocks_in_MCU = 0;
    +
    +    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +      compptr = cinfo->cur_comp_info[ci];
    +      /* Sampling factors give # of blocks of component in each MCU */
    +      compptr->MCU_width = compptr->h_samp_factor;
    +      compptr->MCU_height = compptr->v_samp_factor;
    +      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
    +      compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
    +      /* Figure number of non-dummy blocks in last MCU column & row */
    +      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
    +      if (tmp == 0) tmp = compptr->MCU_width;
    +      compptr->last_col_width = tmp;
    +      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
    +      if (tmp == 0) tmp = compptr->MCU_height;
    +      compptr->last_row_height = tmp;
    +      /* Prepare array describing MCU composition */
    +      mcublks = compptr->MCU_blocks;
    +      if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
    +        ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
    +      while (mcublks-- > 0) {
    +        cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
    +      }
    +    }
    +
    +  }
    +
    +  /* Convert restart specified in rows to actual MCU count. */
    +  /* Note that count must fit in 16 bits, so we provide limiting. */
    +  if (cinfo->restart_in_rows > 0) {
    +    long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
    +    cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
    +  }
    +}
    +
    +
    +/*
    + * Per-pass setup.
    + * This is called at the beginning of each pass.  We determine which modules
    + * will be active during this pass and give them appropriate start_pass calls.
    + * We also set is_last_pass to indicate whether any more passes will be
    + * required.
    + */
    +
    +METHODDEF(void)
    +prepare_for_pass (j_compress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +
    +  switch (master->pass_type) {
    +  case main_pass:
    +    /* Initial pass: will collect input data, and do either Huffman
    +     * optimization or data output for the first scan.
    +     */
    +    select_scan_parameters(cinfo);
    +    per_scan_setup(cinfo);
    +    if (! cinfo->raw_data_in) {
    +      (*cinfo->cconvert->start_pass) (cinfo);
    +      (*cinfo->downsample->start_pass) (cinfo);
    +      (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
    +    }
    +    (*cinfo->fdct->start_pass) (cinfo);
    +    (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
    +    (*cinfo->coef->start_pass) (cinfo,
    +                                (master->total_passes > 1 ?
    +                                 JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
    +    (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
    +    if (cinfo->optimize_coding) {
    +      /* No immediate data output; postpone writing frame/scan headers */
    +      master->pub.call_pass_startup = FALSE;
    +    } else {
    +      /* Will write frame/scan headers at first jpeg_write_scanlines call */
    +      master->pub.call_pass_startup = TRUE;
    +    }
    +    break;
    +#ifdef ENTROPY_OPT_SUPPORTED
    +  case huff_opt_pass:
    +    /* Do Huffman optimization for a scan after the first one. */
    +    select_scan_parameters(cinfo);
    +    per_scan_setup(cinfo);
    +    if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
    +      (*cinfo->entropy->start_pass) (cinfo, TRUE);
    +      (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
    +      master->pub.call_pass_startup = FALSE;
    +      break;
    +    }
    +    /* Special case: Huffman DC refinement scans need no Huffman table
    +     * and therefore we can skip the optimization pass for them.
    +     */
    +    master->pass_type = output_pass;
    +    master->pass_number++;
    +    /*FALLTHROUGH*/
    +#endif
    +  case output_pass:
    +    /* Do a data-output pass. */
    +    /* We need not repeat per-scan setup if prior optimization pass did it. */
    +    if (! cinfo->optimize_coding) {
    +      select_scan_parameters(cinfo);
    +      per_scan_setup(cinfo);
    +    }
    +    (*cinfo->entropy->start_pass) (cinfo, FALSE);
    +    (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
    +    /* We emit frame/scan headers now */
    +    if (master->scan_number == 0)
    +      (*cinfo->marker->write_frame_header) (cinfo);
    +    (*cinfo->marker->write_scan_header) (cinfo);
    +    master->pub.call_pass_startup = FALSE;
    +    break;
    +  default:
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +  }
    +
    +  master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
    +
    +  /* Set up progress monitor's pass info if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->completed_passes = master->pass_number;
    +    cinfo->progress->total_passes = master->total_passes;
    +  }
    +}
    +
    +
    +/*
    + * Special start-of-pass hook.
    + * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
    + * In single-pass processing, we need this hook because we don't want to
    + * write frame/scan headers during jpeg_start_compress; we want to let the
    + * application write COM markers etc. between jpeg_start_compress and the
    + * jpeg_write_scanlines loop.
    + * In multi-pass processing, this routine is not used.
    + */
    +
    +METHODDEF(void)
    +pass_startup (j_compress_ptr cinfo)
    +{
    +  cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
    +
    +  (*cinfo->marker->write_frame_header) (cinfo);
    +  (*cinfo->marker->write_scan_header) (cinfo);
    +}
    +
    +
    +/*
    + * Finish up at end of pass.
    + */
    +
    +METHODDEF(void)
    +finish_pass_master (j_compress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +
    +  /* The entropy coder always needs an end-of-pass call,
    +   * either to analyze statistics or to flush its output buffer.
    +   */
    +  (*cinfo->entropy->finish_pass) (cinfo);
    +
    +  /* Update state for next pass */
    +  switch (master->pass_type) {
    +  case main_pass:
    +    /* next pass is either output of scan 0 (after optimization)
    +     * or output of scan 1 (if no optimization).
    +     */
    +    master->pass_type = output_pass;
    +    if (! cinfo->optimize_coding)
    +      master->scan_number++;
    +    break;
    +  case huff_opt_pass:
    +    /* next pass is always output of current scan */
    +    master->pass_type = output_pass;
    +    break;
    +  case output_pass:
    +    /* next pass is either optimization or output of next scan */
    +    if (cinfo->optimize_coding)
    +      master->pass_type = huff_opt_pass;
    +    master->scan_number++;
    +    break;
    +  }
    +
    +  master->pass_number++;
    +}
    +
    +
    +/*
    + * Initialize master compression control.
    + */
    +
    +GLOBAL(void)
    +jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
    +{
    +  my_master_ptr master;
    +
    +  master = (my_master_ptr)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(my_comp_master));
    +  cinfo->master = (struct jpeg_comp_master *) master;
    +  master->pub.prepare_for_pass = prepare_for_pass;
    +  master->pub.pass_startup = pass_startup;
    +  master->pub.finish_pass = finish_pass_master;
    +  master->pub.is_last_pass = FALSE;
    +
    +  /* Validate parameters, determine derived values */
    +  initial_setup(cinfo);
    +
    +  if (cinfo->scan_info != NULL) {
    +#ifdef C_MULTISCAN_FILES_SUPPORTED
    +    validate_script(cinfo);
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +  } else {
    +    cinfo->progressive_mode = FALSE;
    +    cinfo->num_scans = 1;
    +  }
    +
    +  if (cinfo->progressive_mode)  /*  TEMPORARY HACK ??? */
    +    cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
    +
    +  /* Initialize my private state */
    +  if (transcode_only) {
    +    /* no main pass in transcoding */
    +    if (cinfo->optimize_coding)
    +      master->pass_type = huff_opt_pass;
    +    else
    +      master->pass_type = output_pass;
    +  } else {
    +    /* for normal compression, first pass is always this type: */
    +    master->pass_type = main_pass;
    +  }
    +  master->scan_number = 0;
    +  master->pass_number = 0;
    +  if (cinfo->optimize_coding)
    +    master->total_passes = cinfo->num_scans * 2;
    +  else
    +    master->total_passes = cinfo->num_scans;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcomapi.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcomapi.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcomapi.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcomapi.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,110 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcomapi.c
    + *
    + * Copyright (C) 1994-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains application interface routines that are used for both
    + * compression and decompression.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Abort processing of a JPEG compression or decompression operation,
    + * but don't destroy the object itself.
    + *
    + * For this, we merely clean up all the nonpermanent memory pools.
    + * Note that temp files (virtual arrays) are not allowed to belong to
    + * the permanent pool, so we will be able to close all temp files here.
    + * Closing a data source or destination, if necessary, is the application's
    + * responsibility.
    + */
    +
    +GLOBAL(void)
    +jpeg_abort (j_common_ptr cinfo)
    +{
    +  int pool;
    +
    +  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
    +  if (cinfo->mem == NULL)
    +    return;
    +
    +  /* Releasing pools in reverse order might help avoid fragmentation
    +   * with some (brain-damaged) malloc libraries.
    +   */
    +  for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
    +    (*cinfo->mem->free_pool) (cinfo, pool);
    +  }
    +
    +  /* Reset overall state for possible reuse of object */
    +  if (cinfo->is_decompressor) {
    +    cinfo->global_state = DSTATE_START;
    +    /* Try to keep application from accessing now-deleted marker list.
    +     * A bit kludgy to do it here, but this is the most central place.
    +     */
    +    ((j_decompress_ptr) cinfo)->marker_list = NULL;
    +  } else {
    +    cinfo->global_state = CSTATE_START;
    +  }
    +}
    +
    +
    +/*
    + * Destruction of a JPEG object.
    + *
    + * Everything gets deallocated except the master jpeg_compress_struct itself
    + * and the error manager struct.  Both of these are supplied by the application
    + * and must be freed, if necessary, by the application.  (Often they are on
    + * the stack and so don't need to be freed anyway.)
    + * Closing a data source or destination, if necessary, is the application's
    + * responsibility.
    + */
    +
    +GLOBAL(void)
    +jpeg_destroy (j_common_ptr cinfo)
    +{
    +  /* We need only tell the memory manager to release everything. */
    +  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
    +  if (cinfo->mem != NULL)
    +    (*cinfo->mem->self_destruct) (cinfo);
    +  cinfo->mem = NULL;            /* be safe if jpeg_destroy is called twice */
    +  cinfo->global_state = 0;      /* mark it destroyed */
    +}
    +
    +
    +/*
    + * Convenience routines for allocating quantization and Huffman tables.
    + * (Would jutils.c be a more reasonable place to put these?)
    + */
    +
    +GLOBAL(JQUANT_TBL *)
    +jpeg_alloc_quant_table (j_common_ptr cinfo)
    +{
    +  JQUANT_TBL *tbl;
    +
    +  tbl = (JQUANT_TBL *)
    +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
    +  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
    +  return tbl;
    +}
    +
    +
    +GLOBAL(JHUFF_TBL *)
    +jpeg_alloc_huff_table (j_common_ptr cinfo)
    +{
    +  JHUFF_TBL *tbl;
    +
    +  tbl = (JHUFF_TBL *)
    +    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
    +  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
    +  return tbl;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jconfig.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jconfig.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jconfig.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jconfig.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,43 @@
    +/* jconfig.cfg --- source file edited by configure script */
    +/* see jconfig.doc for explanations */
    +
    +#define HAVE_PROTOTYPES
    +#define HAVE_UNSIGNED_CHAR
    +#define HAVE_UNSIGNED_SHORT
    +#undef void
    +#undef const
    +#undef CHAR_IS_UNSIGNED
    +#define HAVE_STDDEF_H
    +#define HAVE_STDLIB_H
    +#undef NEED_BSD_STRINGS
    +#undef NEED_SYS_TYPES_H
    +#undef NEED_FAR_POINTERS
    +#define NEED_SHORT_EXTERNAL_NAMES
    +/* Define this if you get warnings about undefined structures. */
    +#undef INCOMPLETE_TYPES_BROKEN
    +
    +#ifdef JPEG_INTERNALS
    +
    +#undef RIGHT_SHIFT_IS_UNSIGNED
    +/* These are for configuring the JPEG memory manager. */
    +#undef DEFAULT_MAX_MEM
    +#undef NO_MKTEMP
    +
    +#endif /* JPEG_INTERNALS */
    +
    +#ifdef JPEG_CJPEG_DJPEG
    +
    +#define BMP_SUPPORTED           /* BMP image file format */
    +#define GIF_SUPPORTED           /* GIF image file format */
    +#define PPM_SUPPORTED           /* PBMPLUS PPM/PGM image file format */
    +#undef RLE_SUPPORTED            /* Utah RLE image file format */
    +#define TARGA_SUPPORTED         /* Targa image file format */
    +
    +#undef TWO_FILE_COMMANDLINE
    +#undef NEED_SIGNAL_CATCHER
    +#undef DONT_USE_B_MODE
    +
    +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
    +#undef PROGRESS_REPORT
    +
    +#endif /* JPEG_CJPEG_DJPEG */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcparam.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcparam.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcparam.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcparam.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,614 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcparam.c
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains optional default-setting code for the JPEG compressor.
    + * Applications do not have to use this file, but those that don't use it
    + * must know a lot more about the innards of the JPEG code.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Quantization table setup routines
    + */
    +
    +GLOBAL(void)
    +jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
    +                      const unsigned int *basic_table,
    +                      int scale_factor, boolean force_baseline)
    +/* Define a quantization table equal to the basic_table times
    + * a scale factor (given as a percentage).
    + * If force_baseline is TRUE, the computed quantization table entries
    + * are limited to 1..255 for JPEG baseline compatibility.
    + */
    +{
    +  JQUANT_TBL ** qtblptr;
    +  int i;
    +  long temp;
    +
    +  /* Safety check to ensure start_compress not called yet. */
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
    +    ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
    +
    +  qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
    +
    +  if (*qtblptr == NULL)
    +    *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
    +
    +  for (i = 0; i < DCTSIZE2; i++) {
    +    temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
    +    /* limit the values to the valid range */
    +    if (temp <= 0L) temp = 1L;
    +    if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
    +    if (force_baseline && temp > 255L)
    +      temp = 255L;              /* limit to baseline range if requested */
    +    (*qtblptr)->quantval[i] = (UINT16) temp;
    +  }
    +
    +  /* Initialize sent_table FALSE so table will be written to JPEG file. */
    +  (*qtblptr)->sent_table = FALSE;
    +}
    +
    +
    +GLOBAL(void)
    +jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
    +                         boolean force_baseline)
    +/* Set or change the 'quality' (quantization) setting, using default tables
    + * and a straight percentage-scaling quality scale.  In most cases it's better
    + * to use jpeg_set_quality (below); this entry point is provided for
    + * applications that insist on a linear percentage scaling.
    + */
    +{
    +  /* These are the sample quantization tables given in JPEG spec section K.1.
    +   * The spec says that the values given produce "good" quality, and
    +   * when divided by 2, "very good" quality.
    +   */
    +  static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
    +    16,  11,  10,  16,  24,  40,  51,  61,
    +    12,  12,  14,  19,  26,  58,  60,  55,
    +    14,  13,  16,  24,  40,  57,  69,  56,
    +    14,  17,  22,  29,  51,  87,  80,  62,
    +    18,  22,  37,  56,  68, 109, 103,  77,
    +    24,  35,  55,  64,  81, 104, 113,  92,
    +    49,  64,  78,  87, 103, 121, 120, 101,
    +    72,  92,  95,  98, 112, 100, 103,  99
    +  };
    +  static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
    +    17,  18,  24,  47,  99,  99,  99,  99,
    +    18,  21,  26,  66,  99,  99,  99,  99,
    +    24,  26,  56,  99,  99,  99,  99,  99,
    +    47,  66,  99,  99,  99,  99,  99,  99,
    +    99,  99,  99,  99,  99,  99,  99,  99,
    +    99,  99,  99,  99,  99,  99,  99,  99,
    +    99,  99,  99,  99,  99,  99,  99,  99,
    +    99,  99,  99,  99,  99,  99,  99,  99
    +  };
    +
    +  /* Set up two quantization tables using the specified scaling */
    +  jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
    +                       scale_factor, force_baseline);
    +  jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
    +                       scale_factor, force_baseline);
    +}
    +
    +
    +GLOBAL(int)
    +jpeg_quality_scaling (int quality)
    +/* Convert a user-specified quality rating to a percentage scaling factor
    + * for an underlying quantization table, using our recommended scaling curve.
    + * The input 'quality' factor should be 0 (terrible) to 100 (very good).
    + */
    +{
    +  /* Safety limit on quality factor.  Convert 0 to 1 to avoid zero divide. */
    +  if (quality <= 0) quality = 1;
    +  if (quality > 100) quality = 100;
    +
    +  /* The basic table is used as-is (scaling 100) for a quality of 50.
    +   * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
    +   * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
    +   * to make all the table entries 1 (hence, minimum quantization loss).
    +   * Qualities 1..50 are converted to scaling percentage 5000/Q.
    +   */
    +  if (quality < 50)
    +    quality = 5000 / quality;
    +  else
    +    quality = 200 - quality*2;
    +
    +  return quality;
    +}
    +
    +
    +GLOBAL(void)
    +jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
    +/* Set or change the 'quality' (quantization) setting, using default tables.
    + * This is the standard quality-adjusting entry point for typical user
    + * interfaces; only those who want detailed control over quantization tables
    + * would use the preceding three routines directly.
    + */
    +{
    +  /* Convert user 0-100 rating to percentage scaling */
    +  quality = jpeg_quality_scaling(quality);
    +
    +  /* Set up standard quality tables */
    +  jpeg_set_linear_quality(cinfo, quality, force_baseline);
    +}
    +
    +
    +/*
    + * Huffman table setup routines
    + */
    +
    +LOCAL(void)
    +add_huff_table (j_compress_ptr cinfo,
    +                JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
    +/* Define a Huffman table */
    +{
    +  int nsymbols, len;
    +
    +  if (*htblptr == NULL)
    +    *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
    +
    +  /* Copy the number-of-symbols-of-each-code-length counts */
    +  MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
    +
    +  /* Validate the counts.  We do this here mainly so we can copy the right
    +   * number of symbols from the val[] array, without risking marching off
    +   * the end of memory.  jchuff.c will do a more thorough test later.
    +   */
    +  nsymbols = 0;
    +  for (len = 1; len <= 16; len++)
    +    nsymbols += bits[len];
    +  if (nsymbols < 1 || nsymbols > 256)
    +    ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +
    +  MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
    +
    +  /* Initialize sent_table FALSE so table will be written to JPEG file. */
    +  (*htblptr)->sent_table = FALSE;
    +}
    +
    +
    +LOCAL(void)
    +std_huff_tables (j_compress_ptr cinfo)
    +/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
    +/* IMPORTANT: these are only valid for 8-bit data precision! */
    +{
    +  static const UINT8 bits_dc_luminance[17] =
    +    { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
    +  static const UINT8 val_dc_luminance[] =
    +    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    +
    +  static const UINT8 bits_dc_chrominance[17] =
    +    { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
    +  static const UINT8 val_dc_chrominance[] =
    +    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    +
    +  static const UINT8 bits_ac_luminance[17] =
    +    { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
    +  static const UINT8 val_ac_luminance[] =
    +    { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
    +      0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
    +      0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
    +      0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
    +      0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
    +      0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
    +      0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
    +      0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
    +      0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
    +      0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
    +      0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
    +      0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
    +      0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
    +      0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    +      0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
    +      0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
    +      0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
    +      0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
    +      0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
    +      0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
    +      0xf9, 0xfa };
    +
    +  static const UINT8 bits_ac_chrominance[17] =
    +    { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
    +  static const UINT8 val_ac_chrominance[] =
    +    { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
    +      0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
    +      0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
    +      0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
    +      0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
    +      0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
    +      0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
    +      0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
    +      0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
    +      0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
    +      0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
    +      0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    +      0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
    +      0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
    +      0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
    +      0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
    +      0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
    +      0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
    +      0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
    +      0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
    +      0xf9, 0xfa };
    +
    +  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
    +                 bits_dc_luminance, val_dc_luminance);
    +  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
    +                 bits_ac_luminance, val_ac_luminance);
    +  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
    +                 bits_dc_chrominance, val_dc_chrominance);
    +  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
    +                 bits_ac_chrominance, val_ac_chrominance);
    +}
    +
    +
    +/*
    + * Default parameter setup for compression.
    + *
    + * Applications that don't choose to use this routine must do their
    + * own setup of all these parameters.  Alternately, you can call this
    + * to establish defaults and then alter parameters selectively.  This
    + * is the recommended approach since, if we add any new parameters,
    + * your code will still work (they'll be set to reasonable defaults).
    + */
    +
    +GLOBAL(void)
    +jpeg_set_defaults (j_compress_ptr cinfo)
    +{
    +  int i;
    +
    +  /* Safety check to ensure start_compress not called yet. */
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  /* Allocate comp_info array large enough for maximum component count.
    +   * Array is made permanent in case application wants to compress
    +   * multiple images at same param settings.
    +   */
    +  if (cinfo->comp_info == NULL)
    +    cinfo->comp_info = (jpeg_component_info *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
    +                                  MAX_COMPONENTS * SIZEOF(jpeg_component_info));
    +
    +  /* Initialize everything not dependent on the color space */
    +
    +  cinfo->data_precision = BITS_IN_JSAMPLE;
    +  /* Set up two quantization tables using default quality of 75 */
    +  jpeg_set_quality(cinfo, 75, TRUE);
    +  /* Set up two Huffman tables */
    +  std_huff_tables(cinfo);
    +
    +  /* Initialize default arithmetic coding conditioning */
    +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
    +    cinfo->arith_dc_L[i] = 0;
    +    cinfo->arith_dc_U[i] = 1;
    +    cinfo->arith_ac_K[i] = 5;
    +  }
    +
    +  /* Default is no multiple-scan output */
    +  cinfo->scan_info = NULL;
    +  cinfo->num_scans = 0;
    +
    +  /* Expect normal source image, not raw downsampled data */
    +  cinfo->raw_data_in = FALSE;
    +
    +  /* Use Huffman coding, not arithmetic coding, by default */
    +  cinfo->arith_code = FALSE;
    +
    +  /* By default, don't do extra passes to optimize entropy coding */
    +  cinfo->optimize_coding = FALSE;
    +  /* The standard Huffman tables are only valid for 8-bit data precision.
    +   * If the precision is higher, force optimization on so that usable
    +   * tables will be computed.  This test can be removed if default tables
    +   * are supplied that are valid for the desired precision.
    +   */
    +  if (cinfo->data_precision > 8)
    +    cinfo->optimize_coding = TRUE;
    +
    +  /* By default, use the simpler non-cosited sampling alignment */
    +  cinfo->CCIR601_sampling = FALSE;
    +
    +  /* No input smoothing */
    +  cinfo->smoothing_factor = 0;
    +
    +  /* DCT algorithm preference */
    +  cinfo->dct_method = JDCT_DEFAULT;
    +
    +  /* No restart markers */
    +  cinfo->restart_interval = 0;
    +  cinfo->restart_in_rows = 0;
    +
    +  /* Fill in default JFIF marker parameters.  Note that whether the marker
    +   * will actually be written is determined by jpeg_set_colorspace.
    +   *
    +   * By default, the library emits JFIF version code 1.01.
    +   * An application that wants to emit JFIF 1.02 extension markers should set
    +   * JFIF_minor_version to 2.  We could probably get away with just defaulting
    +   * to 1.02, but there may still be some decoders in use that will complain
    +   * about that; saying 1.01 should minimize compatibility problems.
    +   */
    +  cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
    +  cinfo->JFIF_minor_version = 1;
    +  cinfo->density_unit = 0;      /* Pixel size is unknown by default */
    +  cinfo->X_density = 1;         /* Pixel aspect ratio is square by default */
    +  cinfo->Y_density = 1;
    +
    +  /* Choose JPEG colorspace based on input space, set defaults accordingly */
    +
    +  jpeg_default_colorspace(cinfo);
    +}
    +
    +
    +/*
    + * Select an appropriate JPEG colorspace for in_color_space.
    + */
    +
    +GLOBAL(void)
    +jpeg_default_colorspace (j_compress_ptr cinfo)
    +{
    +  switch (cinfo->in_color_space) {
    +  case JCS_GRAYSCALE:
    +    jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
    +    break;
    +  case JCS_RGB:
    +    jpeg_set_colorspace(cinfo, JCS_YCbCr);
    +    break;
    +  case JCS_YCbCr:
    +    jpeg_set_colorspace(cinfo, JCS_YCbCr);
    +    break;
    +  case JCS_CMYK:
    +    jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
    +    break;
    +  case JCS_YCCK:
    +    jpeg_set_colorspace(cinfo, JCS_YCCK);
    +    break;
    +  case JCS_UNKNOWN:
    +    jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
    +    break;
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
    +  }
    +}
    +
    +
    +/*
    + * Set the JPEG colorspace, and choose colorspace-dependent default values.
    + */
    +
    +GLOBAL(void)
    +jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
    +{
    +  jpeg_component_info * compptr;
    +  int ci;
    +
    +#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl)  \
    +  (compptr = &cinfo->comp_info[index], \
    +   compptr->component_id = (id), \
    +   compptr->h_samp_factor = (hsamp), \
    +   compptr->v_samp_factor = (vsamp), \
    +   compptr->quant_tbl_no = (quant), \
    +   compptr->dc_tbl_no = (dctbl), \
    +   compptr->ac_tbl_no = (actbl) )
    +
    +  /* Safety check to ensure start_compress not called yet. */
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
    +   * tables 1 for chrominance components.
    +   */
    +
    +  cinfo->jpeg_color_space = colorspace;
    +
    +  cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
    +  cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
    +
    +  switch (colorspace) {
    +  case JCS_GRAYSCALE:
    +    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
    +    cinfo->num_components = 1;
    +    /* JFIF specifies component ID 1 */
    +    SET_COMP(0, 1, 1,1, 0, 0,0);
    +    break;
    +  case JCS_RGB:
    +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
    +    cinfo->num_components = 3;
    +    SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
    +    SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
    +    SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
    +    break;
    +  case JCS_YCbCr:
    +    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
    +    cinfo->num_components = 3;
    +    /* JFIF specifies component IDs 1,2,3 */
    +    /* We default to 2x2 subsamples of chrominance */
    +    SET_COMP(0, 1, 2,2, 0, 0,0);
    +    SET_COMP(1, 2, 1,1, 1, 1,1);
    +    SET_COMP(2, 3, 1,1, 1, 1,1);
    +    break;
    +  case JCS_CMYK:
    +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
    +    cinfo->num_components = 4;
    +    SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
    +    SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
    +    SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
    +    SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
    +    break;
    +  case JCS_YCCK:
    +    cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
    +    cinfo->num_components = 4;
    +    SET_COMP(0, 1, 2,2, 0, 0,0);
    +    SET_COMP(1, 2, 1,1, 1, 1,1);
    +    SET_COMP(2, 3, 1,1, 1, 1,1);
    +    SET_COMP(3, 4, 2,2, 0, 0,0);
    +    break;
    +  case JCS_UNKNOWN:
    +    cinfo->num_components = cinfo->input_components;
    +    if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
    +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
    +               MAX_COMPONENTS);
    +    for (ci = 0; ci < cinfo->num_components; ci++) {
    +      SET_COMP(ci, ci, 1,1, 0, 0,0);
    +    }
    +    break;
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +  }
    +}
    +
    +
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +
    +LOCAL(jpeg_scan_info *)
    +fill_a_scan (jpeg_scan_info * scanptr, int ci,
    +             int Ss, int Se, int Ah, int Al)
    +/* Support routine: generate one scan for specified component */
    +{
    +  scanptr->comps_in_scan = 1;
    +  scanptr->component_index[0] = ci;
    +  scanptr->Ss = Ss;
    +  scanptr->Se = Se;
    +  scanptr->Ah = Ah;
    +  scanptr->Al = Al;
    +  scanptr++;
    +  return scanptr;
    +}
    +
    +LOCAL(jpeg_scan_info *)
    +fill_scans (jpeg_scan_info * scanptr, int ncomps,
    +            int Ss, int Se, int Ah, int Al)
    +/* Support routine: generate one scan for each component */
    +{
    +  int ci;
    +
    +  for (ci = 0; ci < ncomps; ci++) {
    +    scanptr->comps_in_scan = 1;
    +    scanptr->component_index[0] = ci;
    +    scanptr->Ss = Ss;
    +    scanptr->Se = Se;
    +    scanptr->Ah = Ah;
    +    scanptr->Al = Al;
    +    scanptr++;
    +  }
    +  return scanptr;
    +}
    +
    +LOCAL(jpeg_scan_info *)
    +fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
    +/* Support routine: generate interleaved DC scan if possible, else N scans */
    +{
    +  int ci;
    +
    +  if (ncomps <= MAX_COMPS_IN_SCAN) {
    +    /* Single interleaved DC scan */
    +    scanptr->comps_in_scan = ncomps;
    +    for (ci = 0; ci < ncomps; ci++)
    +      scanptr->component_index[ci] = ci;
    +    scanptr->Ss = scanptr->Se = 0;
    +    scanptr->Ah = Ah;
    +    scanptr->Al = Al;
    +    scanptr++;
    +  } else {
    +    /* Noninterleaved DC scan for each component */
    +    scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
    +  }
    +  return scanptr;
    +}
    +
    +
    +/*
    + * Create a recommended progressive-JPEG script.
    + * cinfo->num_components and cinfo->jpeg_color_space must be correct.
    + */
    +
    +GLOBAL(void)
    +jpeg_simple_progression (j_compress_ptr cinfo)
    +{
    +  int ncomps = cinfo->num_components;
    +  int nscans;
    +  jpeg_scan_info * scanptr;
    +
    +  /* Safety check to ensure start_compress not called yet. */
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  /* Figure space needed for script.  Calculation must match code below! */
    +  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
    +    /* Custom script for YCbCr color images. */
    +    nscans = 10;
    +  } else {
    +    /* All-purpose script for other color spaces. */
    +    if (ncomps > MAX_COMPS_IN_SCAN)
    +      nscans = 6 * ncomps;      /* 2 DC + 4 AC scans per component */
    +    else
    +      nscans = 2 + 4 * ncomps;  /* 2 DC scans; 4 AC scans per component */
    +  }
    +
    +  /* Allocate space for script.
    +   * We need to put it in the permanent pool in case the application performs
    +   * multiple compressions without changing the settings.  To avoid a memory
    +   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
    +   * object, we try to re-use previously allocated space, and we allocate
    +   * enough space to handle YCbCr even if initially asked for grayscale.
    +   */
    +  if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
    +    cinfo->script_space_size = MAX(nscans, 10);
    +    cinfo->script_space = (jpeg_scan_info *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
    +                        cinfo->script_space_size * SIZEOF(jpeg_scan_info));
    +  }
    +  scanptr = cinfo->script_space;
    +  cinfo->scan_info = scanptr;
    +  cinfo->num_scans = nscans;
    +
    +  if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
    +    /* Custom script for YCbCr color images. */
    +    /* Initial DC scan */
    +    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
    +    /* Initial AC scan: get some luma data out in a hurry */
    +    scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
    +    /* Chroma data is too small to be worth expending many scans on */
    +    scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
    +    scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
    +    /* Complete spectral selection for luma AC */
    +    scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
    +    /* Refine next bit of luma AC */
    +    scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
    +    /* Finish DC successive approximation */
    +    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
    +    /* Finish AC successive approximation */
    +    scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
    +    scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
    +    /* Luma bottom bit comes last since it's usually largest scan */
    +    scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
    +  } else {
    +    /* All-purpose script for other color spaces. */
    +    /* Successive approximation first pass */
    +    scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
    +    scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
    +    scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
    +    /* Successive approximation second pass */
    +    scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
    +    /* Successive approximation final pass */
    +    scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
    +    scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
    +  }
    +}
    +
    +#endif /* C_PROGRESSIVE_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcphuff.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcphuff.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcphuff.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcphuff.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,837 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcphuff.c
    + *
    + * Copyright (C) 1995-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains Huffman entropy encoding routines for progressive JPEG.
    + *
    + * We do not support output suspension in this module, since the library
    + * currently does not allow multiple-scan files to be written with output
    + * suspension.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jchuff.h"             /* Declarations shared with jchuff.c */
    +
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +
    +/* Expanded entropy encoder object for progressive Huffman encoding. */
    +
    +typedef struct {
    +  struct jpeg_entropy_encoder pub; /* public fields */
    +
    +  /* Mode flag: TRUE for optimization, FALSE for actual data output */
    +  boolean gather_statistics;
    +
    +  /* Bit-level coding status.
    +   * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
    +   */
    +  JOCTET * next_output_byte;    /* => next byte to write in buffer */
    +  size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
    +  INT32 put_buffer;             /* current bit-accumulation buffer */
    +  int put_bits;                 /* # of bits now in it */
    +  j_compress_ptr cinfo;         /* link to cinfo (needed for dump_buffer) */
    +
    +  /* Coding status for DC components */
    +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
    +
    +  /* Coding status for AC components */
    +  int ac_tbl_no;                /* the table number of the single component */
    +  unsigned int EOBRUN;          /* run length of EOBs */
    +  unsigned int BE;              /* # of buffered correction bits before MCU */
    +  char * bit_buffer;            /* buffer for correction bits (1 per char) */
    +  /* packing correction bits tightly would save some space but cost time... */
    +
    +  unsigned int restarts_to_go;  /* MCUs left in this restart interval */
    +  int next_restart_num;         /* next restart number to write (0-7) */
    +
    +  /* Pointers to derived tables (these workspaces have image lifespan).
    +   * Since any one scan codes only DC or only AC, we only need one set
    +   * of tables, not one for DC and one for AC.
    +   */
    +  c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
    +
    +  /* Statistics tables for optimization; again, one set is enough */
    +  long * count_ptrs[NUM_HUFF_TBLS];
    +} phuff_entropy_encoder;
    +
    +typedef phuff_entropy_encoder * phuff_entropy_ptr;
    +
    +/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
    + * buffer can hold.  Larger sizes may slightly improve compression, but
    + * 1000 is already well into the realm of overkill.
    + * The minimum safe size is 64 bits.
    + */
    +
    +#define MAX_CORR_BITS  1000     /* Max # of correction bits I can buffer */
    +
    +/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
    + * We assume that int right shift is unsigned if INT32 right shift is,
    + * which should be safe.
    + */
    +
    +#ifdef RIGHT_SHIFT_IS_UNSIGNED
    +#define ISHIFT_TEMPS    int ishift_temp;
    +#define IRIGHT_SHIFT(x,shft)  \
    +        ((ishift_temp = (x)) < 0 ? \
    +         (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
    +         (ishift_temp >> (shft)))
    +#else
    +#define ISHIFT_TEMPS
    +#define IRIGHT_SHIFT(x,shft)    ((x) >> (shft))
    +#endif
    +
    +/* Forward declarations */
    +METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
    +                                            JBLOCKROW *MCU_data));
    +METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
    +                                            JBLOCKROW *MCU_data));
    +METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
    +                                             JBLOCKROW *MCU_data));
    +METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
    +                                             JBLOCKROW *MCU_data));
    +METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
    +METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
    +
    +
    +/*
    + * Initialize for a Huffman-compressed scan using progressive JPEG.
    + */
    +
    +METHODDEF(void)
    +start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  boolean is_DC_band;
    +  int ci, tbl;
    +  jpeg_component_info * compptr;
    +
    +  entropy->cinfo = cinfo;
    +  entropy->gather_statistics = gather_statistics;
    +
    +  is_DC_band = (cinfo->Ss == 0);
    +
    +  /* We assume jcmaster.c already validated the scan parameters. */
    +
    +  /* Select execution routines */
    +  if (cinfo->Ah == 0) {
    +    if (is_DC_band)
    +      entropy->pub.encode_mcu = encode_mcu_DC_first;
    +    else
    +      entropy->pub.encode_mcu = encode_mcu_AC_first;
    +  } else {
    +    if (is_DC_band)
    +      entropy->pub.encode_mcu = encode_mcu_DC_refine;
    +    else {
    +      entropy->pub.encode_mcu = encode_mcu_AC_refine;
    +      /* AC refinement needs a correction bit buffer */
    +      if (entropy->bit_buffer == NULL)
    +        entropy->bit_buffer = (char *)
    +          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                      MAX_CORR_BITS * SIZEOF(char));
    +    }
    +  }
    +  if (gather_statistics)
    +    entropy->pub.finish_pass = finish_pass_gather_phuff;
    +  else
    +    entropy->pub.finish_pass = finish_pass_phuff;
    +
    +  /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
    +   * for AC coefficients.
    +   */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    /* Initialize DC predictions to 0 */
    +    entropy->last_dc_val[ci] = 0;
    +    /* Get table index */
    +    if (is_DC_band) {
    +      if (cinfo->Ah != 0)       /* DC refinement needs no table */
    +        continue;
    +      tbl = compptr->dc_tbl_no;
    +    } else {
    +      entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
    +    }
    +    if (gather_statistics) {
    +      /* Check for invalid table index */
    +      /* (make_c_derived_tbl does this in the other path) */
    +      if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
    +        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
    +      /* Allocate and zero the statistics tables */
    +      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
    +      if (entropy->count_ptrs[tbl] == NULL)
    +        entropy->count_ptrs[tbl] = (long *)
    +          (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                      257 * SIZEOF(long));
    +      MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
    +    } else {
    +      /* Compute derived values for Huffman table */
    +      /* We may do this more than once for a table, but it's not expensive */
    +      jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
    +                              & entropy->derived_tbls[tbl]);
    +    }
    +  }
    +
    +  /* Initialize AC stuff */
    +  entropy->EOBRUN = 0;
    +  entropy->BE = 0;
    +
    +  /* Initialize bit buffer to empty */
    +  entropy->put_buffer = 0;
    +  entropy->put_bits = 0;
    +
    +  /* Initialize restart stuff */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +  entropy->next_restart_num = 0;
    +}
    +
    +
    +/* Outputting bytes to the file.
    + * NB: these must be called only when actually outputting,
    + * that is, entropy->gather_statistics == FALSE.
    + */
    +
    +/* Emit a byte */
    +#define emit_byte(entropy,val)  \
    +        { *(entropy)->next_output_byte++ = (JOCTET) (val);  \
    +          if (--(entropy)->free_in_buffer == 0)  \
    +            dump_buffer(entropy); }
    +
    +
    +LOCAL(void)
    +dump_buffer (phuff_entropy_ptr entropy)
    +/* Empty the output buffer; we do not support suspension in this module. */
    +{
    +  struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
    +
    +  if (! (*dest->empty_output_buffer) (entropy->cinfo))
    +    ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
    +  /* After a successful buffer dump, must reset buffer pointers */
    +  entropy->next_output_byte = dest->next_output_byte;
    +  entropy->free_in_buffer = dest->free_in_buffer;
    +}
    +
    +
    +/* Outputting bits to the file */
    +
    +/* Only the right 24 bits of put_buffer are used; the valid bits are
    + * left-justified in this part.  At most 16 bits can be passed to emit_bits
    + * in one call, and we never retain more than 7 bits in put_buffer
    + * between calls, so 24 bits are sufficient.
    + */
    +
    +INLINE
    +LOCAL(void)
    +emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
    +/* Emit some bits, unless we are in gather mode */
    +{
    +  /* This routine is heavily used, so it's worth coding tightly. */
    +  register INT32 put_buffer = (INT32) code;
    +  register int put_bits = entropy->put_bits;
    +
    +  /* if size is 0, caller used an invalid Huffman table entry */
    +  if (size == 0)
    +    ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
    +
    +  if (entropy->gather_statistics)
    +    return;                     /* do nothing if we're only getting stats */
    +
    +  put_buffer &= (((INT32) 1)<put_buffer; /* and merge with old buffer contents */
    +
    +  while (put_bits >= 8) {
    +    int c = (int) ((put_buffer >> 16) & 0xFF);
    +
    +    emit_byte(entropy, c);
    +    if (c == 0xFF) {            /* need to stuff a zero byte? */
    +      emit_byte(entropy, 0);
    +    }
    +    put_buffer <<= 8;
    +    put_bits -= 8;
    +  }
    +
    +  entropy->put_buffer = put_buffer; /* update variables */
    +  entropy->put_bits = put_bits;
    +}
    +
    +
    +LOCAL(void)
    +flush_bits (phuff_entropy_ptr entropy)
    +{
    +  emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
    +  entropy->put_buffer = 0;     /* and reset bit-buffer to empty */
    +  entropy->put_bits = 0;
    +}
    +
    +
    +/*
    + * Emit (or just count) a Huffman symbol.
    + */
    +
    +INLINE
    +LOCAL(void)
    +emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
    +{
    +  if (entropy->gather_statistics)
    +    entropy->count_ptrs[tbl_no][symbol]++;
    +  else {
    +    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
    +    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
    +  }
    +}
    +
    +
    +/*
    + * Emit bits from a correction bit buffer.
    + */
    +
    +LOCAL(void)
    +emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
    +                    unsigned int nbits)
    +{
    +  if (entropy->gather_statistics)
    +    return;                     /* no real work */
    +
    +  while (nbits > 0) {
    +    emit_bits(entropy, (unsigned int) (*bufstart), 1);
    +    bufstart++;
    +    nbits--;
    +  }
    +}
    +
    +
    +/*
    + * Emit any pending EOBRUN symbol.
    + */
    +
    +LOCAL(void)
    +emit_eobrun (phuff_entropy_ptr entropy)
    +{
    +  register int temp, nbits;
    +
    +  if (entropy->EOBRUN > 0) {    /* if there is any pending EOBRUN */
    +    temp = entropy->EOBRUN;
    +    nbits = 0;
    +    while ((temp >>= 1))
    +      nbits++;
    +    /* safety check: shouldn't happen given limited correction-bit buffer */
    +    if (nbits > 14)
    +      ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
    +
    +    emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
    +    if (nbits)
    +      emit_bits(entropy, entropy->EOBRUN, nbits);
    +
    +    entropy->EOBRUN = 0;
    +
    +    /* Emit any buffered correction bits */
    +    emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
    +    entropy->BE = 0;
    +  }
    +}
    +
    +
    +/*
    + * Emit a restart marker & resynchronize predictions.
    + */
    +
    +LOCAL(void)
    +emit_restart (phuff_entropy_ptr entropy, int restart_num)
    +{
    +  int ci;
    +
    +  emit_eobrun(entropy);
    +
    +  if (! entropy->gather_statistics) {
    +    flush_bits(entropy);
    +    emit_byte(entropy, 0xFF);
    +    emit_byte(entropy, JPEG_RST0 + restart_num);
    +  }
    +
    +  if (entropy->cinfo->Ss == 0) {
    +    /* Re-initialize DC predictions to 0 */
    +    for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
    +      entropy->last_dc_val[ci] = 0;
    +  } else {
    +    /* Re-initialize all AC-related fields to 0 */
    +    entropy->EOBRUN = 0;
    +    entropy->BE = 0;
    +  }
    +}
    +
    +
    +/*
    + * MCU encoding for DC initial scan (either spectral selection,
    + * or first pass of successive approximation).
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  register int temp, temp2;
    +  register int nbits;
    +  int blkn, ci;
    +  int Al = cinfo->Al;
    +  JBLOCKROW block;
    +  jpeg_component_info * compptr;
    +  ISHIFT_TEMPS
    +
    +  entropy->next_output_byte = cinfo->dest->next_output_byte;
    +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
    +
    +  /* Emit restart marker if needed */
    +  if (cinfo->restart_interval)
    +    if (entropy->restarts_to_go == 0)
    +      emit_restart(entropy, entropy->next_restart_num);
    +
    +  /* Encode the MCU data blocks */
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    block = MCU_data[blkn];
    +    ci = cinfo->MCU_membership[blkn];
    +    compptr = cinfo->cur_comp_info[ci];
    +
    +    /* Compute the DC value after the required point transform by Al.
    +     * This is simply an arithmetic right shift.
    +     */
    +    temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
    +
    +    /* DC differences are figured on the point-transformed values. */
    +    temp = temp2 - entropy->last_dc_val[ci];
    +    entropy->last_dc_val[ci] = temp2;
    +
    +    /* Encode the DC coefficient difference per section G.1.2.1 */
    +    temp2 = temp;
    +    if (temp < 0) {
    +      temp = -temp;             /* temp is abs value of input */
    +      /* For a negative input, want temp2 = bitwise complement of abs(input) */
    +      /* This code assumes we are on a two's complement machine */
    +      temp2--;
    +    }
    +
    +    /* Find the number of bits needed for the magnitude of the coefficient */
    +    nbits = 0;
    +    while (temp) {
    +      nbits++;
    +      temp >>= 1;
    +    }
    +    /* Check for out-of-range coefficient values.
    +     * Since we're encoding a difference, the range limit is twice as much.
    +     */
    +    if (nbits > MAX_COEF_BITS+1)
    +      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    +
    +    /* Count/emit the Huffman-coded symbol for the number of bits */
    +    emit_symbol(entropy, compptr->dc_tbl_no, nbits);
    +
    +    /* Emit that number of bits of the value, if positive, */
    +    /* or the complement of its magnitude, if negative. */
    +    if (nbits)                  /* emit_bits rejects calls with size 0 */
    +      emit_bits(entropy, (unsigned int) temp2, nbits);
    +  }
    +
    +  cinfo->dest->next_output_byte = entropy->next_output_byte;
    +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
    +
    +  /* Update restart-interval state too */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +      entropy->next_restart_num++;
    +      entropy->next_restart_num &= 7;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU encoding for AC initial scan (either spectral selection,
    + * or first pass of successive approximation).
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  register int temp, temp2;
    +  register int nbits;
    +  register int r, k;
    +  int Se = cinfo->Se;
    +  int Al = cinfo->Al;
    +  JBLOCKROW block;
    +
    +  entropy->next_output_byte = cinfo->dest->next_output_byte;
    +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
    +
    +  /* Emit restart marker if needed */
    +  if (cinfo->restart_interval)
    +    if (entropy->restarts_to_go == 0)
    +      emit_restart(entropy, entropy->next_restart_num);
    +
    +  /* Encode the MCU data block */
    +  block = MCU_data[0];
    +
    +  /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
    +
    +  r = 0;                        /* r = run length of zeros */
    +
    +  for (k = cinfo->Ss; k <= Se; k++) {
    +    if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
    +      r++;
    +      continue;
    +    }
    +    /* We must apply the point transform by Al.  For AC coefficients this
    +     * is an integer division with rounding towards 0.  To do this portably
    +     * in C, we shift after obtaining the absolute value; so the code is
    +     * interwoven with finding the abs value (temp) and output bits (temp2).
    +     */
    +    if (temp < 0) {
    +      temp = -temp;             /* temp is abs value of input */
    +      temp >>= Al;              /* apply the point transform */
    +      /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
    +      temp2 = ~temp;
    +    } else {
    +      temp >>= Al;              /* apply the point transform */
    +      temp2 = temp;
    +    }
    +    /* Watch out for case that nonzero coef is zero after point transform */
    +    if (temp == 0) {
    +      r++;
    +      continue;
    +    }
    +
    +    /* Emit any pending EOBRUN */
    +    if (entropy->EOBRUN > 0)
    +      emit_eobrun(entropy);
    +    /* if run length > 15, must emit special run-length-16 codes (0xF0) */
    +    while (r > 15) {
    +      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
    +      r -= 16;
    +    }
    +
    +    /* Find the number of bits needed for the magnitude of the coefficient */
    +    nbits = 1;                  /* there must be at least one 1 bit */
    +    while ((temp >>= 1))
    +      nbits++;
    +    /* Check for out-of-range coefficient values */
    +    if (nbits > MAX_COEF_BITS)
    +      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    +
    +    /* Count/emit Huffman symbol for run length / number of bits */
    +    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
    +
    +    /* Emit that number of bits of the value, if positive, */
    +    /* or the complement of its magnitude, if negative. */
    +    emit_bits(entropy, (unsigned int) temp2, nbits);
    +
    +    r = 0;                      /* reset zero run length */
    +  }
    +
    +  if (r > 0) {                  /* If there are trailing zeroes, */
    +    entropy->EOBRUN++;          /* count an EOB */
    +    if (entropy->EOBRUN == 0x7FFF)
    +      emit_eobrun(entropy);     /* force it out to avoid overflow */
    +  }
    +
    +  cinfo->dest->next_output_byte = entropy->next_output_byte;
    +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
    +
    +  /* Update restart-interval state too */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +      entropy->next_restart_num++;
    +      entropy->next_restart_num &= 7;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU encoding for DC successive approximation refinement scan.
    + * Note: we assume such scans can be multi-component, although the spec
    + * is not very clear on the point.
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  register int temp;
    +  int blkn;
    +  int Al = cinfo->Al;
    +  JBLOCKROW block;
    +
    +  entropy->next_output_byte = cinfo->dest->next_output_byte;
    +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
    +
    +  /* Emit restart marker if needed */
    +  if (cinfo->restart_interval)
    +    if (entropy->restarts_to_go == 0)
    +      emit_restart(entropy, entropy->next_restart_num);
    +
    +  /* Encode the MCU data blocks */
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    block = MCU_data[blkn];
    +
    +    /* We simply emit the Al'th bit of the DC coefficient value. */
    +    temp = (*block)[0];
    +    emit_bits(entropy, (unsigned int) (temp >> Al), 1);
    +  }
    +
    +  cinfo->dest->next_output_byte = entropy->next_output_byte;
    +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
    +
    +  /* Update restart-interval state too */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +      entropy->next_restart_num++;
    +      entropy->next_restart_num &= 7;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU encoding for AC successive approximation refinement scan.
    + */
    +
    +METHODDEF(boolean)
    +encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  register int temp;
    +  register int r, k;
    +  int EOB;
    +  char *BR_buffer;
    +  unsigned int BR;
    +  int Se = cinfo->Se;
    +  int Al = cinfo->Al;
    +  JBLOCKROW block;
    +  int absvalues[DCTSIZE2];
    +
    +  entropy->next_output_byte = cinfo->dest->next_output_byte;
    +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
    +
    +  /* Emit restart marker if needed */
    +  if (cinfo->restart_interval)
    +    if (entropy->restarts_to_go == 0)
    +      emit_restart(entropy, entropy->next_restart_num);
    +
    +  /* Encode the MCU data block */
    +  block = MCU_data[0];
    +
    +  /* It is convenient to make a pre-pass to determine the transformed
    +   * coefficients' absolute values and the EOB position.
    +   */
    +  EOB = 0;
    +  for (k = cinfo->Ss; k <= Se; k++) {
    +    temp = (*block)[jpeg_natural_order[k]];
    +    /* We must apply the point transform by Al.  For AC coefficients this
    +     * is an integer division with rounding towards 0.  To do this portably
    +     * in C, we shift after obtaining the absolute value.
    +     */
    +    if (temp < 0)
    +      temp = -temp;             /* temp is abs value of input */
    +    temp >>= Al;                /* apply the point transform */
    +    absvalues[k] = temp;        /* save abs value for main pass */
    +    if (temp == 1)
    +      EOB = k;                  /* EOB = index of last newly-nonzero coef */
    +  }
    +
    +  /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
    +
    +  r = 0;                        /* r = run length of zeros */
    +  BR = 0;                       /* BR = count of buffered bits added now */
    +  BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
    +
    +  for (k = cinfo->Ss; k <= Se; k++) {
    +    if ((temp = absvalues[k]) == 0) {
    +      r++;
    +      continue;
    +    }
    +
    +    /* Emit any required ZRLs, but not if they can be folded into EOB */
    +    while (r > 15 && k <= EOB) {
    +      /* emit any pending EOBRUN and the BE correction bits */
    +      emit_eobrun(entropy);
    +      /* Emit ZRL */
    +      emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
    +      r -= 16;
    +      /* Emit buffered correction bits that must be associated with ZRL */
    +      emit_buffered_bits(entropy, BR_buffer, BR);
    +      BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
    +      BR = 0;
    +    }
    +
    +    /* If the coef was previously nonzero, it only needs a correction bit.
    +     * NOTE: a straight translation of the spec's figure G.7 would suggest
    +     * that we also need to test r > 15.  But if r > 15, we can only get here
    +     * if k > EOB, which implies that this coefficient is not 1.
    +     */
    +    if (temp > 1) {
    +      /* The correction bit is the next bit of the absolute value. */
    +      BR_buffer[BR++] = (char) (temp & 1);
    +      continue;
    +    }
    +
    +    /* Emit any pending EOBRUN and the BE correction bits */
    +    emit_eobrun(entropy);
    +
    +    /* Count/emit Huffman symbol for run length / number of bits */
    +    emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
    +
    +    /* Emit output bit for newly-nonzero coef */
    +    temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
    +    emit_bits(entropy, (unsigned int) temp, 1);
    +
    +    /* Emit buffered correction bits that must be associated with this code */
    +    emit_buffered_bits(entropy, BR_buffer, BR);
    +    BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
    +    BR = 0;
    +    r = 0;                      /* reset zero run length */
    +  }
    +
    +  if (r > 0 || BR > 0) {        /* If there are trailing zeroes, */
    +    entropy->EOBRUN++;          /* count an EOB */
    +    entropy->BE += BR;          /* concat my correction bits to older ones */
    +    /* We force out the EOB if we risk either:
    +     * 1. overflow of the EOB counter;
    +     * 2. overflow of the correction bit buffer during the next MCU.
    +     */
    +    if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
    +      emit_eobrun(entropy);
    +  }
    +
    +  cinfo->dest->next_output_byte = entropy->next_output_byte;
    +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
    +
    +  /* Update restart-interval state too */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0) {
    +      entropy->restarts_to_go = cinfo->restart_interval;
    +      entropy->next_restart_num++;
    +      entropy->next_restart_num &= 7;
    +    }
    +    entropy->restarts_to_go--;
    +  }
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Finish up at the end of a Huffman-compressed progressive scan.
    + */
    +
    +METHODDEF(void)
    +finish_pass_phuff (j_compress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +
    +  entropy->next_output_byte = cinfo->dest->next_output_byte;
    +  entropy->free_in_buffer = cinfo->dest->free_in_buffer;
    +
    +  /* Flush out any buffered data */
    +  emit_eobrun(entropy);
    +  flush_bits(entropy);
    +
    +  cinfo->dest->next_output_byte = entropy->next_output_byte;
    +  cinfo->dest->free_in_buffer = entropy->free_in_buffer;
    +}
    +
    +
    +/*
    + * Finish up a statistics-gathering pass and create the new Huffman tables.
    + */
    +
    +METHODDEF(void)
    +finish_pass_gather_phuff (j_compress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  boolean is_DC_band;
    +  int ci, tbl;
    +  jpeg_component_info * compptr;
    +  JHUFF_TBL **htblptr;
    +  boolean did[NUM_HUFF_TBLS];
    +
    +  /* Flush out buffered data (all we care about is counting the EOB symbol) */
    +  emit_eobrun(entropy);
    +
    +  is_DC_band = (cinfo->Ss == 0);
    +
    +  /* It's important not to apply jpeg_gen_optimal_table more than once
    +   * per table, because it clobbers the input frequency counts!
    +   */
    +  MEMZERO(did, SIZEOF(did));
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    if (is_DC_band) {
    +      if (cinfo->Ah != 0)       /* DC refinement needs no table */
    +        continue;
    +      tbl = compptr->dc_tbl_no;
    +    } else {
    +      tbl = compptr->ac_tbl_no;
    +    }
    +    if (! did[tbl]) {
    +      if (is_DC_band)
    +        htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
    +      else
    +        htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
    +      if (*htblptr == NULL)
    +        *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
    +      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
    +      did[tbl] = TRUE;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Module initialization routine for progressive Huffman entropy encoding.
    + */
    +
    +GLOBAL(void)
    +jinit_phuff_encoder (j_compress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy;
    +  int i;
    +
    +  entropy = (phuff_entropy_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(phuff_entropy_encoder));
    +  cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
    +  entropy->pub.start_pass = start_pass_phuff;
    +
    +  /* Mark tables unallocated */
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    entropy->derived_tbls[i] = NULL;
    +    entropy->count_ptrs[i] = NULL;
    +  }
    +  entropy->bit_buffer = NULL;   /* needed only in AC refinement scan */
    +}
    +
    +#endif /* C_PROGRESSIVE_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcprepct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcprepct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcprepct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcprepct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,358 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcprepct.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the compression preprocessing controller.
    + * This controller manages the color conversion, downsampling,
    + * and edge expansion steps.
    + *
    + * Most of the complexity here is associated with buffering input rows
    + * as required by the downsampler.  See the comments at the head of
    + * jcsample.c for the downsampler's needs.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* At present, jcsample.c can request context rows only for smoothing.
    + * In the future, we might also need context rows for CCIR601 sampling
    + * or other more-complex downsampling procedures.  The code to support
    + * context rows should be compiled only if needed.
    + */
    +#ifdef INPUT_SMOOTHING_SUPPORTED
    +#define CONTEXT_ROWS_SUPPORTED
    +#endif
    +
    +
    +/*
    + * For the simple (no-context-row) case, we just need to buffer one
    + * row group's worth of pixels for the downsampling step.  At the bottom of
    + * the image, we pad to a full row group by replicating the last pixel row.
    + * The downsampler's last output row is then replicated if needed to pad
    + * out to a full iMCU row.
    + *
    + * When providing context rows, we must buffer three row groups' worth of
    + * pixels.  Three row groups are physically allocated, but the row pointer
    + * arrays are made five row groups high, with the extra pointers above and
    + * below "wrapping around" to point to the last and first real row groups.
    + * This allows the downsampler to access the proper context rows.
    + * At the top and bottom of the image, we create dummy context rows by
    + * copying the first or last real pixel row.  This copying could be avoided
    + * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
    + * trouble on the compression side.
    + */
    +
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_c_prep_controller pub; /* public fields */
    +
    +  /* Downsampling input buffer.  This buffer holds color-converted data
    +   * until we have enough to do a downsample step.
    +   */
    +  JSAMPARRAY color_buf[MAX_COMPONENTS];
    +
    +  JDIMENSION rows_to_go;        /* counts rows remaining in source image */
    +  int next_buf_row;             /* index of next row to store in color_buf */
    +
    +#ifdef CONTEXT_ROWS_SUPPORTED   /* only needed for context case */
    +  int this_row_group;           /* starting row index of group to process */
    +  int next_buf_stop;            /* downsample when we reach this index */
    +#endif
    +} my_prep_controller;
    +
    +typedef my_prep_controller * my_prep_ptr;
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    +
    +  if (pass_mode != JBUF_PASS_THRU)
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +
    +  /* Initialize total-height counter for detecting bottom of image */
    +  prep->rows_to_go = cinfo->image_height;
    +  /* Mark the conversion buffer empty */
    +  prep->next_buf_row = 0;
    +#ifdef CONTEXT_ROWS_SUPPORTED
    +  /* Preset additional state variables for context mode.
    +   * These aren't used in non-context mode, so we needn't test which mode.
    +   */
    +  prep->this_row_group = 0;
    +  /* Set next_buf_stop to stop after two row groups have been read in. */
    +  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
    +#endif
    +}
    +
    +
    +/*
    + * Expand an image vertically from height input_rows to height output_rows,
    + * by duplicating the bottom row.
    + */
    +
    +LOCAL(void)
    +expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
    +                    int input_rows, int output_rows)
    +{
    +  register int row;
    +
    +  for (row = input_rows; row < output_rows; row++) {
    +    jcopy_sample_rows(image_data, input_rows-1, image_data, row,
    +                      1, num_cols);
    +  }
    +}
    +
    +
    +/*
    + * Process some data in the simple no-context case.
    + *
    + * Preprocessor output data is counted in "row groups".  A row group
    + * is defined to be v_samp_factor sample rows of each component.
    + * Downsampling will produce this much data from each max_v_samp_factor
    + * input rows.
    + */
    +
    +METHODDEF(void)
    +pre_process_data (j_compress_ptr cinfo,
    +                  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
    +                  JDIMENSION in_rows_avail,
    +                  JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
    +                  JDIMENSION out_row_groups_avail)
    +{
    +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    +  int numrows, ci;
    +  JDIMENSION inrows;
    +  jpeg_component_info * compptr;
    +
    +  while (*in_row_ctr < in_rows_avail &&
    +         *out_row_group_ctr < out_row_groups_avail) {
    +    /* Do color conversion to fill the conversion buffer. */
    +    inrows = in_rows_avail - *in_row_ctr;
    +    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
    +    numrows = (int) MIN((JDIMENSION) numrows, inrows);
    +    (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
    +                                       prep->color_buf,
    +                                       (JDIMENSION) prep->next_buf_row,
    +                                       numrows);
    +    *in_row_ctr += numrows;
    +    prep->next_buf_row += numrows;
    +    prep->rows_to_go -= numrows;
    +    /* If at bottom of image, pad to fill the conversion buffer. */
    +    if (prep->rows_to_go == 0 &&
    +        prep->next_buf_row < cinfo->max_v_samp_factor) {
    +      for (ci = 0; ci < cinfo->num_components; ci++) {
    +        expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
    +                           prep->next_buf_row, cinfo->max_v_samp_factor);
    +      }
    +      prep->next_buf_row = cinfo->max_v_samp_factor;
    +    }
    +    /* If we've filled the conversion buffer, empty it. */
    +    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
    +      (*cinfo->downsample->downsample) (cinfo,
    +                                        prep->color_buf, (JDIMENSION) 0,
    +                                        output_buf, *out_row_group_ctr);
    +      prep->next_buf_row = 0;
    +      (*out_row_group_ctr)++;
    +    }
    +    /* If at bottom of image, pad the output to a full iMCU height.
    +     * Note we assume the caller is providing a one-iMCU-height output buffer!
    +     */
    +    if (prep->rows_to_go == 0 &&
    +        *out_row_group_ctr < out_row_groups_avail) {
    +      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +           ci++, compptr++) {
    +        expand_bottom_edge(output_buf[ci],
    +                           compptr->width_in_blocks * DCTSIZE,
    +                           (int) (*out_row_group_ctr * compptr->v_samp_factor),
    +                           (int) (out_row_groups_avail * compptr->v_samp_factor));
    +      }
    +      *out_row_group_ctr = out_row_groups_avail;
    +      break;                    /* can exit outer loop without test */
    +    }
    +  }
    +}
    +
    +
    +#ifdef CONTEXT_ROWS_SUPPORTED
    +
    +/*
    + * Process some data in the context case.
    + */
    +
    +METHODDEF(void)
    +pre_process_context (j_compress_ptr cinfo,
    +                     JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
    +                     JDIMENSION in_rows_avail,
    +                     JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
    +                     JDIMENSION out_row_groups_avail)
    +{
    +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    +  int numrows, ci;
    +  int buf_height = cinfo->max_v_samp_factor * 3;
    +  JDIMENSION inrows;
    +
    +  while (*out_row_group_ctr < out_row_groups_avail) {
    +    if (*in_row_ctr < in_rows_avail) {
    +      /* Do color conversion to fill the conversion buffer. */
    +      inrows = in_rows_avail - *in_row_ctr;
    +      numrows = prep->next_buf_stop - prep->next_buf_row;
    +      numrows = (int) MIN((JDIMENSION) numrows, inrows);
    +      (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
    +                                         prep->color_buf,
    +                                         (JDIMENSION) prep->next_buf_row,
    +                                         numrows);
    +      /* Pad at top of image, if first time through */
    +      if (prep->rows_to_go == cinfo->image_height) {
    +        for (ci = 0; ci < cinfo->num_components; ci++) {
    +          int row;
    +          for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
    +            jcopy_sample_rows(prep->color_buf[ci], 0,
    +                              prep->color_buf[ci], -row,
    +                              1, cinfo->image_width);
    +          }
    +        }
    +      }
    +      *in_row_ctr += numrows;
    +      prep->next_buf_row += numrows;
    +      prep->rows_to_go -= numrows;
    +    } else {
    +      /* Return for more data, unless we are at the bottom of the image. */
    +      if (prep->rows_to_go != 0)
    +        break;
    +      /* When at bottom of image, pad to fill the conversion buffer. */
    +      if (prep->next_buf_row < prep->next_buf_stop) {
    +        for (ci = 0; ci < cinfo->num_components; ci++) {
    +          expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
    +                             prep->next_buf_row, prep->next_buf_stop);
    +        }
    +        prep->next_buf_row = prep->next_buf_stop;
    +      }
    +    }
    +    /* If we've gotten enough data, downsample a row group. */
    +    if (prep->next_buf_row == prep->next_buf_stop) {
    +      (*cinfo->downsample->downsample) (cinfo,
    +                                        prep->color_buf,
    +                                        (JDIMENSION) prep->this_row_group,
    +                                        output_buf, *out_row_group_ctr);
    +      (*out_row_group_ctr)++;
    +      /* Advance pointers with wraparound as necessary. */
    +      prep->this_row_group += cinfo->max_v_samp_factor;
    +      if (prep->this_row_group >= buf_height)
    +        prep->this_row_group = 0;
    +      if (prep->next_buf_row >= buf_height)
    +        prep->next_buf_row = 0;
    +      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Create the wrapped-around downsampling input buffer needed for context mode.
    + */
    +
    +LOCAL(void)
    +create_context_buffer (j_compress_ptr cinfo)
    +{
    +  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
    +  int rgroup_height = cinfo->max_v_samp_factor;
    +  int ci, i;
    +  jpeg_component_info * compptr;
    +  JSAMPARRAY true_buffer, fake_buffer;
    +
    +  /* Grab enough space for fake row pointers for all the components;
    +   * we need five row groups' worth of pointers for each component.
    +   */
    +  fake_buffer = (JSAMPARRAY)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (cinfo->num_components * 5 * rgroup_height) *
    +                                SIZEOF(JSAMPROW));
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Allocate the actual buffer space (3 row groups) for this component.
    +     * We make the buffer wide enough to allow the downsampler to edge-expand
    +     * horizontally within the buffer, if it so chooses.
    +     */
    +    true_buffer = (*cinfo->mem->alloc_sarray)
    +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +       (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
    +                      cinfo->max_h_samp_factor) / compptr->h_samp_factor),
    +       (JDIMENSION) (3 * rgroup_height));
    +    /* Copy true buffer row pointers into the middle of the fake row array */
    +    MEMCOPY(fake_buffer + rgroup_height, true_buffer,
    +            3 * rgroup_height * SIZEOF(JSAMPROW));
    +    /* Fill in the above and below wraparound pointers */
    +    for (i = 0; i < rgroup_height; i++) {
    +      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
    +      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
    +    }
    +    prep->color_buf[ci] = fake_buffer + rgroup_height;
    +    fake_buffer += 5 * rgroup_height; /* point to space for next component */
    +  }
    +}
    +
    +#endif /* CONTEXT_ROWS_SUPPORTED */
    +
    +
    +/*
    + * Initialize preprocessing controller.
    + */
    +
    +GLOBAL(void)
    +jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_prep_ptr prep;
    +  int ci;
    +  jpeg_component_info * compptr;
    +
    +  if (need_full_buffer)         /* safety check */
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +
    +  prep = (my_prep_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_prep_controller));
    +  cinfo->prep = (struct jpeg_c_prep_controller *) prep;
    +  prep->pub.start_pass = start_pass_prep;
    +
    +  /* Allocate the color conversion buffer.
    +   * We make the buffer wide enough to allow the downsampler to edge-expand
    +   * horizontally within the buffer, if it so chooses.
    +   */
    +  if (cinfo->downsample->need_context_rows) {
    +    /* Set up to provide context rows */
    +#ifdef CONTEXT_ROWS_SUPPORTED
    +    prep->pub.pre_process_data = pre_process_context;
    +    create_context_buffer(cinfo);
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +  } else {
    +    /* No context, just make it tall enough for one row group */
    +    prep->pub.pre_process_data = pre_process_data;
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +         (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
    +                        cinfo->max_h_samp_factor) / compptr->h_samp_factor),
    +         (JDIMENSION) cinfo->max_v_samp_factor);
    +    }
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcsample.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcsample.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jcsample.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jcsample.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,523 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jcsample.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains downsampling routines.
    + *
    + * Downsampling input data is counted in "row groups".  A row group
    + * is defined to be max_v_samp_factor pixel rows of each component,
    + * from which the downsampler produces v_samp_factor sample rows.
    + * A single row group is processed in each call to the downsampler module.
    + *
    + * The downsampler is responsible for edge-expansion of its output data
    + * to fill an integral number of DCT blocks horizontally.  The source buffer
    + * may be modified if it is helpful for this purpose (the source buffer is
    + * allocated wide enough to correspond to the desired output width).
    + * The caller (the prep controller) is responsible for vertical padding.
    + *
    + * The downsampler may request "context rows" by setting need_context_rows
    + * during startup.  In this case, the input arrays will contain at least
    + * one row group's worth of pixels above and below the passed-in data;
    + * the caller will create dummy rows at image top and bottom by replicating
    + * the first or last real pixel row.
    + *
    + * An excellent reference for image resampling is
    + *   Digital Image Warping, George Wolberg, 1990.
    + *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
    + *
    + * The downsampling algorithm used here is a simple average of the source
    + * pixels covered by the output pixel.  The hi-falutin sampling literature
    + * refers to this as a "box filter".  In general the characteristics of a box
    + * filter are not very good, but for the specific cases we normally use (1:1
    + * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
    + * nearly so bad.  If you intend to use other sampling ratios, you'd be well
    + * advised to improve this code.
    + *
    + * A simple input-smoothing capability is provided.  This is mainly intended
    + * for cleaning up color-dithered GIF input files (if you find it inadequate,
    + * we suggest using an external filtering program such as pnmconvol).  When
    + * enabled, each input pixel P is replaced by a weighted sum of itself and its
    + * eight neighbors.  P's weight is 1-8*SF and each neighbor's weight is SF,
    + * where SF = (smoothing_factor / 1024).
    + * Currently, smoothing is only supported for 2h2v sampling factors.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Pointer to routine to downsample a single component */
    +typedef JMETHOD(void, downsample1_ptr,
    +                (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                 JSAMPARRAY input_data, JSAMPARRAY output_data));
    +
    +/* Private subobject */
    +
    +typedef struct {
    +  struct jpeg_downsampler pub;  /* public fields */
    +
    +  /* Downsampling method pointers, one per component */
    +  downsample1_ptr methods[MAX_COMPONENTS];
    +} my_downsampler;
    +
    +typedef my_downsampler * my_downsample_ptr;
    +
    +
    +/*
    + * Initialize for a downsampling pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_downsample (j_compress_ptr cinfo)
    +{
    +  /* no work for now */
    +}
    +
    +
    +/*
    + * Expand a component horizontally from width input_cols to width output_cols,
    + * by duplicating the rightmost samples.
    + */
    +
    +LOCAL(void)
    +expand_right_edge (JSAMPARRAY image_data, int num_rows,
    +                   JDIMENSION input_cols, JDIMENSION output_cols)
    +{
    +  register JSAMPROW ptr;
    +  register JSAMPLE pixval;
    +  register int count;
    +  int row;
    +  int numcols = (int) (output_cols - input_cols);
    +
    +  if (numcols > 0) {
    +    for (row = 0; row < num_rows; row++) {
    +      ptr = image_data[row] + input_cols;
    +      pixval = ptr[-1];         /* don't need GETJSAMPLE() here */
    +      for (count = numcols; count > 0; count--)
    +        *ptr++ = pixval;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Do downsampling for a whole row group (all components).
    + *
    + * In this version we simply downsample each component independently.
    + */
    +
    +METHODDEF(void)
    +sep_downsample (j_compress_ptr cinfo,
    +                JSAMPIMAGE input_buf, JDIMENSION in_row_index,
    +                JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
    +{
    +  my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
    +  int ci;
    +  jpeg_component_info * compptr;
    +  JSAMPARRAY in_ptr, out_ptr;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    in_ptr = input_buf[ci] + in_row_index;
    +    out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
    +    (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
    +  }
    +}
    +
    +
    +/*
    + * Downsample pixel values of a single component.
    + * One row group is processed per call.
    + * This version handles arbitrary integral sampling ratios, without smoothing.
    + * Note that this version is not actually used for customary sampling ratios.
    + */
    +
    +METHODDEF(void)
    +int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
    +  JDIMENSION outcol, outcol_h;  /* outcol_h == outcol*h_expand */
    +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
    +  JSAMPROW inptr, outptr;
    +  INT32 outvalue;
    +
    +  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
    +  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
    +  numpix = h_expand * v_expand;
    +  numpix2 = numpix/2;
    +
    +  /* Expand input data enough to let all the output samples be generated
    +   * by the standard loop.  Special-casing padded output would be more
    +   * efficient.
    +   */
    +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
    +                    cinfo->image_width, output_cols * h_expand);
    +
    +  inrow = 0;
    +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    +    outptr = output_data[outrow];
    +    for (outcol = 0, outcol_h = 0; outcol < output_cols;
    +         outcol++, outcol_h += h_expand) {
    +      outvalue = 0;
    +      for (v = 0; v < v_expand; v++) {
    +        inptr = input_data[inrow+v] + outcol_h;
    +        for (h = 0; h < h_expand; h++) {
    +          outvalue += (INT32) GETJSAMPLE(*inptr++);
    +        }
    +      }
    +      *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
    +    }
    +    inrow += v_expand;
    +  }
    +}
    +
    +
    +/*
    + * Downsample pixel values of a single component.
    + * This version handles the special case of a full-size component,
    + * without smoothing.
    + */
    +
    +METHODDEF(void)
    +fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                     JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  /* Copy the data */
    +  jcopy_sample_rows(input_data, 0, output_data, 0,
    +                    cinfo->max_v_samp_factor, cinfo->image_width);
    +  /* Edge-expand */
    +  expand_right_edge(output_data, cinfo->max_v_samp_factor,
    +                    cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
    +}
    +
    +
    +/*
    + * Downsample pixel values of a single component.
    + * This version handles the common case of 2:1 horizontal and 1:1 vertical,
    + * without smoothing.
    + *
    + * A note about the "bias" calculations: when rounding fractional values to
    + * integer, we do not want to always round 0.5 up to the next integer.
    + * If we did that, we'd introduce a noticeable bias towards larger values.
    + * Instead, this code is arranged so that 0.5 will be rounded up or down at
    + * alternate pixel locations (a simple ordered dither pattern).
    + */
    +
    +METHODDEF(void)
    +h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                 JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  int outrow;
    +  JDIMENSION outcol;
    +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
    +  register JSAMPROW inptr, outptr;
    +  register int bias;
    +
    +  /* Expand input data enough to let all the output samples be generated
    +   * by the standard loop.  Special-casing padded output would be more
    +   * efficient.
    +   */
    +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
    +                    cinfo->image_width, output_cols * 2);
    +
    +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    +    outptr = output_data[outrow];
    +    inptr = input_data[outrow];
    +    bias = 0;                   /* bias = 0,1,0,1,... for successive samples */
    +    for (outcol = 0; outcol < output_cols; outcol++) {
    +      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
    +                              + bias) >> 1);
    +      bias ^= 1;                /* 0=>1, 1=>0 */
    +      inptr += 2;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Downsample pixel values of a single component.
    + * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
    + * without smoothing.
    + */
    +
    +METHODDEF(void)
    +h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                 JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  int inrow, outrow;
    +  JDIMENSION outcol;
    +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
    +  register JSAMPROW inptr0, inptr1, outptr;
    +  register int bias;
    +
    +  /* Expand input data enough to let all the output samples be generated
    +   * by the standard loop.  Special-casing padded output would be more
    +   * efficient.
    +   */
    +  expand_right_edge(input_data, cinfo->max_v_samp_factor,
    +                    cinfo->image_width, output_cols * 2);
    +
    +  inrow = 0;
    +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    +    outptr = output_data[outrow];
    +    inptr0 = input_data[inrow];
    +    inptr1 = input_data[inrow+1];
    +    bias = 1;                   /* bias = 1,2,1,2,... for successive samples */
    +    for (outcol = 0; outcol < output_cols; outcol++) {
    +      *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
    +                              GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
    +                              + bias) >> 2);
    +      bias ^= 3;                /* 1=>2, 2=>1 */
    +      inptr0 += 2; inptr1 += 2;
    +    }
    +    inrow += 2;
    +  }
    +}
    +
    +
    +#ifdef INPUT_SMOOTHING_SUPPORTED
    +
    +/*
    + * Downsample pixel values of a single component.
    + * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
    + * with smoothing.  One row of context is required.
    + */
    +
    +METHODDEF(void)
    +h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
    +                        JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  int inrow, outrow;
    +  JDIMENSION colctr;
    +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
    +  register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
    +  INT32 membersum, neighsum, memberscale, neighscale;
    +
    +  /* Expand input data enough to let all the output samples be generated
    +   * by the standard loop.  Special-casing padded output would be more
    +   * efficient.
    +   */
    +  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
    +                    cinfo->image_width, output_cols * 2);
    +
    +  /* We don't bother to form the individual "smoothed" input pixel values;
    +   * we can directly compute the output which is the average of the four
    +   * smoothed values.  Each of the four member pixels contributes a fraction
    +   * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
    +   * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
    +   * output.  The four corner-adjacent neighbor pixels contribute a fraction
    +   * SF to just one smoothed pixel, or SF/4 to the final output; while the
    +   * eight edge-adjacent neighbors contribute SF to each of two smoothed
    +   * pixels, or SF/2 overall.  In order to use integer arithmetic, these
    +   * factors are scaled by 2^16 = 65536.
    +   * Also recall that SF = smoothing_factor / 1024.
    +   */
    +
    +  memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
    +  neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
    +
    +  inrow = 0;
    +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    +    outptr = output_data[outrow];
    +    inptr0 = input_data[inrow];
    +    inptr1 = input_data[inrow+1];
    +    above_ptr = input_data[inrow-1];
    +    below_ptr = input_data[inrow+2];
    +
    +    /* Special case for first column: pretend column -1 is same as column 0 */
    +    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
    +                GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
    +    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
    +               GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
    +               GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
    +               GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
    +    neighsum += neighsum;
    +    neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
    +                GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
    +    membersum = membersum * memberscale + neighsum * neighscale;
    +    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
    +    inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
    +
    +    for (colctr = output_cols - 2; colctr > 0; colctr--) {
    +      /* sum of pixels directly mapped to this output element */
    +      membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
    +                  GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
    +      /* sum of edge-neighbor pixels */
    +      neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
    +                 GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
    +                 GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
    +                 GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
    +      /* The edge-neighbors count twice as much as corner-neighbors */
    +      neighsum += neighsum;
    +      /* Add in the corner-neighbors */
    +      neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
    +                  GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
    +      /* form final output scaled up by 2^16 */
    +      membersum = membersum * memberscale + neighsum * neighscale;
    +      /* round, descale and output it */
    +      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
    +      inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
    +    }
    +
    +    /* Special case for last column */
    +    membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
    +                GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
    +    neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
    +               GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
    +               GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
    +               GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
    +    neighsum += neighsum;
    +    neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
    +                GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
    +    membersum = membersum * memberscale + neighsum * neighscale;
    +    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
    +
    +    inrow += 2;
    +  }
    +}
    +
    +
    +/*
    + * Downsample pixel values of a single component.
    + * This version handles the special case of a full-size component,
    + * with smoothing.  One row of context is required.
    + */
    +
    +METHODDEF(void)
    +fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
    +                            JSAMPARRAY input_data, JSAMPARRAY output_data)
    +{
    +  int outrow;
    +  JDIMENSION colctr;
    +  JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
    +  register JSAMPROW inptr, above_ptr, below_ptr, outptr;
    +  INT32 membersum, neighsum, memberscale, neighscale;
    +  int colsum, lastcolsum, nextcolsum;
    +
    +  /* Expand input data enough to let all the output samples be generated
    +   * by the standard loop.  Special-casing padded output would be more
    +   * efficient.
    +   */
    +  expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
    +                    cinfo->image_width, output_cols);
    +
    +  /* Each of the eight neighbor pixels contributes a fraction SF to the
    +   * smoothed pixel, while the main pixel contributes (1-8*SF).  In order
    +   * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
    +   * Also recall that SF = smoothing_factor / 1024.
    +   */
    +
    +  memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
    +  neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
    +
    +  for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
    +    outptr = output_data[outrow];
    +    inptr = input_data[outrow];
    +    above_ptr = input_data[outrow-1];
    +    below_ptr = input_data[outrow+1];
    +
    +    /* Special case for first column */
    +    colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
    +             GETJSAMPLE(*inptr);
    +    membersum = GETJSAMPLE(*inptr++);
    +    nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
    +                 GETJSAMPLE(*inptr);
    +    neighsum = colsum + (colsum - membersum) + nextcolsum;
    +    membersum = membersum * memberscale + neighsum * neighscale;
    +    *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
    +    lastcolsum = colsum; colsum = nextcolsum;
    +
    +    for (colctr = output_cols - 2; colctr > 0; colctr--) {
    +      membersum = GETJSAMPLE(*inptr++);
    +      above_ptr++; below_ptr++;
    +      nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
    +                   GETJSAMPLE(*inptr);
    +      neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
    +      membersum = membersum * memberscale + neighsum * neighscale;
    +      *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
    +      lastcolsum = colsum; colsum = nextcolsum;
    +    }
    +
    +    /* Special case for last column */
    +    membersum = GETJSAMPLE(*inptr);
    +    neighsum = lastcolsum + (colsum - membersum) + colsum;
    +    membersum = membersum * memberscale + neighsum * neighscale;
    +    *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
    +
    +  }
    +}
    +
    +#endif /* INPUT_SMOOTHING_SUPPORTED */
    +
    +
    +/*
    + * Module initialization routine for downsampling.
    + * Note that we must select a routine for each component.
    + */
    +
    +GLOBAL(void)
    +jinit_downsampler (j_compress_ptr cinfo)
    +{
    +  my_downsample_ptr downsample;
    +  int ci;
    +  jpeg_component_info * compptr;
    +  boolean smoothok = TRUE;
    +
    +  downsample = (my_downsample_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_downsampler));
    +  cinfo->downsample = (struct jpeg_downsampler *) downsample;
    +  downsample->pub.start_pass = start_pass_downsample;
    +  downsample->pub.downsample = sep_downsample;
    +  downsample->pub.need_context_rows = FALSE;
    +
    +  if (cinfo->CCIR601_sampling)
    +    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
    +
    +  /* Verify we can handle the sampling factors, and set up method pointers */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
    +        compptr->v_samp_factor == cinfo->max_v_samp_factor) {
    +#ifdef INPUT_SMOOTHING_SUPPORTED
    +      if (cinfo->smoothing_factor) {
    +        downsample->methods[ci] = fullsize_smooth_downsample;
    +        downsample->pub.need_context_rows = TRUE;
    +      } else
    +#endif
    +        downsample->methods[ci] = fullsize_downsample;
    +    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
    +               compptr->v_samp_factor == cinfo->max_v_samp_factor) {
    +      smoothok = FALSE;
    +      downsample->methods[ci] = h2v1_downsample;
    +    } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
    +               compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
    +#ifdef INPUT_SMOOTHING_SUPPORTED
    +      if (cinfo->smoothing_factor) {
    +        downsample->methods[ci] = h2v2_smooth_downsample;
    +        downsample->pub.need_context_rows = TRUE;
    +      } else
    +#endif
    +        downsample->methods[ci] = h2v2_downsample;
    +    } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
    +               (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
    +      smoothok = FALSE;
    +      downsample->methods[ci] = int_downsample;
    +    } else
    +      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
    +  }
    +
    +#ifdef INPUT_SMOOTHING_SUPPORTED
    +  if (cinfo->smoothing_factor && !smoothok)
    +    TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
    +#endif
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jctrans.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jctrans.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jctrans.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jctrans.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,392 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jctrans.c
    + *
    + * Copyright (C) 1995-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains library routines for transcoding compression,
    + * that is, writing raw DCT coefficient arrays to an output JPEG file.
    + * The routines in jcapimin.c will also be needed by a transcoder.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Forward declarations */
    +LOCAL(void) transencode_master_selection
    +        JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
    +LOCAL(void) transencode_coef_controller
    +        JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
    +
    +
    +/*
    + * Compression initialization for writing raw-coefficient data.
    + * Before calling this, all parameters and a data destination must be set up.
    + * Call jpeg_finish_compress() to actually write the data.
    + *
    + * The number of passed virtual arrays must match cinfo->num_components.
    + * Note that the virtual arrays need not be filled or even realized at
    + * the time write_coefficients is called; indeed, if the virtual arrays
    + * were requested from this compression object's memory manager, they
    + * typically will be realized during this routine and filled afterwards.
    + */
    +
    +GLOBAL(void)
    +jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
    +{
    +  if (cinfo->global_state != CSTATE_START)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  /* Mark all tables to be written */
    +  jpeg_suppress_tables(cinfo, FALSE);
    +  /* (Re)initialize error mgr and destination modules */
    +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
    +  (*cinfo->dest->init_destination) (cinfo);
    +  /* Perform master selection of active modules */
    +  transencode_master_selection(cinfo, coef_arrays);
    +  /* Wait for jpeg_finish_compress() call */
    +  cinfo->next_scanline = 0;     /* so jpeg_write_marker works */
    +  cinfo->global_state = CSTATE_WRCOEFS;
    +}
    +
    +
    +/*
    + * Initialize the compression object with default parameters,
    + * then copy from the source object all parameters needed for lossless
    + * transcoding.  Parameters that can be varied without loss (such as
    + * scan script and Huffman optimization) are left in their default states.
    + */
    +
    +GLOBAL(void)
    +jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
    +                               j_compress_ptr dstinfo)
    +{
    +  JQUANT_TBL ** qtblptr;
    +  jpeg_component_info *incomp, *outcomp;
    +  JQUANT_TBL *c_quant, *slot_quant;
    +  int tblno, ci, coefi;
    +
    +  /* Safety check to ensure start_compress not called yet. */
    +  if (dstinfo->global_state != CSTATE_START)
    +    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
    +  /* Copy fundamental image dimensions */
    +  dstinfo->image_width = srcinfo->image_width;
    +  dstinfo->image_height = srcinfo->image_height;
    +  dstinfo->input_components = srcinfo->num_components;
    +  dstinfo->in_color_space = srcinfo->jpeg_color_space;
    +  /* Initialize all parameters to default values */
    +  jpeg_set_defaults(dstinfo);
    +  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
    +   * Fix it to get the right header markers for the image colorspace.
    +   */
    +  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
    +  dstinfo->data_precision = srcinfo->data_precision;
    +  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
    +  /* Copy the source's quantization tables. */
    +  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
    +    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
    +      qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
    +      if (*qtblptr == NULL)
    +        *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
    +      MEMCOPY((*qtblptr)->quantval,
    +              srcinfo->quant_tbl_ptrs[tblno]->quantval,
    +              SIZEOF((*qtblptr)->quantval));
    +      (*qtblptr)->sent_table = FALSE;
    +    }
    +  }
    +  /* Copy the source's per-component info.
    +   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
    +   */
    +  dstinfo->num_components = srcinfo->num_components;
    +  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
    +    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
    +             MAX_COMPONENTS);
    +  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
    +       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
    +    outcomp->component_id = incomp->component_id;
    +    outcomp->h_samp_factor = incomp->h_samp_factor;
    +    outcomp->v_samp_factor = incomp->v_samp_factor;
    +    outcomp->quant_tbl_no = incomp->quant_tbl_no;
    +    /* Make sure saved quantization table for component matches the qtable
    +     * slot.  If not, the input file re-used this qtable slot.
    +     * IJG encoder currently cannot duplicate this.
    +     */
    +    tblno = outcomp->quant_tbl_no;
    +    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
    +        srcinfo->quant_tbl_ptrs[tblno] == NULL)
    +      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
    +    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
    +    c_quant = incomp->quant_table;
    +    if (c_quant != NULL) {
    +      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
    +        if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
    +          ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
    +      }
    +    }
    +    /* Note: we do not copy the source's Huffman table assignments;
    +     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
    +     */
    +  }
    +  /* Also copy JFIF version and resolution information, if available.
    +   * Strictly speaking this isn't "critical" info, but it's nearly
    +   * always appropriate to copy it if available.  In particular,
    +   * if the application chooses to copy JFIF 1.02 extension markers from
    +   * the source file, we need to copy the version to make sure we don't
    +   * emit a file that has 1.02 extensions but a claimed version of 1.01.
    +   * We will *not*, however, copy version info from mislabeled "2.01" files.
    +   */
    +  if (srcinfo->saw_JFIF_marker) {
    +    if (srcinfo->JFIF_major_version == 1) {
    +      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
    +      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
    +    }
    +    dstinfo->density_unit = srcinfo->density_unit;
    +    dstinfo->X_density = srcinfo->X_density;
    +    dstinfo->Y_density = srcinfo->Y_density;
    +  }
    +}
    +
    +
    +/*
    + * Master selection of compression modules for transcoding.
    + * This substitutes for jcinit.c's initialization of the full compressor.
    + */
    +
    +LOCAL(void)
    +transencode_master_selection (j_compress_ptr cinfo,
    +                              jvirt_barray_ptr * coef_arrays)
    +{
    +  /* Although we don't actually use input_components for transcoding,
    +   * jcmaster.c's initial_setup will complain if input_components is 0.
    +   */
    +  cinfo->input_components = 1;
    +  /* Initialize master control (includes parameter checking/processing) */
    +  jinit_c_master_control(cinfo, TRUE /* transcode only */);
    +
    +  /* Entropy encoding: either Huffman or arithmetic coding. */
    +  if (cinfo->arith_code) {
    +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
    +  } else {
    +    if (cinfo->progressive_mode) {
    +#ifdef C_PROGRESSIVE_SUPPORTED
    +      jinit_phuff_encoder(cinfo);
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    } else
    +      jinit_huff_encoder(cinfo);
    +  }
    +
    +  /* We need a special coefficient buffer controller. */
    +  transencode_coef_controller(cinfo, coef_arrays);
    +
    +  jinit_marker_writer(cinfo);
    +
    +  /* We can now tell the memory manager to allocate virtual arrays. */
    +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
    +
    +  /* Write the datastream header (SOI, JFIF) immediately.
    +   * Frame and scan headers are postponed till later.
    +   * This lets application insert special markers after the SOI.
    +   */
    +  (*cinfo->marker->write_file_header) (cinfo);
    +}
    +
    +
    +/*
    + * The rest of this file is a special implementation of the coefficient
    + * buffer controller.  This is similar to jccoefct.c, but it handles only
    + * output from presupplied virtual arrays.  Furthermore, we generate any
    + * dummy padding blocks on-the-fly rather than expecting them to be present
    + * in the arrays.
    + */
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_c_coef_controller pub; /* public fields */
    +
    +  JDIMENSION iMCU_row_num;      /* iMCU row # within image */
    +  JDIMENSION mcu_ctr;           /* counts MCUs processed in current row */
    +  int MCU_vert_offset;          /* counts MCU rows within iMCU row */
    +  int MCU_rows_per_iMCU_row;    /* number of such rows needed */
    +
    +  /* Virtual block array for each component. */
    +  jvirt_barray_ptr * whole_image;
    +
    +  /* Workspace for constructing dummy blocks at right/bottom edges. */
    +  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
    +} my_coef_controller;
    +
    +typedef my_coef_controller * my_coef_ptr;
    +
    +
    +LOCAL(void)
    +start_iMCU_row (j_compress_ptr cinfo)
    +/* Reset within-iMCU-row counters for a new row */
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
    +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
    +   * But at the bottom of the image, process only what's left.
    +   */
    +  if (cinfo->comps_in_scan > 1) {
    +    coef->MCU_rows_per_iMCU_row = 1;
    +  } else {
    +    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
    +    else
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
    +  }
    +
    +  coef->mcu_ctr = 0;
    +  coef->MCU_vert_offset = 0;
    +}
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  if (pass_mode != JBUF_CRANK_DEST)
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +
    +  coef->iMCU_row_num = 0;
    +  start_iMCU_row(cinfo);
    +}
    +
    +
    +/*
    + * Process some data.
    + * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
    + * per call, ie, v_samp_factor block rows for each component in the scan.
    + * The data is obtained from the virtual arrays and fed to the entropy coder.
    + * Returns TRUE if the iMCU row is completed, FALSE if suspended.
    + *
    + * NB: input_buf is ignored; it is likely to be a NULL pointer.
    + */
    +
    +METHODDEF(boolean)
    +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  int blkn, ci, xindex, yindex, yoffset, blockcnt;
    +  JDIMENSION start_col;
    +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    +  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
    +  JBLOCKROW buffer_ptr;
    +  jpeg_component_info *compptr;
    +
    +  /* Align the virtual buffers for the components used in this scan. */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    buffer[ci] = (*cinfo->mem->access_virt_barray)
    +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
    +       coef->iMCU_row_num * compptr->v_samp_factor,
    +       (JDIMENSION) compptr->v_samp_factor, FALSE);
    +  }
    +
    +  /* Loop to process one whole iMCU row */
    +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    +       yoffset++) {
    +    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
    +         MCU_col_num++) {
    +      /* Construct list of pointers to DCT blocks belonging to this MCU */
    +      blkn = 0;                 /* index of current DCT block within MCU */
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +        compptr = cinfo->cur_comp_info[ci];
    +        start_col = MCU_col_num * compptr->MCU_width;
    +        blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
    +                                                : compptr->last_col_width;
    +        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    +          if (coef->iMCU_row_num < last_iMCU_row ||
    +              yindex+yoffset < compptr->last_row_height) {
    +            /* Fill in pointers to real blocks in this row */
    +            buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
    +            for (xindex = 0; xindex < blockcnt; xindex++)
    +              MCU_buffer[blkn++] = buffer_ptr++;
    +          } else {
    +            /* At bottom of image, need a whole row of dummy blocks */
    +            xindex = 0;
    +          }
    +          /* Fill in any dummy blocks needed in this row.
    +           * Dummy blocks are filled in the same way as in jccoefct.c:
    +           * all zeroes in the AC entries, DC entries equal to previous
    +           * block's DC value.  The init routine has already zeroed the
    +           * AC entries, so we need only set the DC entries correctly.
    +           */
    +          for (; xindex < compptr->MCU_width; xindex++) {
    +            MCU_buffer[blkn] = coef->dummy_buffer[blkn];
    +            MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
    +            blkn++;
    +          }
    +        }
    +      }
    +      /* Try to write the MCU. */
    +      if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
    +        /* Suspension forced; update state counters and exit */
    +        coef->MCU_vert_offset = yoffset;
    +        coef->mcu_ctr = MCU_col_num;
    +        return FALSE;
    +      }
    +    }
    +    /* Completed an MCU row, but perhaps not an iMCU row */
    +    coef->mcu_ctr = 0;
    +  }
    +  /* Completed the iMCU row, advance counters for next one */
    +  coef->iMCU_row_num++;
    +  start_iMCU_row(cinfo);
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Initialize coefficient buffer controller.
    + *
    + * Each passed coefficient array must be the right size for that
    + * coefficient: width_in_blocks wide and height_in_blocks high,
    + * with unitheight at least v_samp_factor.
    + */
    +
    +LOCAL(void)
    +transencode_coef_controller (j_compress_ptr cinfo,
    +                             jvirt_barray_ptr * coef_arrays)
    +{
    +  my_coef_ptr coef;
    +  JBLOCKROW buffer;
    +  int i;
    +
    +  coef = (my_coef_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_coef_controller));
    +  cinfo->coef = (struct jpeg_c_coef_controller *) coef;
    +  coef->pub.start_pass = start_pass_coef;
    +  coef->pub.compress_data = compress_output;
    +
    +  /* Save pointer to virtual arrays */
    +  coef->whole_image = coef_arrays;
    +
    +  /* Allocate and pre-zero space for dummy DCT blocks. */
    +  buffer = (JBLOCKROW)
    +    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
    +  jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
    +  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
    +    coef->dummy_buffer[i] = buffer + i;
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdapimin.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdapimin.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdapimin.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdapimin.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,399 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdapimin.c
    + *
    + * Copyright (C) 1994-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains application interface code for the decompression half
    + * of the JPEG library.  These are the "minimum" API routines that may be
    + * needed in either the normal full-decompression case or the
    + * transcoding-only case.
    + *
    + * Most of the routines intended to be called directly by an application
    + * are in this file or in jdapistd.c.  But also see jcomapi.c for routines
    + * shared by compression and decompression, and jdtrans.c for the transcoding
    + * case.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * Initialization of a JPEG decompression object.
    + * The error manager must already be set up (in case memory manager fails).
    + */
    +
    +GLOBAL(void)
    +jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
    +{
    +  int i;
    +
    +  /* Guard against version mismatches between library and caller. */
    +  cinfo->mem = NULL;            /* so jpeg_destroy knows mem mgr not called */
    +  if (version != JPEG_LIB_VERSION)
    +    ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
    +  if (structsize != SIZEOF(struct jpeg_decompress_struct))
    +    ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
    +             (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
    +
    +  /* For debugging purposes, we zero the whole master structure.
    +   * But the application has already set the err pointer, and may have set
    +   * client_data, so we have to save and restore those fields.
    +   * Note: if application hasn't set client_data, tools like Purify may
    +   * complain here.
    +   */
    +  {
    +    struct jpeg_error_mgr * err = cinfo->err;
    +    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
    +    MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
    +    cinfo->err = err;
    +    cinfo->client_data = client_data;
    +  }
    +  cinfo->is_decompressor = TRUE;
    +
    +  /* Initialize a memory manager instance for this object */
    +  jinit_memory_mgr((j_common_ptr) cinfo);
    +
    +  /* Zero out pointers to permanent structures. */
    +  cinfo->progress = NULL;
    +  cinfo->src = NULL;
    +
    +  for (i = 0; i < NUM_QUANT_TBLS; i++)
    +    cinfo->quant_tbl_ptrs[i] = NULL;
    +
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    cinfo->dc_huff_tbl_ptrs[i] = NULL;
    +    cinfo->ac_huff_tbl_ptrs[i] = NULL;
    +  }
    +
    +  /* Initialize marker processor so application can override methods
    +   * for COM, APPn markers before calling jpeg_read_header.
    +   */
    +  cinfo->marker_list = NULL;
    +  jinit_marker_reader(cinfo);
    +
    +  /* And initialize the overall input controller. */
    +  jinit_input_controller(cinfo);
    +
    +  /* OK, I'm ready */
    +  cinfo->global_state = DSTATE_START;
    +}
    +
    +
    +/*
    + * Destruction of a JPEG decompression object
    + */
    +
    +GLOBAL(void)
    +jpeg_destroy_decompress (j_decompress_ptr cinfo)
    +{
    +  jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
    +}
    +
    +
    +/*
    + * Abort processing of a JPEG decompression operation,
    + * but don't destroy the object itself.
    + */
    +
    +GLOBAL(void)
    +jpeg_abort_decompress (j_decompress_ptr cinfo)
    +{
    +  jpeg_abort((j_common_ptr) cinfo); /* use common routine */
    +}
    +
    +
    +/*
    + * Set default decompression parameters.
    + */
    +
    +LOCAL(void)
    +default_decompress_parms (j_decompress_ptr cinfo)
    +{
    +  /* Guess the input colorspace, and set output colorspace accordingly. */
    +  /* (Wish JPEG committee had provided a real way to specify this...) */
    +  /* Note application may override our guesses. */
    +  switch (cinfo->num_components) {
    +  case 1:
    +    cinfo->jpeg_color_space = JCS_GRAYSCALE;
    +    cinfo->out_color_space = JCS_GRAYSCALE;
    +    break;
    +
    +  case 3:
    +    if (cinfo->saw_JFIF_marker) {
    +      cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
    +    } else if (cinfo->saw_Adobe_marker) {
    +      switch (cinfo->Adobe_transform) {
    +      case 0:
    +        cinfo->jpeg_color_space = JCS_RGB;
    +        break;
    +      case 1:
    +        cinfo->jpeg_color_space = JCS_YCbCr;
    +        break;
    +      default:
    +        WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
    +        cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
    +        break;
    +      }
    +    } else {
    +      /* Saw no special markers, try to guess from the component IDs */
    +      int cid0 = cinfo->comp_info[0].component_id;
    +      int cid1 = cinfo->comp_info[1].component_id;
    +      int cid2 = cinfo->comp_info[2].component_id;
    +
    +      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
    +        cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
    +      else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
    +        cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
    +      else {
    +        TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
    +        cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
    +      }
    +    }
    +    /* Always guess RGB is proper output colorspace. */
    +    cinfo->out_color_space = JCS_RGB;
    +    break;
    +
    +  case 4:
    +    if (cinfo->saw_Adobe_marker) {
    +      switch (cinfo->Adobe_transform) {
    +      case 0:
    +        cinfo->jpeg_color_space = JCS_CMYK;
    +        break;
    +      case 2:
    +        cinfo->jpeg_color_space = JCS_YCCK;
    +        break;
    +      default:
    +        WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
    +        cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
    +        break;
    +      }
    +    } else {
    +      /* No special markers, assume straight CMYK. */
    +      cinfo->jpeg_color_space = JCS_CMYK;
    +    }
    +    cinfo->out_color_space = JCS_CMYK;
    +    break;
    +
    +  default:
    +    cinfo->jpeg_color_space = JCS_UNKNOWN;
    +    cinfo->out_color_space = JCS_UNKNOWN;
    +    break;
    +  }
    +
    +  /* Set defaults for other decompression parameters. */
    +  cinfo->scale_num = 1;         /* 1:1 scaling */
    +  cinfo->scale_denom = 1;
    +  cinfo->output_gamma = 1.0;
    +  cinfo->buffered_image = FALSE;
    +  cinfo->raw_data_out = FALSE;
    +  cinfo->dct_method = JDCT_DEFAULT;
    +  cinfo->do_fancy_upsampling = TRUE;
    +  cinfo->do_block_smoothing = TRUE;
    +  cinfo->quantize_colors = FALSE;
    +  /* We set these in case application only sets quantize_colors. */
    +  cinfo->dither_mode = JDITHER_FS;
    +#ifdef QUANT_2PASS_SUPPORTED
    +  cinfo->two_pass_quantize = TRUE;
    +#else
    +  cinfo->two_pass_quantize = FALSE;
    +#endif
    +  cinfo->desired_number_of_colors = 256;
    +  cinfo->colormap = NULL;
    +  /* Initialize for no mode change in buffered-image mode. */
    +  cinfo->enable_1pass_quant = FALSE;
    +  cinfo->enable_external_quant = FALSE;
    +  cinfo->enable_2pass_quant = FALSE;
    +}
    +
    +
    +/*
    + * Decompression startup: read start of JPEG datastream to see what's there.
    + * Need only initialize JPEG object and supply a data source before calling.
    + *
    + * This routine will read as far as the first SOS marker (ie, actual start of
    + * compressed data), and will save all tables and parameters in the JPEG
    + * object.  It will also initialize the decompression parameters to default
    + * values, and finally return JPEG_HEADER_OK.  On return, the application may
    + * adjust the decompression parameters and then call jpeg_start_decompress.
    + * (Or, if the application only wanted to determine the image parameters,
    + * the data need not be decompressed.  In that case, call jpeg_abort or
    + * jpeg_destroy to release any temporary space.)
    + * If an abbreviated (tables only) datastream is presented, the routine will
    + * return JPEG_HEADER_TABLES_ONLY upon reaching EOI.  The application may then
    + * re-use the JPEG object to read the abbreviated image datastream(s).
    + * It is unnecessary (but OK) to call jpeg_abort in this case.
    + * The JPEG_SUSPENDED return code only occurs if the data source module
    + * requests suspension of the decompressor.  In this case the application
    + * should load more source data and then re-call jpeg_read_header to resume
    + * processing.
    + * If a non-suspending data source is used and require_image is TRUE, then the
    + * return code need not be inspected since only JPEG_HEADER_OK is possible.
    + *
    + * This routine is now just a front end to jpeg_consume_input, with some
    + * extra error checking.
    + */
    +
    +GLOBAL(int)
    +jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
    +{
    +  int retcode;
    +
    +  if (cinfo->global_state != DSTATE_START &&
    +      cinfo->global_state != DSTATE_INHEADER)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  retcode = jpeg_consume_input(cinfo);
    +
    +  switch (retcode) {
    +  case JPEG_REACHED_SOS:
    +    retcode = JPEG_HEADER_OK;
    +    break;
    +  case JPEG_REACHED_EOI:
    +    if (require_image)          /* Complain if application wanted an image */
    +      ERREXIT(cinfo, JERR_NO_IMAGE);
    +    /* Reset to start state; it would be safer to require the application to
    +     * call jpeg_abort, but we can't change it now for compatibility reasons.
    +     * A side effect is to free any temporary memory (there shouldn't be any).
    +     */
    +    jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
    +    retcode = JPEG_HEADER_TABLES_ONLY;
    +    break;
    +  case JPEG_SUSPENDED:
    +    /* no work */
    +    break;
    +  }
    +
    +  return retcode;
    +}
    +
    +
    +/*
    + * Consume data in advance of what the decompressor requires.
    + * This can be called at any time once the decompressor object has
    + * been created and a data source has been set up.
    + *
    + * This routine is essentially a state machine that handles a couple
    + * of critical state-transition actions, namely initial setup and
    + * transition from header scanning to ready-for-start_decompress.
    + * All the actual input is done via the input controller's consume_input
    + * method.
    + */
    +
    +GLOBAL(int)
    +jpeg_consume_input (j_decompress_ptr cinfo)
    +{
    +  int retcode = JPEG_SUSPENDED;
    +
    +  /* NB: every possible DSTATE value should be listed in this switch */
    +  switch (cinfo->global_state) {
    +  case DSTATE_START:
    +    /* Start-of-datastream actions: reset appropriate modules */
    +    (*cinfo->inputctl->reset_input_controller) (cinfo);
    +    /* Initialize application's data source module */
    +    (*cinfo->src->init_source) (cinfo);
    +    cinfo->global_state = DSTATE_INHEADER;
    +    /*FALLTHROUGH*/
    +  case DSTATE_INHEADER:
    +    retcode = (*cinfo->inputctl->consume_input) (cinfo);
    +    if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
    +      /* Set up default parameters based on header data */
    +      default_decompress_parms(cinfo);
    +      /* Set global state: ready for start_decompress */
    +      cinfo->global_state = DSTATE_READY;
    +    }
    +    break;
    +  case DSTATE_READY:
    +    /* Can't advance past first SOS until start_decompress is called */
    +    retcode = JPEG_REACHED_SOS;
    +    break;
    +  case DSTATE_PRELOAD:
    +  case DSTATE_PRESCAN:
    +  case DSTATE_SCANNING:
    +  case DSTATE_RAW_OK:
    +  case DSTATE_BUFIMAGE:
    +  case DSTATE_BUFPOST:
    +  case DSTATE_STOPPING:
    +    retcode = (*cinfo->inputctl->consume_input) (cinfo);
    +    break;
    +  default:
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  }
    +  return retcode;
    +}
    +
    +
    +/*
    + * Have we finished reading the input file?
    + */
    +
    +GLOBAL(boolean)
    +jpeg_input_complete (j_decompress_ptr cinfo)
    +{
    +  /* Check for valid jpeg object */
    +  if (cinfo->global_state < DSTATE_START ||
    +      cinfo->global_state > DSTATE_STOPPING)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  return cinfo->inputctl->eoi_reached;
    +}
    +
    +
    +/*
    + * Is there more than one scan?
    + */
    +
    +GLOBAL(boolean)
    +jpeg_has_multiple_scans (j_decompress_ptr cinfo)
    +{
    +  /* Only valid after jpeg_read_header completes */
    +  if (cinfo->global_state < DSTATE_READY ||
    +      cinfo->global_state > DSTATE_STOPPING)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  return cinfo->inputctl->has_multiple_scans;
    +}
    +
    +
    +/*
    + * Finish JPEG decompression.
    + *
    + * This will normally just verify the file trailer and release temp storage.
    + *
    + * Returns FALSE if suspended.  The return value need be inspected only if
    + * a suspending data source is used.
    + */
    +
    +GLOBAL(boolean)
    +jpeg_finish_decompress (j_decompress_ptr cinfo)
    +{
    +  if ((cinfo->global_state == DSTATE_SCANNING ||
    +       cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
    +    /* Terminate final pass of non-buffered mode */
    +    if (cinfo->output_scanline < cinfo->output_height)
    +      ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
    +    (*cinfo->master->finish_output_pass) (cinfo);
    +    cinfo->global_state = DSTATE_STOPPING;
    +  } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
    +    /* Finishing after a buffered-image operation */
    +    cinfo->global_state = DSTATE_STOPPING;
    +  } else if (cinfo->global_state != DSTATE_STOPPING) {
    +    /* STOPPING = repeat call after a suspension, anything else is error */
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  }
    +  /* Read until EOI */
    +  while (! cinfo->inputctl->eoi_reached) {
    +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
    +      return FALSE;             /* Suspend, come back later */
    +  }
    +  /* Do final cleanup */
    +  (*cinfo->src->term_source) (cinfo);
    +  /* We can use jpeg_abort to release memory and reset global_state */
    +  jpeg_abort((j_common_ptr) cinfo);
    +  return TRUE;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdapistd.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdapistd.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdapistd.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdapistd.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,279 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdapistd.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains application interface code for the decompression half
    + * of the JPEG library.  These are the "standard" API routines that are
    + * used in the normal full-decompression case.  They are not used by a
    + * transcoding-only application.  Note that if an application links in
    + * jpeg_start_decompress, it will end up linking in the entire decompressor.
    + * We thus must separate this file from jdapimin.c to avoid linking the
    + * whole decompression library into a transcoder.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Forward declarations */
    +LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
    +
    +
    +/*
    + * Decompression initialization.
    + * jpeg_read_header must be completed before calling this.
    + *
    + * If a multipass operating mode was selected, this will do all but the
    + * last pass, and thus may take a great deal of time.
    + *
    + * Returns FALSE if suspended.  The return value need be inspected only if
    + * a suspending data source is used.
    + */
    +
    +GLOBAL(boolean)
    +jpeg_start_decompress (j_decompress_ptr cinfo)
    +{
    +  if (cinfo->global_state == DSTATE_READY) {
    +    /* First call: initialize master control, select active modules */
    +    jinit_master_decompress(cinfo);
    +    if (cinfo->buffered_image) {
    +      /* No more work here; expecting jpeg_start_output next */
    +      cinfo->global_state = DSTATE_BUFIMAGE;
    +      return TRUE;
    +    }
    +    cinfo->global_state = DSTATE_PRELOAD;
    +  }
    +  if (cinfo->global_state == DSTATE_PRELOAD) {
    +    /* If file has multiple scans, absorb them all into the coef buffer */
    +    if (cinfo->inputctl->has_multiple_scans) {
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +      for (;;) {
    +        int retcode;
    +        /* Call progress monitor hook if present */
    +        if (cinfo->progress != NULL)
    +          (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +        /* Absorb some more input */
    +        retcode = (*cinfo->inputctl->consume_input) (cinfo);
    +        if (retcode == JPEG_SUSPENDED)
    +          return FALSE;
    +        if (retcode == JPEG_REACHED_EOI)
    +          break;
    +        /* Advance progress counter if appropriate */
    +        if (cinfo->progress != NULL &&
    +            (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
    +          if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
    +            /* jdmaster underestimated number of scans; ratchet up one scan */
    +            cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
    +          }
    +        }
    +      }
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif /* D_MULTISCAN_FILES_SUPPORTED */
    +    }
    +    cinfo->output_scan_number = cinfo->input_scan_number;
    +  } else if (cinfo->global_state != DSTATE_PRESCAN)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  /* Perform any dummy output passes, and set up for the final pass */
    +  return output_pass_setup(cinfo);
    +}
    +
    +
    +/*
    + * Set up for an output pass, and perform any dummy pass(es) needed.
    + * Common subroutine for jpeg_start_decompress and jpeg_start_output.
    + * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
    + * Exit: If done, returns TRUE and sets global_state for proper output mode.
    + *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
    + */
    +
    +LOCAL(boolean)
    +output_pass_setup (j_decompress_ptr cinfo)
    +{
    +  if (cinfo->global_state != DSTATE_PRESCAN) {
    +    /* First call: do pass setup */
    +    (*cinfo->master->prepare_for_output_pass) (cinfo);
    +    cinfo->output_scanline = 0;
    +    cinfo->global_state = DSTATE_PRESCAN;
    +  }
    +  /* Loop over any required dummy passes */
    +  while (cinfo->master->is_dummy_pass) {
    +#ifdef QUANT_2PASS_SUPPORTED
    +    /* Crank through the dummy pass */
    +    while (cinfo->output_scanline < cinfo->output_height) {
    +      JDIMENSION last_scanline;
    +      /* Call progress monitor hook if present */
    +      if (cinfo->progress != NULL) {
    +        cinfo->progress->pass_counter = (long) cinfo->output_scanline;
    +        cinfo->progress->pass_limit = (long) cinfo->output_height;
    +        (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +      }
    +      /* Process some data */
    +      last_scanline = cinfo->output_scanline;
    +      (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
    +                                    &cinfo->output_scanline, (JDIMENSION) 0);
    +      if (cinfo->output_scanline == last_scanline)
    +        return FALSE;           /* No progress made, must suspend */
    +    }
    +    /* Finish up dummy pass, and set up for another one */
    +    (*cinfo->master->finish_output_pass) (cinfo);
    +    (*cinfo->master->prepare_for_output_pass) (cinfo);
    +    cinfo->output_scanline = 0;
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif /* QUANT_2PASS_SUPPORTED */
    +  }
    +  /* Ready for application to drive output pass through
    +   * jpeg_read_scanlines or jpeg_read_raw_data.
    +   */
    +  cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Read some scanlines of data from the JPEG decompressor.
    + *
    + * The return value will be the number of lines actually read.
    + * This may be less than the number requested in several cases,
    + * including bottom of image, data source suspension, and operating
    + * modes that emit multiple scanlines at a time.
    + *
    + * Note: we warn about excess calls to jpeg_read_scanlines() since
    + * this likely signals an application programmer error.  However,
    + * an oversize buffer (max_lines > scanlines remaining) is not an error.
    + */
    +
    +GLOBAL(JDIMENSION)
    +jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
    +                     JDIMENSION max_lines)
    +{
    +  JDIMENSION row_ctr;
    +
    +  if (cinfo->global_state != DSTATE_SCANNING)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  if (cinfo->output_scanline >= cinfo->output_height) {
    +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
    +    return 0;
    +  }
    +
    +  /* Call progress monitor hook if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
    +    cinfo->progress->pass_limit = (long) cinfo->output_height;
    +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +  }
    +
    +  /* Process some data */
    +  row_ctr = 0;
    +  (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
    +  cinfo->output_scanline += row_ctr;
    +  return row_ctr;
    +}
    +
    +
    +/*
    + * Alternate entry point to read raw data.
    + * Processes exactly one iMCU row per call, unless suspended.
    + */
    +
    +GLOBAL(JDIMENSION)
    +jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
    +                    JDIMENSION max_lines)
    +{
    +  JDIMENSION lines_per_iMCU_row;
    +
    +  if (cinfo->global_state != DSTATE_RAW_OK)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  if (cinfo->output_scanline >= cinfo->output_height) {
    +    WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
    +    return 0;
    +  }
    +
    +  /* Call progress monitor hook if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->pass_counter = (long) cinfo->output_scanline;
    +    cinfo->progress->pass_limit = (long) cinfo->output_height;
    +    (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +  }
    +
    +  /* Verify that at least one iMCU row can be returned. */
    +  lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
    +  if (max_lines < lines_per_iMCU_row)
    +    ERREXIT(cinfo, JERR_BUFFER_SIZE);
    +
    +  /* Decompress directly into user's buffer. */
    +  if (! (*cinfo->coef->decompress_data) (cinfo, data))
    +    return 0;                   /* suspension forced, can do nothing more */
    +
    +  /* OK, we processed one iMCU row. */
    +  cinfo->output_scanline += lines_per_iMCU_row;
    +  return lines_per_iMCU_row;
    +}
    +
    +
    +/* Additional entry points for buffered-image mode. */
    +
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +
    +/*
    + * Initialize for an output pass in buffered-image mode.
    + */
    +
    +GLOBAL(boolean)
    +jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
    +{
    +  if (cinfo->global_state != DSTATE_BUFIMAGE &&
    +      cinfo->global_state != DSTATE_PRESCAN)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  /* Limit scan number to valid range */
    +  if (scan_number <= 0)
    +    scan_number = 1;
    +  if (cinfo->inputctl->eoi_reached &&
    +      scan_number > cinfo->input_scan_number)
    +    scan_number = cinfo->input_scan_number;
    +  cinfo->output_scan_number = scan_number;
    +  /* Perform any dummy output passes, and set up for the real pass */
    +  return output_pass_setup(cinfo);
    +}
    +
    +
    +/*
    + * Finish up after an output pass in buffered-image mode.
    + *
    + * Returns FALSE if suspended.  The return value need be inspected only if
    + * a suspending data source is used.
    + */
    +
    +GLOBAL(boolean)
    +jpeg_finish_output (j_decompress_ptr cinfo)
    +{
    +  if ((cinfo->global_state == DSTATE_SCANNING ||
    +       cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
    +    /* Terminate this pass. */
    +    /* We do not require the whole pass to have been completed. */
    +    (*cinfo->master->finish_output_pass) (cinfo);
    +    cinfo->global_state = DSTATE_BUFPOST;
    +  } else if (cinfo->global_state != DSTATE_BUFPOST) {
    +    /* BUFPOST = repeat call after a suspension, anything else is error */
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  }
    +  /* Read markers looking for SOS or EOI */
    +  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
    +         ! cinfo->inputctl->eoi_reached) {
    +    if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
    +      return FALSE;             /* Suspend, come back later */
    +  }
    +  cinfo->global_state = DSTATE_BUFIMAGE;
    +  return TRUE;
    +}
    +
    +#endif /* D_MULTISCAN_FILES_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdcoefct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdcoefct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdcoefct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdcoefct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,740 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdcoefct.c
    + *
    + * Copyright (C) 1994-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the coefficient buffer controller for decompression.
    + * This controller is the top level of the JPEG decompressor proper.
    + * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
    + *
    + * In buffered-image mode, this controller is the interface between
    + * input-oriented processing and output-oriented processing.
    + * Also, the input side (only) is used when reading a file for transcoding.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +/* Block smoothing is only applicable for progressive JPEG, so: */
    +#ifndef D_PROGRESSIVE_SUPPORTED
    +#undef BLOCK_SMOOTHING_SUPPORTED
    +#endif
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_d_coef_controller pub; /* public fields */
    +
    +  /* These variables keep track of the current location of the input side. */
    +  /* cinfo->input_iMCU_row is also used for this. */
    +  JDIMENSION MCU_ctr;           /* counts MCUs processed in current row */
    +  int MCU_vert_offset;          /* counts MCU rows within iMCU row */
    +  int MCU_rows_per_iMCU_row;    /* number of such rows needed */
    +
    +  /* The output side's location is represented by cinfo->output_iMCU_row. */
    +
    +  /* In single-pass modes, it's sufficient to buffer just one MCU.
    +   * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
    +   * and let the entropy decoder write into that workspace each time.
    +   * (On 80x86, the workspace is FAR even though it's not really very big;
    +   * this is to keep the module interfaces unchanged when a large coefficient
    +   * buffer is necessary.)
    +   * In multi-pass modes, this array points to the current MCU's blocks
    +   * within the virtual arrays; it is used only by the input side.
    +   */
    +  JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
    +
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +  /* In multi-pass modes, we need a virtual block array for each component. */
    +  jvirt_barray_ptr whole_image[MAX_COMPONENTS];
    +#endif
    +
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +  /* When doing block smoothing, we latch coefficient Al values here */
    +  int * coef_bits_latch;
    +#define SAVED_COEFS  6          /* we save coef_bits[0..5] */
    +#endif
    +} my_coef_controller;
    +
    +typedef my_coef_controller * my_coef_ptr;
    +
    +/* Forward declarations */
    +METHODDEF(int) decompress_onepass
    +        JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +METHODDEF(int) decompress_data
    +        JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
    +#endif
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
    +METHODDEF(int) decompress_smooth_data
    +        JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
    +#endif
    +
    +
    +LOCAL(void)
    +start_iMCU_row (j_decompress_ptr cinfo)
    +/* Reset within-iMCU-row counters for a new row (input side) */
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  /* In an interleaved scan, an MCU row is the same as an iMCU row.
    +   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
    +   * But at the bottom of the image, process only what's left.
    +   */
    +  if (cinfo->comps_in_scan > 1) {
    +    coef->MCU_rows_per_iMCU_row = 1;
    +  } else {
    +    if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
    +    else
    +      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
    +  }
    +
    +  coef->MCU_ctr = 0;
    +  coef->MCU_vert_offset = 0;
    +}
    +
    +
    +/*
    + * Initialize for an input processing pass.
    + */
    +
    +METHODDEF(void)
    +start_input_pass (j_decompress_ptr cinfo)
    +{
    +  cinfo->input_iMCU_row = 0;
    +  start_iMCU_row(cinfo);
    +}
    +
    +
    +/*
    + * Initialize for an output processing pass.
    + */
    +
    +METHODDEF(void)
    +start_output_pass (j_decompress_ptr cinfo)
    +{
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +
    +  /* If multipass, check to see whether to use block smoothing on this pass */
    +  if (coef->pub.coef_arrays != NULL) {
    +    if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
    +      coef->pub.decompress_data = decompress_smooth_data;
    +    else
    +      coef->pub.decompress_data = decompress_data;
    +  }
    +#endif
    +  cinfo->output_iMCU_row = 0;
    +}
    +
    +
    +/*
    + * Decompress and return some data in the single-pass case.
    + * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
    + * Input and output must run in lockstep since we have only a one-MCU buffer.
    + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
    + *
    + * NB: output_buf contains a plane for each component in image,
    + * which we index according to the component's SOF position.
    + */
    +
    +METHODDEF(int)
    +decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    +  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  int blkn, ci, xindex, yindex, yoffset, useful_width;
    +  JSAMPARRAY output_ptr;
    +  JDIMENSION start_col, output_col;
    +  jpeg_component_info *compptr;
    +  inverse_DCT_method_ptr inverse_DCT;
    +
    +  /* Loop to process as much as one whole iMCU row */
    +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    +       yoffset++) {
    +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
    +         MCU_col_num++) {
    +      /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
    +      jzero_far((void FAR *) coef->MCU_buffer[0],
    +                (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
    +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
    +        /* Suspension forced; update state counters and exit */
    +        coef->MCU_vert_offset = yoffset;
    +        coef->MCU_ctr = MCU_col_num;
    +        return JPEG_SUSPENDED;
    +      }
    +      /* Determine where data should go in output_buf and do the IDCT thing.
    +       * We skip dummy blocks at the right and bottom edges (but blkn gets
    +       * incremented past them!).  Note the inner loop relies on having
    +       * allocated the MCU_buffer[] blocks sequentially.
    +       */
    +      blkn = 0;                 /* index of current DCT block within MCU */
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +        compptr = cinfo->cur_comp_info[ci];
    +        /* Don't bother to IDCT an uninteresting component. */
    +        if (! compptr->component_needed) {
    +          blkn += compptr->MCU_blocks;
    +          continue;
    +        }
    +        inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
    +        useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
    +                                                    : compptr->last_col_width;
    +        output_ptr = output_buf[compptr->component_index] +
    +          yoffset * compptr->DCT_scaled_size;
    +        start_col = MCU_col_num * compptr->MCU_sample_width;
    +        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    +          if (cinfo->input_iMCU_row < last_iMCU_row ||
    +              yoffset+yindex < compptr->last_row_height) {
    +            output_col = start_col;
    +            for (xindex = 0; xindex < useful_width; xindex++) {
    +              (*inverse_DCT) (cinfo, compptr,
    +                              (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
    +                              output_ptr, output_col);
    +              output_col += compptr->DCT_scaled_size;
    +            }
    +          }
    +          blkn += compptr->MCU_width;
    +          output_ptr += compptr->DCT_scaled_size;
    +        }
    +      }
    +    }
    +    /* Completed an MCU row, but perhaps not an iMCU row */
    +    coef->MCU_ctr = 0;
    +  }
    +  /* Completed the iMCU row, advance counters for next one */
    +  cinfo->output_iMCU_row++;
    +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
    +    start_iMCU_row(cinfo);
    +    return JPEG_ROW_COMPLETED;
    +  }
    +  /* Completed the scan */
    +  (*cinfo->inputctl->finish_input_pass) (cinfo);
    +  return JPEG_SCAN_COMPLETED;
    +}
    +
    +
    +/*
    + * Dummy consume-input routine for single-pass operation.
    + */
    +
    +METHODDEF(int)
    +dummy_consume_data (j_decompress_ptr cinfo)
    +{
    +  return JPEG_SUSPENDED;        /* Always indicate nothing was done */
    +}
    +
    +
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +
    +/*
    + * Consume input data and store it in the full-image coefficient buffer.
    + * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
    + * ie, v_samp_factor block rows for each component in the scan.
    + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
    + */
    +
    +METHODDEF(int)
    +consume_data (j_decompress_ptr cinfo)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    +  int blkn, ci, xindex, yindex, yoffset;
    +  JDIMENSION start_col;
    +  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    +  JBLOCKROW buffer_ptr;
    +  jpeg_component_info *compptr;
    +
    +  /* Align the virtual buffers for the components used in this scan. */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    buffer[ci] = (*cinfo->mem->access_virt_barray)
    +      ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
    +       cinfo->input_iMCU_row * compptr->v_samp_factor,
    +       (JDIMENSION) compptr->v_samp_factor, TRUE);
    +    /* Note: entropy decoder expects buffer to be zeroed,
    +     * but this is handled automatically by the memory manager
    +     * because we requested a pre-zeroed array.
    +     */
    +  }
    +
    +  /* Loop to process one whole iMCU row */
    +  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    +       yoffset++) {
    +    for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
    +         MCU_col_num++) {
    +      /* Construct list of pointers to DCT blocks belonging to this MCU */
    +      blkn = 0;                 /* index of current DCT block within MCU */
    +      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +        compptr = cinfo->cur_comp_info[ci];
    +        start_col = MCU_col_num * compptr->MCU_width;
    +        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    +          buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
    +          for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
    +            coef->MCU_buffer[blkn++] = buffer_ptr++;
    +          }
    +        }
    +      }
    +      /* Try to fetch the MCU. */
    +      if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
    +        /* Suspension forced; update state counters and exit */
    +        coef->MCU_vert_offset = yoffset;
    +        coef->MCU_ctr = MCU_col_num;
    +        return JPEG_SUSPENDED;
    +      }
    +    }
    +    /* Completed an MCU row, but perhaps not an iMCU row */
    +    coef->MCU_ctr = 0;
    +  }
    +  /* Completed the iMCU row, advance counters for next one */
    +  if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
    +    start_iMCU_row(cinfo);
    +    return JPEG_ROW_COMPLETED;
    +  }
    +  /* Completed the scan */
    +  (*cinfo->inputctl->finish_input_pass) (cinfo);
    +  return JPEG_SCAN_COMPLETED;
    +}
    +
    +
    +/*
    + * Decompress and return some data in the multi-pass case.
    + * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
    + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
    + *
    + * NB: output_buf contains a plane for each component in image.
    + */
    +
    +METHODDEF(int)
    +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  JDIMENSION block_num;
    +  int ci, block_row, block_rows;
    +  JBLOCKARRAY buffer;
    +  JBLOCKROW buffer_ptr;
    +  JSAMPARRAY output_ptr;
    +  JDIMENSION output_col;
    +  jpeg_component_info *compptr;
    +  inverse_DCT_method_ptr inverse_DCT;
    +
    +  /* Force some input to be done if we are getting ahead of the input. */
    +  while (cinfo->input_scan_number < cinfo->output_scan_number ||
    +         (cinfo->input_scan_number == cinfo->output_scan_number &&
    +          cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
    +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
    +      return JPEG_SUSPENDED;
    +  }
    +
    +  /* OK, output from the virtual arrays. */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Don't bother to IDCT an uninteresting component. */
    +    if (! compptr->component_needed)
    +      continue;
    +    /* Align the virtual buffer for this component. */
    +    buffer = (*cinfo->mem->access_virt_barray)
    +      ((j_common_ptr) cinfo, coef->whole_image[ci],
    +       cinfo->output_iMCU_row * compptr->v_samp_factor,
    +       (JDIMENSION) compptr->v_samp_factor, FALSE);
    +    /* Count non-dummy DCT block rows in this iMCU row. */
    +    if (cinfo->output_iMCU_row < last_iMCU_row)
    +      block_rows = compptr->v_samp_factor;
    +    else {
    +      /* NB: can't use last_row_height here; it is input-side-dependent! */
    +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
    +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    +    }
    +    inverse_DCT = cinfo->idct->inverse_DCT[ci];
    +    output_ptr = output_buf[ci];
    +    /* Loop over all DCT blocks to be processed. */
    +    for (block_row = 0; block_row < block_rows; block_row++) {
    +      buffer_ptr = buffer[block_row];
    +      output_col = 0;
    +      for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
    +        (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
    +                        output_ptr, output_col);
    +        buffer_ptr++;
    +        output_col += compptr->DCT_scaled_size;
    +      }
    +      output_ptr += compptr->DCT_scaled_size;
    +    }
    +  }
    +
    +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
    +    return JPEG_ROW_COMPLETED;
    +  return JPEG_SCAN_COMPLETED;
    +}
    +
    +#endif /* D_MULTISCAN_FILES_SUPPORTED */
    +
    +
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +
    +/*
    + * This code applies interblock smoothing as described by section K.8
    + * of the JPEG standard: the first 5 AC coefficients are estimated from
    + * the DC values of a DCT block and its 8 neighboring blocks.
    + * We apply smoothing only for progressive JPEG decoding, and only if
    + * the coefficients it can estimate are not yet known to full precision.
    + */
    +
    +/* Natural-order array positions of the first 5 zigzag-order coefficients */
    +#define Q01_POS  1
    +#define Q10_POS  8
    +#define Q20_POS  16
    +#define Q11_POS  9
    +#define Q02_POS  2
    +
    +/*
    + * Determine whether block smoothing is applicable and safe.
    + * We also latch the current states of the coef_bits[] entries for the
    + * AC coefficients; otherwise, if the input side of the decompressor
    + * advances into a new scan, we might think the coefficients are known
    + * more accurately than they really are.
    + */
    +
    +LOCAL(boolean)
    +smoothing_ok (j_decompress_ptr cinfo)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  boolean smoothing_useful = FALSE;
    +  int ci, coefi;
    +  jpeg_component_info *compptr;
    +  JQUANT_TBL * qtable;
    +  int * coef_bits;
    +  int * coef_bits_latch;
    +
    +  if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
    +    return FALSE;
    +
    +  /* Allocate latch area if not already done */
    +  if (coef->coef_bits_latch == NULL)
    +    coef->coef_bits_latch = (int *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  cinfo->num_components *
    +                                  (SAVED_COEFS * SIZEOF(int)));
    +  coef_bits_latch = coef->coef_bits_latch;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* All components' quantization values must already be latched. */
    +    if ((qtable = compptr->quant_table) == NULL)
    +      return FALSE;
    +    /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
    +    if (qtable->quantval[0] == 0 ||
    +        qtable->quantval[Q01_POS] == 0 ||
    +        qtable->quantval[Q10_POS] == 0 ||
    +        qtable->quantval[Q20_POS] == 0 ||
    +        qtable->quantval[Q11_POS] == 0 ||
    +        qtable->quantval[Q02_POS] == 0)
    +      return FALSE;
    +    /* DC values must be at least partly known for all components. */
    +    coef_bits = cinfo->coef_bits[ci];
    +    if (coef_bits[0] < 0)
    +      return FALSE;
    +    /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
    +    for (coefi = 1; coefi <= 5; coefi++) {
    +      coef_bits_latch[coefi] = coef_bits[coefi];
    +      if (coef_bits[coefi] != 0)
    +        smoothing_useful = TRUE;
    +    }
    +    coef_bits_latch += SAVED_COEFS;
    +  }
    +
    +  return smoothing_useful;
    +}
    +
    +
    +/*
    + * Variant of decompress_data for use when doing block smoothing.
    + */
    +
    +METHODDEF(int)
    +decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
    +{
    +  my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
    +  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    +  JDIMENSION block_num, last_block_column;
    +  int ci, block_row, block_rows, access_rows;
    +  JBLOCKARRAY buffer;
    +  JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
    +  JSAMPARRAY output_ptr;
    +  JDIMENSION output_col;
    +  jpeg_component_info *compptr;
    +  inverse_DCT_method_ptr inverse_DCT;
    +  boolean first_row, last_row;
    +  JBLOCK workspace;
    +  int *coef_bits;
    +  JQUANT_TBL *quanttbl;
    +  INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
    +  int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
    +  int Al, pred;
    +
    +  /* Force some input to be done if we are getting ahead of the input. */
    +  while (cinfo->input_scan_number <= cinfo->output_scan_number &&
    +         ! cinfo->inputctl->eoi_reached) {
    +    if (cinfo->input_scan_number == cinfo->output_scan_number) {
    +      /* If input is working on current scan, we ordinarily want it to
    +       * have completed the current row.  But if input scan is DC,
    +       * we want it to keep one row ahead so that next block row's DC
    +       * values are up to date.
    +       */
    +      JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
    +      if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
    +        break;
    +    }
    +    if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
    +      return JPEG_SUSPENDED;
    +  }
    +
    +  /* OK, output from the virtual arrays. */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Don't bother to IDCT an uninteresting component. */
    +    if (! compptr->component_needed)
    +      continue;
    +    /* Count non-dummy DCT block rows in this iMCU row. */
    +    if (cinfo->output_iMCU_row < last_iMCU_row) {
    +      block_rows = compptr->v_samp_factor;
    +      access_rows = block_rows * 2; /* this and next iMCU row */
    +      last_row = FALSE;
    +    } else {
    +      /* NB: can't use last_row_height here; it is input-side-dependent! */
    +      block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
    +      if (block_rows == 0) block_rows = compptr->v_samp_factor;
    +      access_rows = block_rows; /* this iMCU row only */
    +      last_row = TRUE;
    +    }
    +    /* Align the virtual buffer for this component. */
    +    if (cinfo->output_iMCU_row > 0) {
    +      access_rows += compptr->v_samp_factor; /* prior iMCU row too */
    +      buffer = (*cinfo->mem->access_virt_barray)
    +        ((j_common_ptr) cinfo, coef->whole_image[ci],
    +         (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
    +         (JDIMENSION) access_rows, FALSE);
    +      buffer += compptr->v_samp_factor; /* point to current iMCU row */
    +      first_row = FALSE;
    +    } else {
    +      buffer = (*cinfo->mem->access_virt_barray)
    +        ((j_common_ptr) cinfo, coef->whole_image[ci],
    +         (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
    +      first_row = TRUE;
    +    }
    +    /* Fetch component-dependent info */
    +    coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
    +    quanttbl = compptr->quant_table;
    +    Q00 = quanttbl->quantval[0];
    +    Q01 = quanttbl->quantval[Q01_POS];
    +    Q10 = quanttbl->quantval[Q10_POS];
    +    Q20 = quanttbl->quantval[Q20_POS];
    +    Q11 = quanttbl->quantval[Q11_POS];
    +    Q02 = quanttbl->quantval[Q02_POS];
    +    inverse_DCT = cinfo->idct->inverse_DCT[ci];
    +    output_ptr = output_buf[ci];
    +    /* Loop over all DCT blocks to be processed. */
    +    for (block_row = 0; block_row < block_rows; block_row++) {
    +      buffer_ptr = buffer[block_row];
    +      if (first_row && block_row == 0)
    +        prev_block_row = buffer_ptr;
    +      else
    +        prev_block_row = buffer[block_row-1];
    +      if (last_row && block_row == block_rows-1)
    +        next_block_row = buffer_ptr;
    +      else
    +        next_block_row = buffer[block_row+1];
    +      /* We fetch the surrounding DC values using a sliding-register approach.
    +       * Initialize all nine here so as to do the right thing on narrow pics.
    +       */
    +      DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
    +      DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
    +      DC7 = DC8 = DC9 = (int) next_block_row[0][0];
    +      output_col = 0;
    +      last_block_column = compptr->width_in_blocks - 1;
    +      for (block_num = 0; block_num <= last_block_column; block_num++) {
    +        /* Fetch current DCT block into workspace so we can modify it. */
    +        jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
    +        /* Update DC values */
    +        if (block_num < last_block_column) {
    +          DC3 = (int) prev_block_row[1][0];
    +          DC6 = (int) buffer_ptr[1][0];
    +          DC9 = (int) next_block_row[1][0];
    +        }
    +        /* Compute coefficient estimates per K.8.
    +         * An estimate is applied only if coefficient is still zero,
    +         * and is not known to be fully accurate.
    +         */
    +        /* AC01 */
    +        if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
    +          num = 36 * Q00 * (DC4 - DC6);
    +          if (num >= 0) {
    +            pred = (int) (((Q01<<7) + num) / (Q01<<8));
    +            if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) {
    +            pred = (int) (((Q10<<7) + num) / (Q10<<8));
    +            if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) {
    +            pred = (int) (((Q20<<7) + num) / (Q20<<8));
    +            if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) {
    +            pred = (int) (((Q11<<7) + num) / (Q11<<8));
    +            if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) {
    +            pred = (int) (((Q02<<7) + num) / (Q02<<8));
    +            if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_scaled_size;
    +      }
    +      output_ptr += compptr->DCT_scaled_size;
    +    }
    +  }
    +
    +  if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
    +    return JPEG_ROW_COMPLETED;
    +  return JPEG_SCAN_COMPLETED;
    +}
    +
    +#endif /* BLOCK_SMOOTHING_SUPPORTED */
    +
    +
    +/*
    + * Initialize coefficient buffer controller.
    + */
    +
    +GLOBAL(void)
    +jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_coef_ptr coef;
    +
    +  coef = (my_coef_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_coef_controller));
    +  cinfo->coef = (struct jpeg_d_coef_controller *) coef;
    +  coef->pub.start_input_pass = start_input_pass;
    +  coef->pub.start_output_pass = start_output_pass;
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +  coef->coef_bits_latch = NULL;
    +#endif
    +
    +  /* Create the coefficient buffer. */
    +  if (need_full_buffer) {
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +    /* Allocate a full-image virtual array for each component, */
    +    /* padded to a multiple of samp_factor DCT blocks in each direction. */
    +    /* Note we ask for a pre-zeroed array. */
    +    int ci, access_rows;
    +    jpeg_component_info *compptr;
    +
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      access_rows = compptr->v_samp_factor;
    +#ifdef BLOCK_SMOOTHING_SUPPORTED
    +      /* If block smoothing could be used, need a bigger window */
    +      if (cinfo->progressive_mode)
    +        access_rows *= 3;
    +#endif
    +      coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
    +         (JDIMENSION) jround_up((long) compptr->width_in_blocks,
    +                                (long) compptr->h_samp_factor),
    +         (JDIMENSION) jround_up((long) compptr->height_in_blocks,
    +                                (long) compptr->v_samp_factor),
    +         (JDIMENSION) access_rows);
    +    }
    +    coef->pub.consume_data = consume_data;
    +    coef->pub.decompress_data = decompress_data;
    +    coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +  } else {
    +    /* We only need a single-MCU buffer. */
    +    JBLOCKROW buffer;
    +    int i;
    +
    +    buffer = (JBLOCKROW)
    +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
    +    for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
    +      coef->MCU_buffer[i] = buffer + i;
    +    }
    +    coef->pub.consume_data = dummy_consume_data;
    +    coef->pub.decompress_data = decompress_onepass;
    +    coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdcolor.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdcolor.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdcolor.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdcolor.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,398 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdcolor.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains output colorspace conversion routines.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private subobject */
    +
    +typedef struct {
    +  struct jpeg_color_deconverter pub; /* public fields */
    +
    +  /* Private state for YCC->RGB conversion */
    +  int * Cr_r_tab;               /* => table for Cr to R conversion */
    +  int * Cb_b_tab;               /* => table for Cb to B conversion */
    +  INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
    +  INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
    +} my_color_deconverter;
    +
    +typedef my_color_deconverter * my_cconvert_ptr;
    +
    +
    +/**************** YCbCr -> RGB conversion: most common case **************/
    +
    +/*
    + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
    + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
    + * The conversion equations to be implemented are therefore
    + *      R = Y                + 1.40200 * Cr
    + *      G = Y - 0.34414 * Cb - 0.71414 * Cr
    + *      B = Y + 1.77200 * Cb
    + * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
    + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
    + *
    + * To avoid floating-point arithmetic, we represent the fractional constants
    + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
    + * the products by 2^16, with appropriate rounding, to get the correct answer.
    + * Notice that Y, being an integral input, does not contribute any fraction
    + * so it need not participate in the rounding.
    + *
    + * For even more speed, we avoid doing any multiplications in the inner loop
    + * by precalculating the constants times Cb and Cr for all possible values.
    + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
    + * for 12-bit samples it is still acceptable.  It's not very reasonable for
    + * 16-bit samples, but if you want lossless storage you shouldn't be changing
    + * colorspace anyway.
    + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
    + * values for the G calculation are left scaled up, since we must add them
    + * together before rounding.
    + */
    +
    +#define SCALEBITS       16      /* speediest right-shift on some machines */
    +#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
    +#define FIX(x)          ((INT32) ((x) * (1L<RGB colorspace conversion.
    + */
    +
    +LOCAL(void)
    +build_ycc_rgb_table (j_decompress_ptr cinfo)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  int i;
    +  INT32 x;
    +  SHIFT_TEMPS
    +
    +  cconvert->Cr_r_tab = (int *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(int));
    +  cconvert->Cb_b_tab = (int *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(int));
    +  cconvert->Cr_g_tab = (INT32 *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(INT32));
    +  cconvert->Cb_g_tab = (INT32 *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(INT32));
    +
    +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    +    /* Cr=>R value is nearest int to 1.40200 * x */
    +    cconvert->Cr_r_tab[i] = (int)
    +                    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    +    /* Cb=>B value is nearest int to 1.77200 * x */
    +    cconvert->Cb_b_tab[i] = (int)
    +                    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
    +    /* Cr=>G value is scaled-up -0.71414 * x */
    +    cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
    +    /* Cb=>G value is scaled-up -0.34414 * x */
    +    /* We also add in ONE_HALF so that need not do it in inner loop */
    +    cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
    +  }
    +}
    +
    +
    +/*
    + * Convert some rows of samples to the output colorspace.
    + *
    + * Note that we change from noninterleaved, one-plane-per-component format
    + * to interleaved-pixel format.  The output buffer is therefore three times
    + * as wide as the input buffer.
    + * A starting row offset is provided only for the input buffer.  The caller
    + * can easily adjust the passed output_buf value to accommodate any row
    + * offset required on that side.
    + */
    +
    +METHODDEF(void)
    +ycc_rgb_convert (j_decompress_ptr cinfo,
    +                 JSAMPIMAGE input_buf, JDIMENSION input_row,
    +                 JSAMPARRAY output_buf, int num_rows)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  register int y, cb, cr;
    +  register JSAMPROW outptr;
    +  register JSAMPROW inptr0, inptr1, inptr2;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->output_width;
    +  /* copy these pointers into registers if possible */
    +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
    +  register int * Crrtab = cconvert->Cr_r_tab;
    +  register int * Cbbtab = cconvert->Cb_b_tab;
    +  register INT32 * Crgtab = cconvert->Cr_g_tab;
    +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
    +  SHIFT_TEMPS
    +
    +  while (--num_rows >= 0) {
    +    inptr0 = input_buf[0][input_row];
    +    inptr1 = input_buf[1][input_row];
    +    inptr2 = input_buf[2][input_row];
    +    input_row++;
    +    outptr = *output_buf++;
    +    for (col = 0; col < num_cols; col++) {
    +      y  = GETJSAMPLE(inptr0[col]);
    +      cb = GETJSAMPLE(inptr1[col]);
    +      cr = GETJSAMPLE(inptr2[col]);
    +      /* Range-limiting is essential due to noise introduced by DCT losses. */
    +      outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
    +      outptr[RGB_GREEN] = range_limit[y +
    +                              ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    +                                                 SCALEBITS))];
    +      outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
    +      outptr += RGB_PIXELSIZE;
    +    }
    +  }
    +}
    +
    +
    +/**************** Cases other than YCbCr -> RGB **************/
    +
    +
    +/*
    + * Color conversion for no colorspace change: just copy the data,
    + * converting from separate-planes to interleaved representation.
    + */
    +
    +METHODDEF(void)
    +null_convert (j_decompress_ptr cinfo,
    +              JSAMPIMAGE input_buf, JDIMENSION input_row,
    +              JSAMPARRAY output_buf, int num_rows)
    +{
    +  register JSAMPROW inptr, outptr;
    +  register JDIMENSION count;
    +  register int num_components = cinfo->num_components;
    +  JDIMENSION num_cols = cinfo->output_width;
    +  int ci;
    +
    +  while (--num_rows >= 0) {
    +    for (ci = 0; ci < num_components; ci++) {
    +      inptr = input_buf[ci][input_row];
    +      outptr = output_buf[0] + ci;
    +      for (count = num_cols; count > 0; count--) {
    +        *outptr = *inptr++;     /* needn't bother with GETJSAMPLE() here */
    +        outptr += num_components;
    +      }
    +    }
    +    input_row++;
    +    output_buf++;
    +  }
    +}
    +
    +
    +/*
    + * Color conversion for grayscale: just copy the data.
    + * This also works for YCbCr -> grayscale conversion, in which
    + * we just copy the Y (luminance) component and ignore chrominance.
    + */
    +
    +METHODDEF(void)
    +grayscale_convert (j_decompress_ptr cinfo,
    +                   JSAMPIMAGE input_buf, JDIMENSION input_row,
    +                   JSAMPARRAY output_buf, int num_rows)
    +{
    +  jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
    +                    num_rows, cinfo->output_width);
    +}
    +
    +/*
    + * Convert grayscale to RGB: just duplicate the graylevel three times.
    + * This is provided to support applications that don't want to cope
    + * with grayscale as a separate case.
    + */
    +
    +METHODDEF(void)
    +gray_rgb_convert (j_decompress_ptr cinfo,
    +                  JSAMPIMAGE input_buf, JDIMENSION input_row,
    +                  JSAMPARRAY output_buf, int num_rows)
    +{
    +  register JSAMPROW inptr, outptr;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->output_width;
    +
    +  while (--num_rows >= 0) {
    +    inptr = input_buf[0][input_row++];
    +    outptr = *output_buf++;
    +    for (col = 0; col < num_cols; col++) {
    +      /* We can dispense with GETJSAMPLE() here */
    +      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
    +      outptr += RGB_PIXELSIZE;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Adobe-style YCCK->CMYK conversion.
    + * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
    + * conversion as above, while passing K (black) unchanged.
    + * We assume build_ycc_rgb_table has been called.
    + */
    +
    +METHODDEF(void)
    +ycck_cmyk_convert (j_decompress_ptr cinfo,
    +                   JSAMPIMAGE input_buf, JDIMENSION input_row,
    +                   JSAMPARRAY output_buf, int num_rows)
    +{
    +  my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    +  register int y, cb, cr;
    +  register JSAMPROW outptr;
    +  register JSAMPROW inptr0, inptr1, inptr2, inptr3;
    +  register JDIMENSION col;
    +  JDIMENSION num_cols = cinfo->output_width;
    +  /* copy these pointers into registers if possible */
    +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
    +  register int * Crrtab = cconvert->Cr_r_tab;
    +  register int * Cbbtab = cconvert->Cb_b_tab;
    +  register INT32 * Crgtab = cconvert->Cr_g_tab;
    +  register INT32 * Cbgtab = cconvert->Cb_g_tab;
    +  SHIFT_TEMPS
    +
    +  while (--num_rows >= 0) {
    +    inptr0 = input_buf[0][input_row];
    +    inptr1 = input_buf[1][input_row];
    +    inptr2 = input_buf[2][input_row];
    +    inptr3 = input_buf[3][input_row];
    +    input_row++;
    +    outptr = *output_buf++;
    +    for (col = 0; col < num_cols; col++) {
    +      y  = GETJSAMPLE(inptr0[col]);
    +      cb = GETJSAMPLE(inptr1[col]);
    +      cr = GETJSAMPLE(inptr2[col]);
    +      /* Range-limiting is essential due to noise introduced by DCT losses. */
    +      outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
    +      outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
    +                              ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    +                                                 SCALEBITS)))];
    +      outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
    +      /* K passes through unchanged */
    +      outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
    +      outptr += 4;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Empty method for start_pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_dcolor (j_decompress_ptr cinfo)
    +{
    +  /* no work needed */
    +}
    +
    +
    +/*
    + * Module initialization routine for output colorspace conversion.
    + */
    +
    +GLOBAL(void)
    +jinit_color_deconverter (j_decompress_ptr cinfo)
    +{
    +  my_cconvert_ptr cconvert;
    +  int ci;
    +
    +  cconvert = (my_cconvert_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_color_deconverter));
    +  cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
    +  cconvert->pub.start_pass = start_pass_dcolor;
    +
    +  /* Make sure num_components agrees with jpeg_color_space */
    +  switch (cinfo->jpeg_color_space) {
    +  case JCS_GRAYSCALE:
    +    if (cinfo->num_components != 1)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    break;
    +  case JCS_RGB:
    +  case JCS_YCbCr:
    +    if (cinfo->num_components != 3)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    break;
    +
    +  case JCS_CMYK:
    +  case JCS_YCCK:
    +    if (cinfo->num_components != 4)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    break;
    +
    +  default:                      /* JCS_UNKNOWN can be anything */
    +    if (cinfo->num_components < 1)
    +      ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
    +    break;
    +  }
    +
    +  /* Set out_color_components and conversion method based on requested space.
    +   * Also clear the component_needed flags for any unused components,
    +   * so that earlier pipeline stages can avoid useless computation.
    +   */
    +
    +  switch (cinfo->out_color_space) {
    +  case JCS_GRAYSCALE:
    +    cinfo->out_color_components = 1;
    +    if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
    +        cinfo->jpeg_color_space == JCS_YCbCr) {
    +      cconvert->pub.color_convert = grayscale_convert;
    +      /* For color->grayscale conversion, only the Y (0) component is needed */
    +      for (ci = 1; ci < cinfo->num_components; ci++)
    +        cinfo->comp_info[ci].component_needed = FALSE;
    +    } else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_RGB:
    +    cinfo->out_color_components = RGB_PIXELSIZE;
    +    if (cinfo->jpeg_color_space == JCS_YCbCr) {
    +      cconvert->pub.color_convert = ycc_rgb_convert;
    +      build_ycc_rgb_table(cinfo);
    +    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
    +      cconvert->pub.color_convert = gray_rgb_convert;
    +    } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
    +      cconvert->pub.color_convert = null_convert;
    +    } else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  case JCS_CMYK:
    +    cinfo->out_color_components = 4;
    +    if (cinfo->jpeg_color_space == JCS_YCCK) {
    +      cconvert->pub.color_convert = ycck_cmyk_convert;
    +      build_ycc_rgb_table(cinfo);
    +    } else if (cinfo->jpeg_color_space == JCS_CMYK) {
    +      cconvert->pub.color_convert = null_convert;
    +    } else
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +
    +  default:
    +    /* Permit null conversion to same output space */
    +    if (cinfo->out_color_space == cinfo->jpeg_color_space) {
    +      cinfo->out_color_components = cinfo->num_components;
    +      cconvert->pub.color_convert = null_convert;
    +    } else                      /* unsupported non-null conversion */
    +      ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
    +    break;
    +  }
    +
    +  if (cinfo->quantize_colors)
    +    cinfo->output_components = 1; /* single colormapped output component */
    +  else
    +    cinfo->output_components = cinfo->out_color_components;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdct.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdct.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdct.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdct.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,180 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdct.h
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This include file contains common declarations for the forward and
    + * inverse DCT modules.  These declarations are private to the DCT managers
    + * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
    + * The individual DCT algorithms are kept in separate files to ease
    + * machine-dependent tuning (e.g., assembly coding).
    + */
    +
    +
    +/*
    + * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
    + * the DCT is to be performed in-place in that buffer.  Type DCTELEM is int
    + * for 8-bit samples, INT32 for 12-bit samples.  (NOTE: Floating-point DCT
    + * implementations use an array of type FAST_FLOAT, instead.)
    + * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
    + * The DCT outputs are returned scaled up by a factor of 8; they therefore
    + * have a range of +-8K for 8-bit data, +-128K for 12-bit data.  This
    + * convention improves accuracy in integer implementations and saves some
    + * work in floating-point ones.
    + * Quantization of the output coefficients is done by jcdctmgr.c.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +typedef int DCTELEM;            /* 16 or 32 bits is fine */
    +#else
    +typedef INT32 DCTELEM;          /* must have 32 bits */
    +#endif
    +
    +typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
    +typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
    +
    +
    +/*
    + * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
    + * to an output sample array.  The routine must dequantize the input data as
    + * well as perform the IDCT; for dequantization, it uses the multiplier table
    + * pointed to by compptr->dct_table.  The output data is to be placed into the
    + * sample array starting at a specified column.  (Any row offset needed will
    + * be applied to the array pointer before it is passed to the IDCT code.)
    + * Note that the number of samples emitted by the IDCT routine is
    + * DCT_scaled_size * DCT_scaled_size.
    + */
    +
    +/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
    +
    +/*
    + * Each IDCT routine has its own ideas about the best dct_table element type.
    + */
    +
    +typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
    +#if BITS_IN_JSAMPLE == 8
    +typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
    +#define IFAST_SCALE_BITS  2     /* fractional bits in scale factors */
    +#else
    +typedef INT32 IFAST_MULT_TYPE;  /* need 32 bits for scaled quantizers */
    +#define IFAST_SCALE_BITS  13    /* fractional bits in scale factors */
    +#endif
    +typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
    +
    +
    +/*
    + * Each IDCT routine is responsible for range-limiting its results and
    + * converting them to unsigned form (0..MAXJSAMPLE).  The raw outputs could
    + * be quite far out of range if the input data is corrupt, so a bulletproof
    + * range-limiting step is required.  We use a mask-and-table-lookup method
    + * to do the combined operations quickly.  See the comments with
    + * prepare_range_limit_table (in jdmaster.c) for more info.
    + */
    +
    +#define IDCT_range_limit(cinfo)  ((cinfo)->sample_range_limit + CENTERJSAMPLE)
    +
    +#define RANGE_MASK  (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
    +
    +
    +/* Short forms of external names for systems with brain-damaged linkers. */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_fdct_islow         jFDislow
    +#define jpeg_fdct_ifast         jFDifast
    +#define jpeg_fdct_float         jFDfloat
    +#define jpeg_idct_islow         jRDislow
    +#define jpeg_idct_ifast         jRDifast
    +#define jpeg_idct_float         jRDfloat
    +#define jpeg_idct_4x4           jRD4x4
    +#define jpeg_idct_2x2           jRD2x2
    +#define jpeg_idct_1x1           jRD1x1
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +/* Extern declarations for the forward and inverse DCT routines. */
    +
    +EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
    +EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
    +EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
    +
    +EXTERN(void) jpeg_idct_islow
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +EXTERN(void) jpeg_idct_ifast
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +EXTERN(void) jpeg_idct_float
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +EXTERN(void) jpeg_idct_4x4
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +EXTERN(void) jpeg_idct_2x2
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +EXTERN(void) jpeg_idct_1x1
    +    JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +         JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
    +
    +
    +/*
    + * Macros for handling fixed-point arithmetic; these are used by many
    + * but not all of the DCT/IDCT modules.
    + *
    + * All values are expected to be of type INT32.
    + * Fractional constants are scaled left by CONST_BITS bits.
    + * CONST_BITS is defined within each module using these macros,
    + * and may differ from one module to the next.
    + */
    +
    +#define ONE     ((INT32) 1)
    +#define CONST_SCALE (ONE << CONST_BITS)
    +
    +/* Convert a positive real constant to an integer scaled by CONST_SCALE.
    + * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
    + * thus causing a lot of useless floating-point operations at run time.
    + */
    +
    +#define FIX(x)  ((INT32) ((x) * CONST_SCALE + 0.5))
    +
    +/* Descale and correctly round an INT32 value that's scaled by N bits.
    + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
    + * the fudge factor is correct for either sign of X.
    + */
    +
    +#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
    +
    +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
    + * This macro is used only when the two inputs will actually be no more than
    + * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
    + * full 32x32 multiply.  This provides a useful speedup on many machines.
    + * Unfortunately there is no way to specify a 16x16->32 multiply portably
    + * in C, but some C compilers will do the right thing if you provide the
    + * correct combination of casts.
    + */
    +
    +#ifdef SHORTxSHORT_32           /* may work if 'int' is 32 bits */
    +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT16) (const)))
    +#endif
    +#ifdef SHORTxLCONST_32          /* known to work with Microsoft C 6.0 */
    +#define MULTIPLY16C16(var,const)  (((INT16) (var)) * ((INT32) (const)))
    +#endif
    +
    +#ifndef MULTIPLY16C16           /* default definition */
    +#define MULTIPLY16C16(var,const)  ((var) * (const))
    +#endif
    +
    +/* Same except both inputs are variables. */
    +
    +#ifdef SHORTxSHORT_32           /* may work if 'int' is 32 bits */
    +#define MULTIPLY16V16(var1,var2)  (((INT16) (var1)) * ((INT16) (var2)))
    +#endif
    +
    +#ifndef MULTIPLY16V16           /* default definition */
    +#define MULTIPLY16V16(var1,var2)  ((var1) * (var2))
    +#endif
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jddctmgr.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jddctmgr.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jddctmgr.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jddctmgr.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,273 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jddctmgr.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the inverse-DCT management logic.
    + * This code selects a particular IDCT implementation to be used,
    + * and it performs related housekeeping chores.  No code in this file
    + * is executed per IDCT step, only during output pass setup.
    + *
    + * Note that the IDCT routines are responsible for performing coefficient
    + * dequantization as well as the IDCT proper.  This module sets up the
    + * dequantization multiplier table needed by the IDCT routine.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +
    +/*
    + * The decompressor input side (jdinput.c) saves away the appropriate
    + * quantization table for each component at the start of the first scan
    + * involving that component.  (This is necessary in order to correctly
    + * decode files that reuse Q-table slots.)
    + * When we are ready to make an output pass, the saved Q-table is converted
    + * to a multiplier table that will actually be used by the IDCT routine.
    + * The multiplier table contents are IDCT-method-dependent.  To support
    + * application changes in IDCT method between scans, we can remake the
    + * multiplier tables if necessary.
    + * In buffered-image mode, the first output pass may occur before any data
    + * has been seen for some components, and thus before their Q-tables have
    + * been saved away.  To handle this case, multiplier tables are preset
    + * to zeroes; the result of the IDCT will be a neutral gray level.
    + */
    +
    +
    +/* Private subobject for this module */
    +
    +typedef struct {
    +  struct jpeg_inverse_dct pub;  /* public fields */
    +
    +  /* This array contains the IDCT method code that each multiplier table
    +   * is currently set up for, or -1 if it's not yet set up.
    +   * The actual multiplier tables are pointed to by dct_table in the
    +   * per-component comp_info structures.
    +   */
    +  int cur_method[MAX_COMPONENTS];
    +} my_idct_controller;
    +
    +typedef my_idct_controller * my_idct_ptr;
    +
    +
    +/* Allocated multiplier tables: big enough for any supported variant */
    +
    +typedef union {
    +  ISLOW_MULT_TYPE islow_array[DCTSIZE2];
    +#ifdef DCT_IFAST_SUPPORTED
    +  IFAST_MULT_TYPE ifast_array[DCTSIZE2];
    +#endif
    +#ifdef DCT_FLOAT_SUPPORTED
    +  FLOAT_MULT_TYPE float_array[DCTSIZE2];
    +#endif
    +} multiplier_table;
    +
    +
    +/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
    + * so be sure to compile that code if either ISLOW or SCALING is requested.
    + */
    +#ifdef DCT_ISLOW_SUPPORTED
    +#define PROVIDE_ISLOW_TABLES
    +#else
    +#ifdef IDCT_SCALING_SUPPORTED
    +#define PROVIDE_ISLOW_TABLES
    +#endif
    +#endif
    +
    +
    +/*
    + * Prepare for an output pass.
    + * Here we select the proper IDCT routine for each component and build
    + * a matching multiplier table.
    + */
    +
    +METHODDEF(void)
    +start_pass (j_decompress_ptr cinfo)
    +{
    +  my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
    +  int ci, i;
    +  jpeg_component_info *compptr;
    +  int method = 0;
    +  inverse_DCT_method_ptr method_ptr = NULL;
    +  JQUANT_TBL * qtbl;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Select the proper IDCT routine for this component's scaling */
    +    switch (compptr->DCT_scaled_size) {
    +#ifdef IDCT_SCALING_SUPPORTED
    +    case 1:
    +      method_ptr = jpeg_idct_1x1;
    +      method = JDCT_ISLOW;      /* jidctred uses islow-style table */
    +      break;
    +    case 2:
    +      method_ptr = jpeg_idct_2x2;
    +      method = JDCT_ISLOW;      /* jidctred uses islow-style table */
    +      break;
    +    case 4:
    +      method_ptr = jpeg_idct_4x4;
    +      method = JDCT_ISLOW;      /* jidctred uses islow-style table */
    +      break;
    +#endif
    +    case DCTSIZE:
    +      switch (cinfo->dct_method) {
    +#ifdef DCT_ISLOW_SUPPORTED
    +      case JDCT_ISLOW:
    +        method_ptr = jpeg_idct_islow;
    +        method = JDCT_ISLOW;
    +        break;
    +#endif
    +#ifdef DCT_IFAST_SUPPORTED
    +      case JDCT_IFAST:
    +        method_ptr = jpeg_idct_ifast;
    +        method = JDCT_IFAST;
    +        break;
    +#endif
    +#ifdef DCT_FLOAT_SUPPORTED
    +      case JDCT_FLOAT:
    +        method_ptr = jpeg_idct_float;
    +        method = JDCT_FLOAT;
    +        break;
    +#endif
    +      default:
    +        ERREXIT(cinfo, JERR_NOT_COMPILED);
    +        break;
    +      }
    +      break;
    +    default:
    +      ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
    +      break;
    +    }
    +    idct->pub.inverse_DCT[ci] = method_ptr;
    +    /* Create multiplier table from quant table.
    +     * However, we can skip this if the component is uninteresting
    +     * or if we already built the table.  Also, if no quant table
    +     * has yet been saved for the component, we leave the
    +     * multiplier table all-zero; we'll be reading zeroes from the
    +     * coefficient controller's buffer anyway.
    +     */
    +    if (! compptr->component_needed || idct->cur_method[ci] == method)
    +      continue;
    +    qtbl = compptr->quant_table;
    +    if (qtbl == NULL)           /* happens if no data yet for component */
    +      continue;
    +    idct->cur_method[ci] = method;
    +    switch (method) {
    +#ifdef PROVIDE_ISLOW_TABLES
    +    case JDCT_ISLOW:
    +      {
    +        /* For LL&M IDCT method, multipliers are equal to raw quantization
    +         * coefficients, but are stored as ints to ensure access efficiency.
    +         */
    +        ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
    +        for (i = 0; i < DCTSIZE2; i++) {
    +          ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
    +        }
    +      }
    +      break;
    +#endif
    +#ifdef DCT_IFAST_SUPPORTED
    +    case JDCT_IFAST:
    +      {
    +        /* For AA&N IDCT method, multipliers are equal to quantization
    +         * coefficients scaled by scalefactor[row]*scalefactor[col], where
    +         *   scalefactor[0] = 1
    +         *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
    +         * For integer operation, the multiplier table is to be scaled by
    +         * IFAST_SCALE_BITS.
    +         */
    +        IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
    +#define CONST_BITS 14
    +        static const INT16 aanscales[DCTSIZE2] = {
    +          /* precomputed values scaled up by 14 bits */
    +          16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
    +          22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
    +          21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
    +          19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
    +          16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
    +          12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
    +           8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
    +           4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
    +        };
    +        SHIFT_TEMPS
    +
    +        for (i = 0; i < DCTSIZE2; i++) {
    +          ifmtbl[i] = (IFAST_MULT_TYPE)
    +            DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
    +                                  (INT32) aanscales[i]),
    +                    CONST_BITS-IFAST_SCALE_BITS);
    +        }
    +      }
    +      break;
    +#endif
    +#ifdef DCT_FLOAT_SUPPORTED
    +    case JDCT_FLOAT:
    +      {
    +        /* For float AA&N IDCT method, multipliers are equal to quantization
    +         * coefficients scaled by scalefactor[row]*scalefactor[col], where
    +         *   scalefactor[0] = 1
    +         *   scalefactor[k] = cos(k*PI/16) * sqrt(2)    for k=1..7
    +         */
    +        FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
    +        int row, col;
    +        static const double aanscalefactor[DCTSIZE] = {
    +          1.0, 1.387039845, 1.306562965, 1.175875602,
    +          1.0, 0.785694958, 0.541196100, 0.275899379
    +        };
    +
    +        i = 0;
    +        for (row = 0; row < DCTSIZE; row++) {
    +          for (col = 0; col < DCTSIZE; col++) {
    +            fmtbl[i] = (FLOAT_MULT_TYPE)
    +              ((double) qtbl->quantval[i] *
    +               aanscalefactor[row] * aanscalefactor[col]);
    +            i++;
    +          }
    +        }
    +      }
    +      break;
    +#endif
    +    default:
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +      break;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Initialize IDCT manager.
    + */
    +
    +GLOBAL(void)
    +jinit_inverse_dct (j_decompress_ptr cinfo)
    +{
    +  my_idct_ptr idct;
    +  int ci;
    +  jpeg_component_info *compptr;
    +
    +  idct = (my_idct_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_idct_controller));
    +  cinfo->idct = (struct jpeg_inverse_dct *) idct;
    +  idct->pub.start_pass = start_pass;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Allocate and pre-zero a multiplier table for each component */
    +    compptr->dct_table =
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(multiplier_table));
    +    MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
    +    /* Mark multiplier table not yet set up for any method */
    +    idct->cur_method[ci] = -1;
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdhuff.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdhuff.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdhuff.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdhuff.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,660 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdhuff.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains Huffman entropy decoding routines.
    + *
    + * Much of the complexity here has to do with supporting input suspension.
    + * If the data source module demands suspension, we want to be able to back
    + * up to the start of the current MCU.  To do this, we copy state variables
    + * into local working storage, and update them back to the permanent
    + * storage only upon successful completion of an MCU.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdhuff.h"             /* Declarations shared with jdphuff.c */
    +
    +
    +/*
    + * Expanded entropy decoder object for Huffman decoding.
    + *
    + * The savable_state subrecord contains fields that change within an MCU,
    + * but must not be updated permanently until we complete the MCU.
    + */
    +
    +typedef struct {
    +  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
    +} savable_state;
    +
    +/* This macro is to work around compilers with missing or broken
    + * structure assignment.  You'll need to fix this code if you have
    + * such a compiler and you change MAX_COMPS_IN_SCAN.
    + */
    +
    +#ifndef NO_STRUCT_ASSIGN
    +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
    +#else
    +#if MAX_COMPS_IN_SCAN == 4
    +#define ASSIGN_STATE(dest,src)  \
    +        ((dest).last_dc_val[0] = (src).last_dc_val[0], \
    +         (dest).last_dc_val[1] = (src).last_dc_val[1], \
    +         (dest).last_dc_val[2] = (src).last_dc_val[2], \
    +         (dest).last_dc_val[3] = (src).last_dc_val[3])
    +#endif
    +#endif
    +
    +
    +typedef struct {
    +  struct jpeg_entropy_decoder pub; /* public fields */
    +
    +  /* These fields are loaded into local variables at start of each MCU.
    +   * In case of suspension, we exit WITHOUT updating them.
    +   */
    +  bitread_perm_state bitstate;  /* Bit buffer at start of MCU */
    +  savable_state saved;          /* Other state at start of MCU */
    +
    +  /* These fields are NOT loaded into local working state. */
    +  unsigned int restarts_to_go;  /* MCUs left in this restart interval */
    +
    +  /* Pointers to derived tables (these workspaces have image lifespan) */
    +  d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
    +  d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
    +
    +  /* Precalculated info set up by start_pass for use in decode_mcu: */
    +
    +  /* Pointers to derived tables to be used for each block within an MCU */
    +  d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
    +  d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
    +  /* Whether we care about the DC and AC coefficient values for each block */
    +  boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
    +  boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
    +} huff_entropy_decoder;
    +
    +typedef huff_entropy_decoder * huff_entropy_ptr;
    +
    +
    +/*
    + * Initialize for a Huffman-compressed scan.
    + */
    +
    +METHODDEF(void)
    +start_pass_huff_decoder (j_decompress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int ci, blkn, dctbl, actbl;
    +  jpeg_component_info * compptr;
    +
    +  /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
    +   * This ought to be an error condition, but we make it a warning because
    +   * there are some baseline files out there with all zeroes in these bytes.
    +   */
    +  if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
    +      cinfo->Ah != 0 || cinfo->Al != 0)
    +    WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    dctbl = compptr->dc_tbl_no;
    +    actbl = compptr->ac_tbl_no;
    +    /* Compute derived values for Huffman tables */
    +    /* We may do this more than once for a table, but it's not expensive */
    +    jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
    +                            & entropy->dc_derived_tbls[dctbl]);
    +    jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
    +                            & entropy->ac_derived_tbls[actbl]);
    +    /* Initialize DC predictions to 0 */
    +    entropy->saved.last_dc_val[ci] = 0;
    +  }
    +
    +  /* Precalculate decoding info for each block in an MCU of this scan */
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    ci = cinfo->MCU_membership[blkn];
    +    compptr = cinfo->cur_comp_info[ci];
    +    /* Precalculate which table to use for each block */
    +    entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
    +    entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
    +    /* Decide whether we really care about the coefficient values */
    +    if (compptr->component_needed) {
    +      entropy->dc_needed[blkn] = TRUE;
    +      /* we don't need the ACs if producing a 1/8th-size image */
    +      entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
    +    } else {
    +      entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
    +    }
    +  }
    +
    +  /* Initialize bitread state variables */
    +  entropy->bitstate.bits_left = 0;
    +  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
    +  entropy->pub.insufficient_data = FALSE;
    +
    +  /* Initialize restart counter */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +}
    +
    +
    +/*
    + * Compute the derived values for a Huffman table.
    + * This routine also performs some validation checks on the table.
    + *
    + * Note this is also used by jdphuff.c.
    + */
    +
    +GLOBAL(void)
    +jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
    +                         d_derived_tbl ** pdtbl)
    +{
    +  JHUFF_TBL *htbl;
    +  d_derived_tbl *dtbl;
    +  int p, i, l, si, numsymbols;
    +  int lookbits, ctr;
    +  char huffsize[257];
    +  unsigned int huffcode[257];
    +  unsigned int code;
    +
    +  /* Note that huffsize[] and huffcode[] are filled in code-length order,
    +   * paralleling the order of the symbols themselves in htbl->huffval[].
    +   */
    +
    +  /* Find the input Huffman table */
    +  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
    +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
    +  htbl =
    +    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
    +  if (htbl == NULL)
    +    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
    +
    +  /* Allocate a workspace if we haven't already done so. */
    +  if (*pdtbl == NULL)
    +    *pdtbl = (d_derived_tbl *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(d_derived_tbl));
    +  dtbl = *pdtbl;
    +  dtbl->pub = htbl;             /* fill in back link */
    +
    +  /* Figure C.1: make table of Huffman code length for each symbol */
    +
    +  p = 0;
    +  for (l = 1; l <= 16; l++) {
    +    i = (int) htbl->bits[l];
    +    if (i < 0 || p + i > 256)   /* protect against table overrun */
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    while (i--)
    +      huffsize[p++] = (char) l;
    +  }
    +  huffsize[p] = 0;
    +  numsymbols = p;
    +
    +  /* Figure C.2: generate the codes themselves */
    +  /* We also validate that the counts represent a legal Huffman code tree. */
    +
    +  code = 0;
    +  si = huffsize[0];
    +  p = 0;
    +  while (huffsize[p]) {
    +    while (((int) huffsize[p]) == si) {
    +      huffcode[p++] = code;
    +      code++;
    +    }
    +    /* code is now 1 more than the last code used for codelength si; but
    +     * it must still fit in si bits, since no code is allowed to be all ones.
    +     */
    +    if (((INT32) code) >= (((INT32) 1) << si))
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    code <<= 1;
    +    si++;
    +  }
    +
    +  /* Figure F.15: generate decoding tables for bit-sequential decoding */
    +
    +  p = 0;
    +  for (l = 1; l <= 16; l++) {
    +    if (htbl->bits[l]) {
    +      /* valoffset[l] = huffval[] index of 1st symbol of code length l,
    +       * minus the minimum code of length l
    +       */
    +      dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
    +      p += htbl->bits[l];
    +      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
    +    } else {
    +      dtbl->maxcode[l] = -1;    /* -1 if no codes of this length */
    +    }
    +  }
    +  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
    +
    +  /* Compute lookahead tables to speed up decoding.
    +   * First we set all the table entries to 0, indicating "too long";
    +   * then we iterate through the Huffman codes that are short enough and
    +   * fill in all the entries that correspond to bit sequences starting
    +   * with that code.
    +   */
    +
    +  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
    +
    +  p = 0;
    +  for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
    +    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
    +      /* l = current code's length, p = its index in huffcode[] & huffval[]. */
    +      /* Generate left-justified code followed by all possible bit sequences */
    +      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
    +      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
    +        dtbl->look_nbits[lookbits] = l;
    +        dtbl->look_sym[lookbits] = htbl->huffval[p];
    +        lookbits++;
    +      }
    +    }
    +  }
    +
    +  /* Validate symbols as being reasonable.
    +   * For AC tables, we make no check, but accept all byte values 0..255.
    +   * For DC tables, we require the symbols to be in range 0..15.
    +   * (Tighter bounds could be applied depending on the data depth and mode,
    +   * but this is sufficient to ensure safe decoding.)
    +   */
    +  if (isDC) {
    +    for (i = 0; i < numsymbols; i++) {
    +      int sym = htbl->huffval[i];
    +      if (sym < 0 || sym > 15)
    +        ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Out-of-line code for bit fetching (shared with jdphuff.c).
    + * See jdhuff.h for info about usage.
    + * Note: current values of get_buffer and bits_left are passed as parameters,
    + * but are returned in the corresponding fields of the state struct.
    + *
    + * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
    + * of get_buffer to be used.  (On machines with wider words, an even larger
    + * buffer could be used.)  However, on some machines 32-bit shifts are
    + * quite slow and take time proportional to the number of places shifted.
    + * (This is true with most PC compilers, for instance.)  In this case it may
    + * be a win to set MIN_GET_BITS to the minimum value of 15.  This reduces the
    + * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
    + */
    +
    +#ifdef SLOW_SHIFT_32
    +#define MIN_GET_BITS  15        /* minimum allowable value */
    +#else
    +#define MIN_GET_BITS  (BIT_BUF_SIZE-7)
    +#endif
    +
    +
    +GLOBAL(boolean)
    +jpeg_fill_bit_buffer (bitread_working_state * state,
    +                      register bit_buf_type get_buffer, register int bits_left,
    +                      int nbits)
    +/* Load up the bit buffer to a depth of at least nbits */
    +{
    +  /* Copy heavily used state fields into locals (hopefully registers) */
    +  register const JOCTET * next_input_byte = state->next_input_byte;
    +  register size_t bytes_in_buffer = state->bytes_in_buffer;
    +  j_decompress_ptr cinfo = state->cinfo;
    +
    +  /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
    +  /* (It is assumed that no request will be for more than that many bits.) */
    +  /* We fail to do so only if we hit a marker or are forced to suspend. */
    +
    +  if (cinfo->unread_marker == 0) {      /* cannot advance past a marker */
    +    while (bits_left < MIN_GET_BITS) {
    +      register int c;
    +
    +      /* Attempt to read a byte */
    +      if (bytes_in_buffer == 0) {
    +        if (! (*cinfo->src->fill_input_buffer) (cinfo))
    +          return FALSE;
    +        next_input_byte = cinfo->src->next_input_byte;
    +        bytes_in_buffer = cinfo->src->bytes_in_buffer;
    +      }
    +      bytes_in_buffer--;
    +      c = GETJOCTET(*next_input_byte++);
    +
    +      /* If it's 0xFF, check and discard stuffed zero byte */
    +      if (c == 0xFF) {
    +        /* Loop here to discard any padding FF's on terminating marker,
    +         * so that we can save a valid unread_marker value.  NOTE: we will
    +         * accept multiple FF's followed by a 0 as meaning a single FF data
    +         * byte.  This data pattern is not valid according to the standard.
    +         */
    +        do {
    +          if (bytes_in_buffer == 0) {
    +            if (! (*cinfo->src->fill_input_buffer) (cinfo))
    +              return FALSE;
    +            next_input_byte = cinfo->src->next_input_byte;
    +            bytes_in_buffer = cinfo->src->bytes_in_buffer;
    +          }
    +          bytes_in_buffer--;
    +          c = GETJOCTET(*next_input_byte++);
    +        } while (c == 0xFF);
    +
    +        if (c == 0) {
    +          /* Found FF/00, which represents an FF data byte */
    +          c = 0xFF;
    +        } else {
    +          /* Oops, it's actually a marker indicating end of compressed data.
    +           * Save the marker code for later use.
    +           * Fine point: it might appear that we should save the marker into
    +           * bitread working state, not straight into permanent state.  But
    +           * once we have hit a marker, we cannot need to suspend within the
    +           * current MCU, because we will read no more bytes from the data
    +           * source.  So it is OK to update permanent state right away.
    +           */
    +          cinfo->unread_marker = c;
    +          /* See if we need to insert some fake zero bits. */
    +          goto no_more_bytes;
    +        }
    +      }
    +
    +      /* OK, load c into get_buffer */
    +      get_buffer = (get_buffer << 8) | c;
    +      bits_left += 8;
    +    } /* end while */
    +  } else {
    +  no_more_bytes:
    +    /* We get here if we've read the marker that terminates the compressed
    +     * data segment.  There should be enough bits in the buffer register
    +     * to satisfy the request; if so, no problem.
    +     */
    +    if (nbits > bits_left) {
    +      /* Uh-oh.  Report corrupted data to user and stuff zeroes into
    +       * the data stream, so that we can produce some kind of image.
    +       * We use a nonvolatile flag to ensure that only one warning message
    +       * appears per data segment.
    +       */
    +      if (! cinfo->entropy->insufficient_data) {
    +        WARNMS(cinfo, JWRN_HIT_MARKER);
    +        cinfo->entropy->insufficient_data = TRUE;
    +      }
    +      /* Fill the buffer with zero bits */
    +      get_buffer <<= MIN_GET_BITS - bits_left;
    +      bits_left = MIN_GET_BITS;
    +    }
    +  }
    +
    +  /* Unload the local registers */
    +  state->next_input_byte = next_input_byte;
    +  state->bytes_in_buffer = bytes_in_buffer;
    +  state->get_buffer = get_buffer;
    +  state->bits_left = bits_left;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Out-of-line code for Huffman code decoding.
    + * See jdhuff.h for info about usage.
    + */
    +
    +GLOBAL(int)
    +jpeg_huff_decode (bitread_working_state * state,
    +                  register bit_buf_type get_buffer, register int bits_left,
    +                  d_derived_tbl * htbl, int min_bits)
    +{
    +  register int l = min_bits;
    +  register INT32 code;
    +
    +  /* HUFF_DECODE has determined that the code is at least min_bits */
    +  /* bits long, so fetch that many bits in one swoop. */
    +
    +  CHECK_BIT_BUFFER(*state, l, return -1);
    +  code = GET_BITS(l);
    +
    +  /* Collect the rest of the Huffman code one bit at a time. */
    +  /* This is per Figure F.16 in the JPEG spec. */
    +
    +  while (code > htbl->maxcode[l]) {
    +    code <<= 1;
    +    CHECK_BIT_BUFFER(*state, 1, return -1);
    +    code |= GET_BITS(1);
    +    l++;
    +  }
    +
    +  /* Unload the local registers */
    +  state->get_buffer = get_buffer;
    +  state->bits_left = bits_left;
    +
    +  /* With garbage input we may reach the sentinel value l = 17. */
    +
    +  if (l > 16) {
    +    WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
    +    return 0;                   /* fake a zero as the safest result */
    +  }
    +
    +  return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
    +}
    +
    +
    +/*
    + * Figure F.12: extend sign bit.
    + * On some machines, a shift and add will be faster than a table lookup.
    + */
    +
    +#ifdef AVOID_TABLES
    +
    +#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
    +
    +#else
    +
    +#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
    +
    +static const int extend_test[16] =   /* entry n is 2**(n-1) */
    +  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
    +    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
    +
    +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
    +  { 0,
    +    (int)(((unsigned)(~0)<<1)  + 1), (int)(((unsigned)(~0)<<2)  + 1),
    +    (int)(((unsigned)(~0)<<3)  + 1), (int)(((unsigned)(~0)<<4)  + 1),
    +    (int)(((unsigned)(~0)<<5)  + 1), (int)(((unsigned)(~0)<<6)  + 1),
    +    (int)(((unsigned)(~0)<<7)  + 1), (int)(((unsigned)(~0)<<8)  + 1),
    +    (int)(((unsigned)(~0)<<9)  + 1), (int)(((unsigned)(~0)<<10) + 1),
    +    (int)(((unsigned)(~0)<<11) + 1), (int)(((unsigned)(~0)<<12) + 1),
    +    (int)(((unsigned)(~0)<<13) + 1), (int)(((unsigned)(~0)<<14) + 1),
    +    (int)(((unsigned)(~0)<<15) + 1) };
    +
    +#endif /* AVOID_TABLES */
    +
    +
    +/*
    + * Check for a restart marker & resynchronize decoder.
    + * Returns FALSE if must suspend.
    + */
    +
    +LOCAL(boolean)
    +process_restart (j_decompress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int ci;
    +
    +  /* Throw away any unused bits remaining in bit buffer; */
    +  /* include any full bytes in next_marker's count of discarded bytes */
    +  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
    +  entropy->bitstate.bits_left = 0;
    +
    +  /* Advance past the RSTn marker */
    +  if (! (*cinfo->marker->read_restart_marker) (cinfo))
    +    return FALSE;
    +
    +  /* Re-initialize DC predictions to 0 */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
    +    entropy->saved.last_dc_val[ci] = 0;
    +
    +  /* Reset restart counter */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +
    +  /* Reset out-of-data flag, unless read_restart_marker left us smack up
    +   * against a marker.  In that case we will end up treating the next data
    +   * segment as empty, and we can avoid producing bogus output pixels by
    +   * leaving the flag set.
    +   */
    +  if (cinfo->unread_marker == 0)
    +    entropy->pub.insufficient_data = FALSE;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Decode and return one MCU's worth of Huffman-compressed coefficients.
    + * The coefficients are reordered from zigzag order into natural array order,
    + * but are not dequantized.
    + *
    + * The i'th block of the MCU is stored into the block pointed to by
    + * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
    + * (Wholesale zeroing is usually a little faster than retail...)
    + *
    + * Returns FALSE if data source requested suspension.  In that case no
    + * changes have been made to permanent state.  (Exception: some output
    + * coefficients may already have been assigned.  This is harmless for
    + * this module, since we'll just re-assign them on the next call.)
    + */
    +
    +METHODDEF(boolean)
    +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
    +  int blkn;
    +  BITREAD_STATE_VARS;
    +  savable_state state;
    +
    +  /* Process restart marker if needed; may have to suspend */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! process_restart(cinfo))
    +        return FALSE;
    +  }
    +
    +  /* If we've run out of data, just leave the MCU set to zeroes.
    +   * This way, we return uniform gray for the remainder of the segment.
    +   */
    +  if (! entropy->pub.insufficient_data) {
    +
    +    /* Load up working state */
    +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
    +    ASSIGN_STATE(state, entropy->saved);
    +
    +    /* Outer loop handles each block in the MCU */
    +
    +    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +      JBLOCKROW block = MCU_data[blkn];
    +      d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
    +      d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
    +      register int s, k, r;
    +
    +      /* Decode a single block's worth of coefficients */
    +
    +      /* Section F.2.2.1: decode the DC coefficient difference */
    +      HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
    +      if (s) {
    +        CHECK_BIT_BUFFER(br_state, s, return FALSE);
    +        r = GET_BITS(s);
    +        s = HUFF_EXTEND(r, s);
    +      }
    +
    +      if (entropy->dc_needed[blkn]) {
    +        /* Convert DC difference to actual value, update last_dc_val */
    +        int ci = cinfo->MCU_membership[blkn];
    +        s += state.last_dc_val[ci];
    +        state.last_dc_val[ci] = s;
    +        /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
    +        (*block)[0] = (JCOEF) s;
    +      }
    +
    +      if (entropy->ac_needed[blkn]) {
    +
    +        /* Section F.2.2.2: decode the AC coefficients */
    +        /* Since zeroes are skipped, output area must be cleared beforehand */
    +        for (k = 1; k < DCTSIZE2; k++) {
    +          HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
    +
    +          r = s >> 4;
    +          s &= 15;
    +
    +          if (s) {
    +            k += r;
    +            CHECK_BIT_BUFFER(br_state, s, return FALSE);
    +            r = GET_BITS(s);
    +            s = HUFF_EXTEND(r, s);
    +            /* Output coefficient in natural (dezigzagged) order.
    +             * Note: the extra entries in jpeg_natural_order[] will save us
    +             * if k >= DCTSIZE2, which could happen if the data is corrupted.
    +             */
    +            (*block)[jpeg_natural_order[k]] = (JCOEF) s;
    +          } else {
    +            if (r != 15)
    +              break;
    +            k += 15;
    +          }
    +        }
    +
    +      } else {
    +
    +        /* Section F.2.2.2: decode the AC coefficients */
    +        /* In this path we just discard the values */
    +        for (k = 1; k < DCTSIZE2; k++) {
    +          HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
    +
    +          r = s >> 4;
    +          s &= 15;
    +
    +          if (s) {
    +            k += r;
    +            CHECK_BIT_BUFFER(br_state, s, return FALSE);
    +            DROP_BITS(s);
    +          } else {
    +            if (r != 15)
    +              break;
    +            k += 15;
    +          }
    +        }
    +
    +      }
    +    }
    +
    +    /* Completed MCU, so update state */
    +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    +    ASSIGN_STATE(entropy->saved, state);
    +  }
    +
    +  /* Account for restart interval (no-op if not using restarts) */
    +  entropy->restarts_to_go--;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Module initialization routine for Huffman entropy decoding.
    + */
    +
    +GLOBAL(void)
    +jinit_huff_decoder (j_decompress_ptr cinfo)
    +{
    +  huff_entropy_ptr entropy;
    +  int i;
    +
    +  entropy = (huff_entropy_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(huff_entropy_decoder));
    +  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
    +  entropy->pub.start_pass = start_pass_huff_decoder;
    +  entropy->pub.decode_mcu = decode_mcu;
    +
    +  /* Mark tables unallocated */
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdhuff.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdhuff.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdhuff.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdhuff.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,205 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdhuff.h
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains declarations for Huffman entropy decoding routines
    + * that are shared between the sequential decoder (jdhuff.c) and the
    + * progressive decoder (jdphuff.c).  No other modules need to see these.
    + */
    +
    +/* Short forms of external names for systems with brain-damaged linkers. */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_make_d_derived_tbl jMkDDerived
    +#define jpeg_fill_bit_buffer    jFilBitBuf
    +#define jpeg_huff_decode        jHufDecode
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +
    +/* Derived data constructed for each Huffman table */
    +
    +#define HUFF_LOOKAHEAD  8       /* # of bits of lookahead */
    +
    +typedef struct {
    +  /* Basic tables: (element [0] of each array is unused) */
    +  INT32 maxcode[18];            /* largest code of length k (-1 if none) */
    +  /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
    +  INT32 valoffset[17];          /* huffval[] offset for codes of length k */
    +  /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
    +   * the smallest code of length k; so given a code of length k, the
    +   * corresponding symbol is huffval[code + valoffset[k]]
    +   */
    +
    +  /* Link to public Huffman table (needed only in jpeg_huff_decode) */
    +  JHUFF_TBL *pub;
    +
    +  /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
    +   * the input data stream.  If the next Huffman code is no more
    +   * than HUFF_LOOKAHEAD bits long, we can obtain its length and
    +   * the corresponding symbol directly from these tables.
    +   */
    +  int look_nbits[1< 32 bits on your machine, and shifting/masking longs is
    + * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
    + * appropriately should be a win.  Unfortunately we can't define the size
    + * with something like  #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
    + * because not all machines measure sizeof in 8-bit bytes.
    + */
    +
    +typedef struct {                /* Bitreading state saved across MCUs */
    +  bit_buf_type get_buffer;      /* current bit-extraction buffer */
    +  int bits_left;                /* # of unused bits in it */
    +} bitread_perm_state;
    +
    +typedef struct {                /* Bitreading working state within an MCU */
    +  /* Current data source location */
    +  /* We need a copy, rather than munging the original, in case of suspension */
    +  const JOCTET * next_input_byte; /* => next byte to read from source */
    +  size_t bytes_in_buffer;       /* # of bytes remaining in source buffer */
    +  /* Bit input buffer --- note these values are kept in register variables,
    +   * not in this struct, inside the inner loops.
    +   */
    +  bit_buf_type get_buffer;      /* current bit-extraction buffer */
    +  int bits_left;                /* # of unused bits in it */
    +  /* Pointer needed by jpeg_fill_bit_buffer. */
    +  j_decompress_ptr cinfo;       /* back link to decompress master record */
    +} bitread_working_state;
    +
    +/* Macros to declare and load/save bitread local variables. */
    +#define BITREAD_STATE_VARS  \
    +        register bit_buf_type get_buffer;  \
    +        register int bits_left;  \
    +        bitread_working_state br_state
    +
    +#define BITREAD_LOAD_STATE(cinfop,permstate)  \
    +        br_state.cinfo = cinfop; \
    +        br_state.next_input_byte = cinfop->src->next_input_byte; \
    +        br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
    +        get_buffer = permstate.get_buffer; \
    +        bits_left = permstate.bits_left;
    +
    +#define BITREAD_SAVE_STATE(cinfop,permstate)  \
    +        cinfop->src->next_input_byte = br_state.next_input_byte; \
    +        cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
    +        permstate.get_buffer = get_buffer; \
    +        permstate.bits_left = bits_left
    +
    +/*
    + * These macros provide the in-line portion of bit fetching.
    + * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
    + * before using GET_BITS, PEEK_BITS, or DROP_BITS.
    + * The variables get_buffer and bits_left are assumed to be locals,
    + * but the state struct might not be (jpeg_huff_decode needs this).
    + *      CHECK_BIT_BUFFER(state,n,action);
    + *              Ensure there are N bits in get_buffer; if suspend, take action.
    + *      val = GET_BITS(n);
    + *              Fetch next N bits.
    + *      val = PEEK_BITS(n);
    + *              Fetch next N bits without removing them from the buffer.
    + *      DROP_BITS(n);
    + *              Discard next N bits.
    + * The value N should be a simple variable, not an expression, because it
    + * is evaluated multiple times.
    + */
    +
    +#define CHECK_BIT_BUFFER(state,nbits,action) \
    +        { if (bits_left < (nbits)) {  \
    +            if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits))  \
    +              { action; }  \
    +            get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
    +
    +#define GET_BITS(nbits) \
    +        (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
    +
    +#define PEEK_BITS(nbits) \
    +        (((int) (get_buffer >> (bits_left -  (nbits)))) & ((1<<(nbits))-1))
    +
    +#define DROP_BITS(nbits) \
    +        (bits_left -= (nbits))
    +
    +/* Load up the bit buffer to a depth of at least nbits */
    +EXTERN(boolean) jpeg_fill_bit_buffer
    +        JPP((bitread_working_state * state, register bit_buf_type get_buffer,
    +             register int bits_left, int nbits));
    +
    +
    +/*
    + * Code for extracting next Huffman-coded symbol from input bit stream.
    + * Again, this is time-critical and we make the main paths be macros.
    + *
    + * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
    + * without looping.  Usually, more than 95% of the Huffman codes will be 8
    + * or fewer bits long.  The few overlength codes are handled with a loop,
    + * which need not be inline code.
    + *
    + * Notes about the HUFF_DECODE macro:
    + * 1. Near the end of the data segment, we may fail to get enough bits
    + *    for a lookahead.  In that case, we do it the hard way.
    + * 2. If the lookahead table contains no entry, the next code must be
    + *    more than HUFF_LOOKAHEAD bits long.
    + * 3. jpeg_huff_decode returns -1 if forced to suspend.
    + */
    +
    +#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
    +{ register int nb, look; \
    +  if (bits_left < HUFF_LOOKAHEAD) { \
    +    if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
    +    get_buffer = state.get_buffer; bits_left = state.bits_left; \
    +    if (bits_left < HUFF_LOOKAHEAD) { \
    +      nb = 1; goto slowlabel; \
    +    } \
    +  } \
    +  look = PEEK_BITS(HUFF_LOOKAHEAD); \
    +  if ((nb = htbl->look_nbits[look]) != 0) { \
    +    DROP_BITS(nb); \
    +    result = htbl->look_sym[look]; \
    +  } else { \
    +    nb = HUFF_LOOKAHEAD+1; \
    +slowlabel: \
    +    if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
    +        { failaction; } \
    +    get_buffer = state.get_buffer; bits_left = state.bits_left; \
    +  } \
    +}
    +
    +/* Out-of-line case for Huffman code fetching */
    +EXTERN(int) jpeg_huff_decode
    +        JPP((bitread_working_state * state, register bit_buf_type get_buffer,
    +             register int bits_left, d_derived_tbl * htbl, int min_bits));
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdinput.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdinput.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdinput.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdinput.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,385 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdinput.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains input control logic for the JPEG decompressor.
    + * These routines are concerned with controlling the decompressor's input
    + * processing (marker reading and coefficient decoding).  The actual input
    + * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private state */
    +
    +typedef struct {
    +  struct jpeg_input_controller pub; /* public fields */
    +
    +  boolean inheaders;            /* TRUE until first SOS is reached */
    +} my_input_controller;
    +
    +typedef my_input_controller * my_inputctl_ptr;
    +
    +
    +/* Forward declarations */
    +METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
    +
    +
    +/*
    + * Routines to calculate various quantities related to the size of the image.
    + */
    +
    +LOCAL(void)
    +initial_setup (j_decompress_ptr cinfo)
    +/* Called once, when first SOS marker is reached */
    +{
    +  int ci;
    +  jpeg_component_info *compptr;
    +
    +  /* Make sure image isn't bigger than I can handle */
    +  if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
    +      (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
    +    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
    +
    +  /* For now, precision must match compiled-in value... */
    +  if (cinfo->data_precision != BITS_IN_JSAMPLE)
    +    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    +
    +  /* Check that number of components won't exceed internal array sizes */
    +  if (cinfo->num_components > MAX_COMPONENTS)
    +    ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
    +             MAX_COMPONENTS);
    +
    +  /* Compute maximum sampling factors; check factor validity */
    +  cinfo->max_h_samp_factor = 1;
    +  cinfo->max_v_samp_factor = 1;
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
    +        compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
    +      ERREXIT(cinfo, JERR_BAD_SAMPLING);
    +    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
    +                                   compptr->h_samp_factor);
    +    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
    +                                   compptr->v_samp_factor);
    +  }
    +
    +  /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
    +   * In the full decompressor, this will be overridden by jdmaster.c;
    +   * but in the transcoder, jdmaster.c is not used, so we must do it here.
    +   */
    +  cinfo->min_DCT_scaled_size = DCTSIZE;
    +
    +  /* Compute dimensions of components */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    compptr->DCT_scaled_size = DCTSIZE;
    +    /* Size in DCT blocks */
    +    compptr->width_in_blocks = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
    +                    (long) (cinfo->max_h_samp_factor * DCTSIZE));
    +    compptr->height_in_blocks = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
    +                    (long) (cinfo->max_v_samp_factor * DCTSIZE));
    +    /* downsampled_width and downsampled_height will also be overridden by
    +     * jdmaster.c if we are doing full decompression.  The transcoder library
    +     * doesn't use these values, but the calling application might.
    +     */
    +    /* Size in samples */
    +    compptr->downsampled_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
    +                    (long) cinfo->max_h_samp_factor);
    +    compptr->downsampled_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
    +                    (long) cinfo->max_v_samp_factor);
    +    /* Mark component needed, until color conversion says otherwise */
    +    compptr->component_needed = TRUE;
    +    /* Mark no quantization table yet saved for component */
    +    compptr->quant_table = NULL;
    +  }
    +
    +  /* Compute number of fully interleaved MCU rows. */
    +  cinfo->total_iMCU_rows = (JDIMENSION)
    +    jdiv_round_up((long) cinfo->image_height,
    +                  (long) (cinfo->max_v_samp_factor*DCTSIZE));
    +
    +  /* Decide whether file contains multiple scans */
    +  if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
    +    cinfo->inputctl->has_multiple_scans = TRUE;
    +  else
    +    cinfo->inputctl->has_multiple_scans = FALSE;
    +}
    +
    +
    +LOCAL(void)
    +per_scan_setup (j_decompress_ptr cinfo)
    +/* Do computations that are needed before processing a JPEG scan */
    +/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
    +{
    +  int ci, mcublks, tmp;
    +  jpeg_component_info *compptr;
    +
    +  if (cinfo->comps_in_scan == 1) {
    +
    +    /* Noninterleaved (single-component) scan */
    +    compptr = cinfo->cur_comp_info[0];
    +
    +    /* Overall image size in MCUs */
    +    cinfo->MCUs_per_row = compptr->width_in_blocks;
    +    cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
    +
    +    /* For noninterleaved scan, always one block per MCU */
    +    compptr->MCU_width = 1;
    +    compptr->MCU_height = 1;
    +    compptr->MCU_blocks = 1;
    +    compptr->MCU_sample_width = compptr->DCT_scaled_size;
    +    compptr->last_col_width = 1;
    +    /* For noninterleaved scans, it is convenient to define last_row_height
    +     * as the number of block rows present in the last iMCU row.
    +     */
    +    tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
    +    if (tmp == 0) tmp = compptr->v_samp_factor;
    +    compptr->last_row_height = tmp;
    +
    +    /* Prepare array describing MCU composition */
    +    cinfo->blocks_in_MCU = 1;
    +    cinfo->MCU_membership[0] = 0;
    +
    +  } else {
    +
    +    /* Interleaved (multi-component) scan */
    +    if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
    +      ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
    +               MAX_COMPS_IN_SCAN);
    +
    +    /* Overall image size in MCUs */
    +    cinfo->MCUs_per_row = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width,
    +                    (long) (cinfo->max_h_samp_factor*DCTSIZE));
    +    cinfo->MCU_rows_in_scan = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height,
    +                    (long) (cinfo->max_v_samp_factor*DCTSIZE));
    +
    +    cinfo->blocks_in_MCU = 0;
    +
    +    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +      compptr = cinfo->cur_comp_info[ci];
    +      /* Sampling factors give # of blocks of component in each MCU */
    +      compptr->MCU_width = compptr->h_samp_factor;
    +      compptr->MCU_height = compptr->v_samp_factor;
    +      compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
    +      compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
    +      /* Figure number of non-dummy blocks in last MCU column & row */
    +      tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
    +      if (tmp == 0) tmp = compptr->MCU_width;
    +      compptr->last_col_width = tmp;
    +      tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
    +      if (tmp == 0) tmp = compptr->MCU_height;
    +      compptr->last_row_height = tmp;
    +      /* Prepare array describing MCU composition */
    +      mcublks = compptr->MCU_blocks;
    +      if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
    +        ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
    +      while (mcublks-- > 0) {
    +        cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
    +      }
    +    }
    +
    +  }
    +}
    +
    +
    +/*
    + * Save away a copy of the Q-table referenced by each component present
    + * in the current scan, unless already saved during a prior scan.
    + *
    + * In a multiple-scan JPEG file, the encoder could assign different components
    + * the same Q-table slot number, but change table definitions between scans
    + * so that each component uses a different Q-table.  (The IJG encoder is not
    + * currently capable of doing this, but other encoders might.)  Since we want
    + * to be able to dequantize all the components at the end of the file, this
    + * means that we have to save away the table actually used for each component.
    + * We do this by copying the table at the start of the first scan containing
    + * the component.
    + * The JPEG spec prohibits the encoder from changing the contents of a Q-table
    + * slot between scans of a component using that slot.  If the encoder does so
    + * anyway, this decoder will simply use the Q-table values that were current
    + * at the start of the first scan for the component.
    + *
    + * The decompressor output side looks only at the saved quant tables,
    + * not at the current Q-table slots.
    + */
    +
    +LOCAL(void)
    +latch_quant_tables (j_decompress_ptr cinfo)
    +{
    +  int ci, qtblno;
    +  jpeg_component_info *compptr;
    +  JQUANT_TBL * qtbl;
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    /* No work if we already saved Q-table for this component */
    +    if (compptr->quant_table != NULL)
    +      continue;
    +    /* Make sure specified quantization table is present */
    +    qtblno = compptr->quant_tbl_no;
    +    if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
    +        cinfo->quant_tbl_ptrs[qtblno] == NULL)
    +      ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
    +    /* OK, save away the quantization table */
    +    qtbl = (JQUANT_TBL *)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(JQUANT_TBL));
    +    MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
    +    compptr->quant_table = qtbl;
    +  }
    +}
    +
    +
    +/*
    + * Initialize the input modules to read a scan of compressed data.
    + * The first call to this is done by jdmaster.c after initializing
    + * the entire decompressor (during jpeg_start_decompress).
    + * Subsequent calls come from consume_markers, below.
    + */
    +
    +METHODDEF(void)
    +start_input_pass (j_decompress_ptr cinfo)
    +{
    +  per_scan_setup(cinfo);
    +  latch_quant_tables(cinfo);
    +  (*cinfo->entropy->start_pass) (cinfo);
    +  (*cinfo->coef->start_input_pass) (cinfo);
    +  cinfo->inputctl->consume_input = cinfo->coef->consume_data;
    +}
    +
    +
    +/*
    + * Finish up after inputting a compressed-data scan.
    + * This is called by the coefficient controller after it's read all
    + * the expected data of the scan.
    + */
    +
    +METHODDEF(void)
    +finish_input_pass (j_decompress_ptr cinfo)
    +{
    +  cinfo->inputctl->consume_input = consume_markers;
    +}
    +
    +
    +/*
    + * Read JPEG markers before, between, or after compressed-data scans.
    + * Change state as necessary when a new scan is reached.
    + * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
    + *
    + * The consume_input method pointer points either here or to the
    + * coefficient controller's consume_data routine, depending on whether
    + * we are reading a compressed data segment or inter-segment markers.
    + */
    +
    +METHODDEF(int)
    +consume_markers (j_decompress_ptr cinfo)
    +{
    +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
    +  int val;
    +
    +  if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
    +    return JPEG_REACHED_EOI;
    +
    +  val = (*cinfo->marker->read_markers) (cinfo);
    +
    +  switch (val) {
    +  case JPEG_REACHED_SOS:        /* Found SOS */
    +    if (inputctl->inheaders) {  /* 1st SOS */
    +      initial_setup(cinfo);
    +      inputctl->inheaders = FALSE;
    +      /* Note: start_input_pass must be called by jdmaster.c
    +       * before any more input can be consumed.  jdapimin.c is
    +       * responsible for enforcing this sequencing.
    +       */
    +    } else {                    /* 2nd or later SOS marker */
    +      if (! inputctl->pub.has_multiple_scans)
    +        ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
    +      start_input_pass(cinfo);
    +    }
    +    break;
    +  case JPEG_REACHED_EOI:        /* Found EOI */
    +    inputctl->pub.eoi_reached = TRUE;
    +    if (inputctl->inheaders) {  /* Tables-only datastream, apparently */
    +      if (cinfo->marker->saw_SOF)
    +        ERREXIT(cinfo, JERR_SOF_NO_SOS);
    +    } else {
    +      /* Prevent infinite loop in coef ctlr's decompress_data routine
    +       * if user set output_scan_number larger than number of scans.
    +       */
    +      if (cinfo->output_scan_number > cinfo->input_scan_number)
    +        cinfo->output_scan_number = cinfo->input_scan_number;
    +    }
    +    break;
    +  case JPEG_SUSPENDED:
    +    break;
    +  }
    +
    +  return val;
    +}
    +
    +
    +/*
    + * Reset state to begin a fresh datastream.
    + */
    +
    +METHODDEF(void)
    +reset_input_controller (j_decompress_ptr cinfo)
    +{
    +  my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
    +
    +  inputctl->pub.consume_input = consume_markers;
    +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
    +  inputctl->pub.eoi_reached = FALSE;
    +  inputctl->inheaders = TRUE;
    +  /* Reset other modules */
    +  (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
    +  (*cinfo->marker->reset_marker_reader) (cinfo);
    +  /* Reset progression state -- would be cleaner if entropy decoder did this */
    +  cinfo->coef_bits = NULL;
    +}
    +
    +
    +/*
    + * Initialize the input controller module.
    + * This is called only once, when the decompression object is created.
    + */
    +
    +GLOBAL(void)
    +jinit_input_controller (j_decompress_ptr cinfo)
    +{
    +  my_inputctl_ptr inputctl;
    +
    +  /* Create subobject in permanent pool */
    +  inputctl = (my_inputctl_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
    +                                SIZEOF(my_input_controller));
    +  cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
    +  /* Initialize method pointers */
    +  inputctl->pub.consume_input = consume_markers;
    +  inputctl->pub.reset_input_controller = reset_input_controller;
    +  inputctl->pub.start_input_pass = start_input_pass;
    +  inputctl->pub.finish_input_pass = finish_input_pass;
    +  /* Initialize state: can't use reset_input_controller since we don't
    +   * want to try to reset other modules yet.
    +   */
    +  inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
    +  inputctl->pub.eoi_reached = FALSE;
    +  inputctl->inheaders = TRUE;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmainct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmainct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmainct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmainct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,516 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdmainct.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the main buffer controller for decompression.
    + * The main buffer lies between the JPEG decompressor proper and the
    + * post-processor; it holds downsampled data in the JPEG colorspace.
    + *
    + * Note that this code is bypassed in raw-data mode, since the application
    + * supplies the equivalent of the main buffer in that case.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * In the current system design, the main buffer need never be a full-image
    + * buffer; any full-height buffers will be found inside the coefficient or
    + * postprocessing controllers.  Nonetheless, the main controller is not
    + * trivial.  Its responsibility is to provide context rows for upsampling/
    + * rescaling, and doing this in an efficient fashion is a bit tricky.
    + *
    + * Postprocessor input data is counted in "row groups".  A row group
    + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
    + * sample rows of each component.  (We require DCT_scaled_size values to be
    + * chosen such that these numbers are integers.  In practice DCT_scaled_size
    + * values will likely be powers of two, so we actually have the stronger
    + * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
    + * Upsampling will typically produce max_v_samp_factor pixel rows from each
    + * row group (times any additional scale factor that the upsampler is
    + * applying).
    + *
    + * The coefficient controller will deliver data to us one iMCU row at a time;
    + * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
    + * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds
    + * to one row of MCUs when the image is fully interleaved.)  Note that the
    + * number of sample rows varies across components, but the number of row
    + * groups does not.  Some garbage sample rows may be included in the last iMCU
    + * row at the bottom of the image.
    + *
    + * Depending on the vertical scaling algorithm used, the upsampler may need
    + * access to the sample row(s) above and below its current input row group.
    + * The upsampler is required to set need_context_rows TRUE at global selection
    + * time if so.  When need_context_rows is FALSE, this controller can simply
    + * obtain one iMCU row at a time from the coefficient controller and dole it
    + * out as row groups to the postprocessor.
    + *
    + * When need_context_rows is TRUE, this controller guarantees that the buffer
    + * passed to postprocessing contains at least one row group's worth of samples
    + * above and below the row group(s) being processed.  Note that the context
    + * rows "above" the first passed row group appear at negative row offsets in
    + * the passed buffer.  At the top and bottom of the image, the required
    + * context rows are manufactured by duplicating the first or last real sample
    + * row; this avoids having special cases in the upsampling inner loops.
    + *
    + * The amount of context is fixed at one row group just because that's a
    + * convenient number for this controller to work with.  The existing
    + * upsamplers really only need one sample row of context.  An upsampler
    + * supporting arbitrary output rescaling might wish for more than one row
    + * group of context when shrinking the image; tough, we don't handle that.
    + * (This is justified by the assumption that downsizing will be handled mostly
    + * by adjusting the DCT_scaled_size values, so that the actual scale factor at
    + * the upsample step needn't be much less than one.)
    + *
    + * To provide the desired context, we have to retain the last two row groups
    + * of one iMCU row while reading in the next iMCU row.  (The last row group
    + * can't be processed until we have another row group for its below-context,
    + * and so we have to save the next-to-last group too for its above-context.)
    + * We could do this most simply by copying data around in our buffer, but
    + * that'd be very slow.  We can avoid copying any data by creating a rather
    + * strange pointer structure.  Here's how it works.  We allocate a workspace
    + * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
    + * of row groups per iMCU row).  We create two sets of redundant pointers to
    + * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized
    + * pointer lists look like this:
    + *                   M+1                          M-1
    + * master pointer --> 0         master pointer --> 0
    + *                    1                            1
    + *                   ...                          ...
    + *                   M-3                          M-3
    + *                   M-2                           M
    + *                   M-1                          M+1
    + *                    M                           M-2
    + *                   M+1                          M-1
    + *                    0                            0
    + * We read alternate iMCU rows using each master pointer; thus the last two
    + * row groups of the previous iMCU row remain un-overwritten in the workspace.
    + * The pointer lists are set up so that the required context rows appear to
    + * be adjacent to the proper places when we pass the pointer lists to the
    + * upsampler.
    + *
    + * The above pictures describe the normal state of the pointer lists.
    + * At top and bottom of the image, we diddle the pointer lists to duplicate
    + * the first or last sample row as necessary (this is cheaper than copying
    + * sample rows around).
    + *
    + * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that
    + * situation each iMCU row provides only one row group so the buffering logic
    + * must be different (eg, we must read two iMCU rows before we can emit the
    + * first row group).  For now, we simply do not support providing context
    + * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to
    + * be worth providing --- if someone wants a 1/8th-size preview, they probably
    + * want it quick and dirty, so a context-free upsampler is sufficient.
    + */
    +
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_d_main_controller pub; /* public fields */
    +
    +  /* Pointer to allocated workspace (M or M+2 row groups). */
    +  JSAMPARRAY buffer[MAX_COMPONENTS];
    +
    +  boolean buffer_full;          /* Have we gotten an iMCU row from decoder? */
    +  JDIMENSION rowgroup_ctr;      /* counts row groups output to postprocessor */
    +
    +  /* Remaining fields are only used in the context case. */
    +
    +  /* These are the master pointers to the funny-order pointer lists. */
    +  JSAMPIMAGE xbuffer[2];        /* pointers to weird pointer lists */
    +
    +  int whichptr;                 /* indicates which pointer set is now in use */
    +  int context_state;            /* process_data state machine status */
    +  JDIMENSION rowgroups_avail;   /* row groups available to postprocessor */
    +  JDIMENSION iMCU_row_ctr;      /* counts iMCU rows to detect image top/bot */
    +} my_main_controller;
    +
    +typedef my_main_controller * my_main_ptr;
    +
    +/* context_state values: */
    +#define CTX_PREPARE_FOR_IMCU    0       /* need to prepare for MCU row */
    +#define CTX_PROCESS_IMCU        1       /* feeding iMCU to postprocessor */
    +#define CTX_POSTPONED_ROW       2       /* feeding postponed row group */
    +
    +
    +/* Forward declarations */
    +METHODDEF(void) process_data_simple_main
    +        JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
    +             JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
    +METHODDEF(void) process_data_context_main
    +        JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
    +             JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
    +#ifdef QUANT_2PASS_SUPPORTED
    +METHODDEF(void) process_data_crank_post
    +        JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
    +             JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
    +#endif
    +
    +
    +LOCAL(void)
    +alloc_funny_pointers (j_decompress_ptr cinfo)
    +/* Allocate space for the funny pointer lists.
    + * This is done only once, not once per pass.
    + */
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  int ci, rgroup;
    +  int M = cinfo->min_DCT_scaled_size;
    +  jpeg_component_info *compptr;
    +  JSAMPARRAY xbuf;
    +
    +  /* Get top-level space for component array pointers.
    +   * We alloc both arrays with one call to save a few cycles.
    +   */
    +  _main->xbuffer[0] = (JSAMPIMAGE)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
    +  _main->xbuffer[1] = _main->xbuffer[0] + cinfo->num_components;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
    +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
    +    /* Get space for pointer lists --- M+4 row groups in each list.
    +     * We alloc both pointer lists with one call to save a few cycles.
    +     */
    +    xbuf = (JSAMPARRAY)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
    +    xbuf += rgroup;             /* want one row group at negative offsets */
    +    _main->xbuffer[0][ci] = xbuf;
    +    xbuf += rgroup * (M + 4);
    +    _main->xbuffer[1][ci] = xbuf;
    +  }
    +}
    +
    +
    +LOCAL(void)
    +make_funny_pointers (j_decompress_ptr cinfo)
    +/* Create the funny pointer lists discussed in the comments above.
    + * The actual workspace is already allocated (in main->buffer),
    + * and the space for the pointer lists is allocated too.
    + * This routine just fills in the curiously ordered lists.
    + * This will be repeated at the beginning of each pass.
    + */
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  int ci, i, rgroup;
    +  int M = cinfo->min_DCT_scaled_size;
    +  jpeg_component_info *compptr;
    +  JSAMPARRAY buf, xbuf0, xbuf1;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
    +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
    +    xbuf0 = _main->xbuffer[0][ci];
    +    xbuf1 = _main->xbuffer[1][ci];
    +    /* First copy the workspace pointers as-is */
    +    buf = _main->buffer[ci];
    +    for (i = 0; i < rgroup * (M + 2); i++) {
    +      xbuf0[i] = xbuf1[i] = buf[i];
    +    }
    +    /* In the second list, put the last four row groups in swapped order */
    +    for (i = 0; i < rgroup * 2; i++) {
    +      xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
    +      xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
    +    }
    +    /* The wraparound pointers at top and bottom will be filled later
    +     * (see set_wraparound_pointers, below).  Initially we want the "above"
    +     * pointers to duplicate the first actual data line.  This only needs
    +     * to happen in xbuffer[0].
    +     */
    +    for (i = 0; i < rgroup; i++) {
    +      xbuf0[i - rgroup] = xbuf0[0];
    +    }
    +  }
    +}
    +
    +
    +LOCAL(void)
    +set_wraparound_pointers (j_decompress_ptr cinfo)
    +/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
    + * This changes the pointer list state from top-of-image to the normal state.
    + */
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  int ci, i, rgroup;
    +  int M = cinfo->min_DCT_scaled_size;
    +  jpeg_component_info *compptr;
    +  JSAMPARRAY xbuf0, xbuf1;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
    +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
    +    xbuf0 = _main->xbuffer[0][ci];
    +    xbuf1 = _main->xbuffer[1][ci];
    +    for (i = 0; i < rgroup; i++) {
    +      xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
    +      xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
    +      xbuf0[rgroup*(M+2) + i] = xbuf0[i];
    +      xbuf1[rgroup*(M+2) + i] = xbuf1[i];
    +    }
    +  }
    +}
    +
    +
    +LOCAL(void)
    +set_bottom_pointers (j_decompress_ptr cinfo)
    +/* Change the pointer lists to duplicate the last sample row at the bottom
    + * of the image.  whichptr indicates which xbuffer holds the final iMCU row.
    + * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
    + */
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  int ci, i, rgroup, iMCUheight, rows_left;
    +  jpeg_component_info *compptr;
    +  JSAMPARRAY xbuf;
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Count sample rows in one iMCU row and in one row group */
    +    iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
    +    rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
    +    /* Count nondummy sample rows remaining for this component */
    +    rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
    +    if (rows_left == 0) rows_left = iMCUheight;
    +    /* Count nondummy row groups.  Should get same answer for each component,
    +     * so we need only do it once.
    +     */
    +    if (ci == 0) {
    +      _main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
    +    }
    +    /* Duplicate the last real sample row rgroup*2 times; this pads out the
    +     * last partial rowgroup and ensures at least one full rowgroup of context.
    +     */
    +    xbuf = _main->xbuffer[_main->whichptr][ci];
    +    for (i = 0; i < rgroup * 2; i++) {
    +      xbuf[rows_left + i] = xbuf[rows_left-1];
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +
    +  switch (pass_mode) {
    +  case JBUF_PASS_THRU:
    +    if (cinfo->upsample->need_context_rows) {
    +      _main->pub.process_data = process_data_context_main;
    +      make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
    +      _main->whichptr = 0;      /* Read first iMCU row into xbuffer[0] */
    +      _main->context_state = CTX_PREPARE_FOR_IMCU;
    +      _main->iMCU_row_ctr = 0;
    +    } else {
    +      /* Simple case with no context needed */
    +      _main->pub.process_data = process_data_simple_main;
    +    }
    +    _main->buffer_full = FALSE; /* Mark buffer empty */
    +    _main->rowgroup_ctr = 0;
    +    break;
    +#ifdef QUANT_2PASS_SUPPORTED
    +  case JBUF_CRANK_DEST:
    +    /* For last pass of 2-pass quantization, just crank the postprocessor */
    +    _main->pub.process_data = process_data_crank_post;
    +    break;
    +#endif
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    break;
    +  }
    +}
    +
    +
    +/*
    + * Process some data.
    + * This handles the simple case where no context is required.
    + */
    +
    +METHODDEF(void)
    +process_data_simple_main (j_decompress_ptr cinfo,
    +                          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                          JDIMENSION out_rows_avail)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +  JDIMENSION rowgroups_avail;
    +
    +  /* Read input data if we haven't filled the main buffer yet */
    +  if (! _main->buffer_full) {
    +    if (! (*cinfo->coef->decompress_data) (cinfo, _main->buffer))
    +      return;                   /* suspension forced, can do nothing more */
    +    _main->buffer_full = TRUE;  /* OK, we have an iMCU row to work with */
    +  }
    +
    +  /* There are always min_DCT_scaled_size row groups in an iMCU row. */
    +  rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
    +  /* Note: at the bottom of the image, we may pass extra garbage row groups
    +   * to the postprocessor.  The postprocessor has to check for bottom
    +   * of image anyway (at row resolution), so no point in us doing it too.
    +   */
    +
    +  /* Feed the postprocessor */
    +  (*cinfo->post->post_process_data) (cinfo, _main->buffer,
    +                                     &_main->rowgroup_ctr, rowgroups_avail,
    +                                     output_buf, out_row_ctr, out_rows_avail);
    +
    +  /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
    +  if (_main->rowgroup_ctr >= rowgroups_avail) {
    +    _main->buffer_full = FALSE;
    +    _main->rowgroup_ctr = 0;
    +  }
    +}
    +
    +
    +/*
    + * Process some data.
    + * This handles the case where context rows must be provided.
    + */
    +
    +METHODDEF(void)
    +process_data_context_main (j_decompress_ptr cinfo,
    +                           JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                           JDIMENSION out_rows_avail)
    +{
    +  my_main_ptr _main = (my_main_ptr) cinfo->main;
    +
    +  /* Read input data if we haven't filled the _main buffer yet */
    +  if (! _main->buffer_full) {
    +    if (! (*cinfo->coef->decompress_data) (cinfo,
    +                                           _main->xbuffer[_main->whichptr]))
    +      return;                   /* suspension forced, can do nothing more */
    +    _main->buffer_full = TRUE;  /* OK, we have an iMCU row to work with */
    +    _main->iMCU_row_ctr++;      /* count rows received */
    +  }
    +
    +  /* Postprocessor typically will not swallow all the input data it is handed
    +   * in one call (due to filling the output buffer first).  Must be prepared
    +   * to exit and restart.  This switch lets us keep track of how far we got.
    +   * Note that each case falls through to the next on successful completion.
    +   */
    +  switch (_main->context_state) {
    +  case CTX_POSTPONED_ROW:
    +    /* Call postprocessor using previously set pointers for postponed row */
    +    (*cinfo->post->post_process_data) (cinfo, _main->xbuffer[_main->whichptr],
    +                        &_main->rowgroup_ctr, _main->rowgroups_avail,
    +                        output_buf, out_row_ctr, out_rows_avail);
    +    if (_main->rowgroup_ctr < _main->rowgroups_avail)
    +      return;                   /* Need to suspend */
    +    _main->context_state = CTX_PREPARE_FOR_IMCU;
    +    if (*out_row_ctr >= out_rows_avail)
    +      return;                   /* Postprocessor exactly filled output buf */
    +    /*FALLTHROUGH*/
    +  case CTX_PREPARE_FOR_IMCU:
    +    /* Prepare to process first M-1 row groups of this iMCU row */
    +    _main->rowgroup_ctr = 0;
    +    _main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
    +    /* Check for bottom of image: if so, tweak pointers to "duplicate"
    +     * the last sample row, and adjust rowgroups_avail to ignore padding rows.
    +     */
    +    if (_main->iMCU_row_ctr == cinfo->total_iMCU_rows)
    +      set_bottom_pointers(cinfo);
    +    _main->context_state = CTX_PROCESS_IMCU;
    +    /*FALLTHROUGH*/
    +  case CTX_PROCESS_IMCU:
    +    /* Call postprocessor using previously set pointers */
    +    (*cinfo->post->post_process_data) (cinfo, _main->xbuffer[_main->whichptr],
    +                        &_main->rowgroup_ctr, _main->rowgroups_avail,
    +                        output_buf, out_row_ctr, out_rows_avail);
    +    if (_main->rowgroup_ctr < _main->rowgroups_avail)
    +      return;                   /* Need to suspend */
    +    /* After the first iMCU, change wraparound pointers to normal state */
    +    if (_main->iMCU_row_ctr == 1)
    +      set_wraparound_pointers(cinfo);
    +    /* Prepare to load new iMCU row using other xbuffer list */
    +    _main->whichptr ^= 1;       /* 0=>1 or 1=>0 */
    +    _main->buffer_full = FALSE;
    +    /* Still need to process last row group of this iMCU row, */
    +    /* which is saved at index M+1 of the other xbuffer */
    +    _main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
    +    _main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
    +    _main->context_state = CTX_POSTPONED_ROW;
    +  }
    +}
    +
    +
    +/*
    + * Process some data.
    + * Final pass of two-pass quantization: just call the postprocessor.
    + * Source data will be the postprocessor controller's internal buffer.
    + */
    +
    +#ifdef QUANT_2PASS_SUPPORTED
    +
    +METHODDEF(void)
    +process_data_crank_post (j_decompress_ptr cinfo,
    +                         JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                         JDIMENSION out_rows_avail)
    +{
    +  (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
    +                                     (JDIMENSION *) NULL, (JDIMENSION) 0,
    +                                     output_buf, out_row_ctr, out_rows_avail);
    +}
    +
    +#endif /* QUANT_2PASS_SUPPORTED */
    +
    +
    +/*
    + * Initialize main buffer controller.
    + */
    +
    +GLOBAL(void)
    +jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_main_ptr _main;
    +  int ci, rgroup, ngroups;
    +  jpeg_component_info *compptr;
    +
    +  _main = (my_main_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_main_controller));
    +  cinfo->main = (struct jpeg_d_main_controller *) _main;
    +  _main->pub.start_pass = start_pass_main;
    +
    +  if (need_full_buffer)         /* shouldn't happen */
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +
    +  /* Allocate the workspace.
    +   * ngroups is the number of row groups we need.
    +   */
    +  if (cinfo->upsample->need_context_rows) {
    +    if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
    +      ERREXIT(cinfo, JERR_NOTIMPL);
    +    alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
    +    ngroups = cinfo->min_DCT_scaled_size + 2;
    +  } else {
    +    ngroups = cinfo->min_DCT_scaled_size;
    +  }
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
    +      cinfo->min_DCT_scaled_size; /* height of a row group of component */
    +    _main->buffer[ci] = (*cinfo->mem->alloc_sarray)
    +                        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                         compptr->width_in_blocks * compptr->DCT_scaled_size,
    +                         (JDIMENSION) (rgroup * ngroups));
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmarker.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmarker.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmarker.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmarker.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1390 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdmarker.c
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains routines to decode JPEG datastream markers.
    + * Most of the complexity arises from our desire to support input
    + * suspension: if not all of the data for a marker is available,
    + * we must exit back to the application.  On resumption, we reprocess
    + * the marker.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +typedef enum {                  /* JPEG marker codes */
    +  M_SOF0  = 0xc0,
    +  M_SOF1  = 0xc1,
    +  M_SOF2  = 0xc2,
    +  M_SOF3  = 0xc3,
    +
    +  M_SOF5  = 0xc5,
    +  M_SOF6  = 0xc6,
    +  M_SOF7  = 0xc7,
    +
    +  M_JPG   = 0xc8,
    +  M_SOF9  = 0xc9,
    +  M_SOF10 = 0xca,
    +  M_SOF11 = 0xcb,
    +
    +  M_SOF13 = 0xcd,
    +  M_SOF14 = 0xce,
    +  M_SOF15 = 0xcf,
    +
    +  M_DHT   = 0xc4,
    +
    +  M_DAC   = 0xcc,
    +
    +  M_RST0  = 0xd0,
    +  M_RST1  = 0xd1,
    +  M_RST2  = 0xd2,
    +  M_RST3  = 0xd3,
    +  M_RST4  = 0xd4,
    +  M_RST5  = 0xd5,
    +  M_RST6  = 0xd6,
    +  M_RST7  = 0xd7,
    +
    +  M_SOI   = 0xd8,
    +  M_EOI   = 0xd9,
    +  M_SOS   = 0xda,
    +  M_DQT   = 0xdb,
    +  M_DNL   = 0xdc,
    +  M_DRI   = 0xdd,
    +  M_DHP   = 0xde,
    +  M_EXP   = 0xdf,
    +
    +  M_APP0  = 0xe0,
    +  M_APP1  = 0xe1,
    +  M_APP2  = 0xe2,
    +  M_APP3  = 0xe3,
    +  M_APP4  = 0xe4,
    +  M_APP5  = 0xe5,
    +  M_APP6  = 0xe6,
    +  M_APP7  = 0xe7,
    +  M_APP8  = 0xe8,
    +  M_APP9  = 0xe9,
    +  M_APP10 = 0xea,
    +  M_APP11 = 0xeb,
    +  M_APP12 = 0xec,
    +  M_APP13 = 0xed,
    +  M_APP14 = 0xee,
    +  M_APP15 = 0xef,
    +
    +  M_JPG0  = 0xf0,
    +  M_JPG13 = 0xfd,
    +  M_COM   = 0xfe,
    +
    +  M_TEM   = 0x01,
    +
    +  M_ERROR = 0x100
    +} JPEG_MARKER;
    +
    +
    +/* Private state */
    +
    +typedef struct {
    +  struct jpeg_marker_reader pub; /* public fields */
    +
    +  /* Application-overridable marker processing methods */
    +  jpeg_marker_parser_method process_COM;
    +  jpeg_marker_parser_method process_APPn[16];
    +
    +  /* Limit on marker data length to save for each marker type */
    +  unsigned int length_limit_COM;
    +  unsigned int length_limit_APPn[16];
    +
    +  /* Status of COM/APPn marker saving */
    +  jpeg_saved_marker_ptr cur_marker;     /* NULL if not processing a marker */
    +  unsigned int bytes_read;              /* data bytes read so far in marker */
    +  /* Note: cur_marker is not linked into marker_list until it's all read. */
    +} my_marker_reader;
    +
    +typedef my_marker_reader * my_marker_ptr;
    +
    +
    +/*
    + * Macros for fetching data from the data source module.
    + *
    + * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
    + * the current restart point; we update them only when we have reached a
    + * suitable place to restart if a suspension occurs.
    + */
    +
    +/* Declare and initialize local copies of input pointer/count */
    +#define INPUT_VARS(cinfo)  \
    +        struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
    +        const JOCTET * next_input_byte = datasrc->next_input_byte;  \
    +        size_t bytes_in_buffer = datasrc->bytes_in_buffer
    +
    +/* Unload the local copies --- do this only at a restart boundary */
    +#define INPUT_SYNC(cinfo)  \
    +        ( datasrc->next_input_byte = next_input_byte,  \
    +          datasrc->bytes_in_buffer = bytes_in_buffer )
    +
    +/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
    +#define INPUT_RELOAD(cinfo)  \
    +        ( next_input_byte = datasrc->next_input_byte,  \
    +          bytes_in_buffer = datasrc->bytes_in_buffer )
    +
    +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
    + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
    + * but we must reload the local copies after a successful fill.
    + */
    +#define MAKE_BYTE_AVAIL(cinfo,action)  \
    +        if (bytes_in_buffer == 0) {  \
    +          if (! (*datasrc->fill_input_buffer) (cinfo))  \
    +            { action; }  \
    +          INPUT_RELOAD(cinfo);  \
    +        }
    +
    +/* Read a byte into variable V.
    + * If must suspend, take the specified action (typically "return FALSE").
    + */
    +#define INPUT_BYTE(cinfo,V,action)  \
    +        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
    +                  bytes_in_buffer--; \
    +                  V = GETJOCTET(*next_input_byte++); )
    +
    +/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
    + * V should be declared unsigned int or perhaps INT32.
    + */
    +#define INPUT_2BYTES(cinfo,V,action)  \
    +        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
    +                  bytes_in_buffer--; \
    +                  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
    +                  MAKE_BYTE_AVAIL(cinfo,action); \
    +                  bytes_in_buffer--; \
    +                  V += GETJOCTET(*next_input_byte++); )
    +
    +
    +/*
    + * Routines to process JPEG markers.
    + *
    + * Entry condition: JPEG marker itself has been read and its code saved
    + *   in cinfo->unread_marker; input restart point is just after the marker.
    + *
    + * Exit: if return TRUE, have read and processed any parameters, and have
    + *   updated the restart point to point after the parameters.
    + *   If return FALSE, was forced to suspend before reaching end of
    + *   marker parameters; restart point has not been moved.  Same routine
    + *   will be called again after application supplies more input data.
    + *
    + * This approach to suspension assumes that all of a marker's parameters
    + * can fit into a single input bufferload.  This should hold for "normal"
    + * markers.  Some COM/APPn markers might have large parameter segments
    + * that might not fit.  If we are simply dropping such a marker, we use
    + * skip_input_data to get past it, and thereby put the problem on the
    + * source manager's shoulders.  If we are saving the marker's contents
    + * into memory, we use a slightly different convention: when forced to
    + * suspend, the marker processor updates the restart point to the end of
    + * what it's consumed (ie, the end of the buffer) before returning FALSE.
    + * On resumption, cinfo->unread_marker still contains the marker code,
    + * but the data source will point to the next chunk of marker data.
    + * The marker processor must retain internal state to deal with this.
    + *
    + * Note that we don't bother to avoid duplicate trace messages if a
    + * suspension occurs within marker parameters.  Other side effects
    + * require more care.
    + */
    +
    +
    +LOCAL(boolean)
    +get_soi (j_decompress_ptr cinfo)
    +/* Process an SOI marker */
    +{
    +  int i;
    +
    +  TRACEMS(cinfo, 1, JTRC_SOI);
    +
    +  if (cinfo->marker->saw_SOI)
    +    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
    +
    +  /* Reset all parameters that are defined to be reset by SOI */
    +
    +  for (i = 0; i < NUM_ARITH_TBLS; i++) {
    +    cinfo->arith_dc_L[i] = 0;
    +    cinfo->arith_dc_U[i] = 1;
    +    cinfo->arith_ac_K[i] = 5;
    +  }
    +  cinfo->restart_interval = 0;
    +
    +  /* Set initial assumptions for colorspace etc */
    +
    +  cinfo->jpeg_color_space = JCS_UNKNOWN;
    +  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
    +
    +  cinfo->saw_JFIF_marker = FALSE;
    +  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
    +  cinfo->JFIF_minor_version = 1;
    +  cinfo->density_unit = 0;
    +  cinfo->X_density = 1;
    +  cinfo->Y_density = 1;
    +  cinfo->saw_Adobe_marker = FALSE;
    +  cinfo->Adobe_transform = 0;
    +
    +  cinfo->marker->saw_SOI = TRUE;
    +
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
    +/* Process a SOFn marker */
    +{
    +  INT32 length;
    +  int c, ci;
    +  jpeg_component_info * compptr;
    +  INPUT_VARS(cinfo);
    +
    +  cinfo->progressive_mode = is_prog;
    +  cinfo->arith_code = is_arith;
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +
    +  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
    +  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
    +  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
    +  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
    +
    +  length -= 8;
    +
    +  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
    +           (int) cinfo->image_width, (int) cinfo->image_height,
    +           cinfo->num_components);
    +
    +  if (cinfo->marker->saw_SOF)
    +    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
    +
    +  /* We don't support files in which the image height is initially specified */
    +  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
    +  /* might as well have a general sanity check. */
    +  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
    +      || cinfo->num_components <= 0)
    +    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
    +
    +  if (length != (cinfo->num_components * 3))
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  if (cinfo->comp_info == NULL) { /* do only once, even if suspend */
    +    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
    +                        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                         cinfo->num_components * SIZEOF(jpeg_component_info));
    +    MEMZERO(cinfo->comp_info,
    +            cinfo->num_components * SIZEOF(jpeg_component_info));
    +  }
    +
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    compptr->component_index = ci;
    +    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
    +    INPUT_BYTE(cinfo, c, return FALSE);
    +    compptr->h_samp_factor = (c >> 4) & 15;
    +    compptr->v_samp_factor = (c     ) & 15;
    +    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
    +
    +    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
    +             compptr->component_id, compptr->h_samp_factor,
    +             compptr->v_samp_factor, compptr->quant_tbl_no);
    +  }
    +
    +  cinfo->marker->saw_SOF = TRUE;
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +get_sos (j_decompress_ptr cinfo)
    +/* Process a SOS marker */
    +{
    +  INT32 length;
    +  int i, ci, n, c, cc;
    +  jpeg_component_info * compptr;
    +  INPUT_VARS(cinfo);
    +
    +  if (! cinfo->marker->saw_SOF)
    +    ERREXIT(cinfo, JERR_SOS_NO_SOF);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +
    +  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
    +
    +  TRACEMS1(cinfo, 1, JTRC_SOS, n);
    +
    +  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  cinfo->comps_in_scan = n;
    +
    +  /* Collect the component-spec parameters */
    +
    +  for (i = 0; i < n; i++) {
    +    INPUT_BYTE(cinfo, cc, return FALSE);
    +    INPUT_BYTE(cinfo, c, return FALSE);
    +
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      if (cc == compptr->component_id)
    +        goto id_found;
    +    }
    +
    +    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
    +
    +  id_found:
    +
    +    cinfo->cur_comp_info[i] = compptr;
    +    compptr->dc_tbl_no = (c >> 4) & 15;
    +    compptr->ac_tbl_no = (c     ) & 15;
    +
    +    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
    +             compptr->dc_tbl_no, compptr->ac_tbl_no);
    +
    +    /* This CSi (cc) should differ from the previous CSi */
    +    for (ci = 0; ci < i; ci++) {
    +      if (cinfo->cur_comp_info[ci] == compptr)
    +        ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
    +    }
    +  }
    +
    +  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
    +  INPUT_BYTE(cinfo, c, return FALSE);
    +  cinfo->Ss = c;
    +  INPUT_BYTE(cinfo, c, return FALSE);
    +  cinfo->Se = c;
    +  INPUT_BYTE(cinfo, c, return FALSE);
    +  cinfo->Ah = (c >> 4) & 15;
    +  cinfo->Al = (c     ) & 15;
    +
    +  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
    +           cinfo->Ah, cinfo->Al);
    +
    +  /* Prepare to scan data & restart markers */
    +  cinfo->marker->next_restart_num = 0;
    +
    +  /* Count another SOS marker */
    +  cinfo->input_scan_number++;
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +#ifdef D_ARITH_CODING_SUPPORTED
    +
    +LOCAL(boolean)
    +get_dac (j_decompress_ptr cinfo)
    +/* Process a DAC marker */
    +{
    +  INT32 length;
    +  int index, val;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +  length -= 2;
    +
    +  while (length > 0) {
    +    INPUT_BYTE(cinfo, index, return FALSE);
    +    INPUT_BYTE(cinfo, val, return FALSE);
    +
    +    length -= 2;
    +
    +    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
    +
    +    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
    +      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
    +
    +    if (index >= NUM_ARITH_TBLS) { /* define AC table */
    +      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
    +    } else {                    /* define DC table */
    +      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
    +      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
    +      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
    +        ERREXIT1(cinfo, JERR_DAC_VALUE, val);
    +    }
    +  }
    +
    +  if (length != 0)
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +#else /* ! D_ARITH_CODING_SUPPORTED */
    +
    +#define get_dac(cinfo)  skip_variable(cinfo)
    +
    +#endif /* D_ARITH_CODING_SUPPORTED */
    +
    +
    +LOCAL(boolean)
    +get_dht (j_decompress_ptr cinfo)
    +/* Process a DHT marker */
    +{
    +  INT32 length;
    +  UINT8 bits[17];
    +  UINT8 huffval[256];
    +  int i, index, count;
    +  JHUFF_TBL **htblptr;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +  length -= 2;
    +
    +  while (length > 16) {
    +    INPUT_BYTE(cinfo, index, return FALSE);
    +
    +    TRACEMS1(cinfo, 1, JTRC_DHT, index);
    +
    +    bits[0] = 0;
    +    count = 0;
    +    for (i = 1; i <= 16; i++) {
    +      INPUT_BYTE(cinfo, bits[i], return FALSE);
    +      count += bits[i];
    +    }
    +
    +    length -= 1 + 16;
    +
    +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
    +             bits[1], bits[2], bits[3], bits[4],
    +             bits[5], bits[6], bits[7], bits[8]);
    +    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
    +             bits[9], bits[10], bits[11], bits[12],
    +             bits[13], bits[14], bits[15], bits[16]);
    +
    +    /* Here we just do minimal validation of the counts to avoid walking
    +     * off the end of our table space.  jdhuff.c will check more carefully.
    +     */
    +    if (count > 256 || ((INT32) count) > length)
    +      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    +
    +    for (i = 0; i < count; i++)
    +      INPUT_BYTE(cinfo, huffval[i], return FALSE);
    +
    +    length -= count;
    +
    +    if (index & 0x10) {         /* AC table definition */
    +      index -= 0x10;
    +      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
    +    } else {                    /* DC table definition */
    +      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
    +    }
    +
    +    if (index < 0 || index >= NUM_HUFF_TBLS)
    +      ERREXIT1(cinfo, JERR_DHT_INDEX, index);
    +
    +    if (*htblptr == NULL)
    +      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
    +
    +    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
    +    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
    +  }
    +
    +  if (length != 0)
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +get_dqt (j_decompress_ptr cinfo)
    +/* Process a DQT marker */
    +{
    +  INT32 length;
    +  int n, i, prec;
    +  unsigned int tmp;
    +  JQUANT_TBL *quant_ptr;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +  length -= 2;
    +
    +  while (length > 0) {
    +    INPUT_BYTE(cinfo, n, return FALSE);
    +    prec = n >> 4;
    +    n &= 0x0F;
    +
    +    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
    +
    +    if (n >= NUM_QUANT_TBLS)
    +      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
    +
    +    if (cinfo->quant_tbl_ptrs[n] == NULL)
    +      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
    +    quant_ptr = cinfo->quant_tbl_ptrs[n];
    +
    +    for (i = 0; i < DCTSIZE2; i++) {
    +      if (prec)
    +        INPUT_2BYTES(cinfo, tmp, return FALSE);
    +      else
    +        INPUT_BYTE(cinfo, tmp, return FALSE);
    +      /* We convert the zigzag-order table to natural array order. */
    +      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
    +    }
    +
    +    if (cinfo->err->trace_level >= 2) {
    +      for (i = 0; i < DCTSIZE2; i += 8) {
    +        TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
    +                 quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
    +                 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
    +                 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
    +                 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
    +      }
    +    }
    +
    +    length -= DCTSIZE2+1;
    +    if (prec) length -= DCTSIZE2;
    +  }
    +
    +  if (length != 0)
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +get_dri (j_decompress_ptr cinfo)
    +/* Process a DRI marker */
    +{
    +  INT32 length;
    +  unsigned int tmp;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +
    +  if (length != 4)
    +    ERREXIT(cinfo, JERR_BAD_LENGTH);
    +
    +  INPUT_2BYTES(cinfo, tmp, return FALSE);
    +
    +  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
    +
    +  cinfo->restart_interval = tmp;
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Routines for processing APPn and COM markers.
    + * These are either saved in memory or discarded, per application request.
    + * APP0 and APP14 are specially checked to see if they are
    + * JFIF and Adobe markers, respectively.
    + */
    +
    +#define APP0_DATA_LEN   14      /* Length of interesting data in APP0 */
    +#define APP14_DATA_LEN  12      /* Length of interesting data in APP14 */
    +#define APPN_DATA_LEN   14      /* Must be the largest of the above!! */
    +
    +
    +LOCAL(void)
    +examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
    +              unsigned int datalen, INT32 remaining)
    +/* Examine first few bytes from an APP0.
    + * Take appropriate action if it is a JFIF marker.
    + * datalen is # of bytes at data[], remaining is length of rest of marker data.
    + */
    +{
    +  INT32 totallen = (INT32) datalen + remaining;
    +
    +  if (datalen >= APP0_DATA_LEN &&
    +      GETJOCTET(data[0]) == 0x4A &&
    +      GETJOCTET(data[1]) == 0x46 &&
    +      GETJOCTET(data[2]) == 0x49 &&
    +      GETJOCTET(data[3]) == 0x46 &&
    +      GETJOCTET(data[4]) == 0) {
    +    /* Found JFIF APP0 marker: save info */
    +    cinfo->saw_JFIF_marker = TRUE;
    +    cinfo->JFIF_major_version = GETJOCTET(data[5]);
    +    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
    +    cinfo->density_unit = GETJOCTET(data[7]);
    +    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
    +    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
    +    /* Check version.
    +     * Major version must be 1, anything else signals an incompatible change.
    +     * (We used to treat this as an error, but now it's a nonfatal warning,
    +     * because some bozo at Hijaak couldn't read the spec.)
    +     * Minor version should be 0..2, but process anyway if newer.
    +     */
    +    if (cinfo->JFIF_major_version != 1)
    +      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
    +              cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
    +    /* Generate trace messages */
    +    TRACEMS5(cinfo, 1, JTRC_JFIF,
    +             cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
    +             cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
    +    /* Validate thumbnail dimensions and issue appropriate messages */
    +    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
    +      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
    +               GETJOCTET(data[12]), GETJOCTET(data[13]));
    +    totallen -= APP0_DATA_LEN;
    +    if (totallen !=
    +        ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
    +      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
    +  } else if (datalen >= 6 &&
    +      GETJOCTET(data[0]) == 0x4A &&
    +      GETJOCTET(data[1]) == 0x46 &&
    +      GETJOCTET(data[2]) == 0x58 &&
    +      GETJOCTET(data[3]) == 0x58 &&
    +      GETJOCTET(data[4]) == 0) {
    +    /* Found JFIF "JFXX" extension APP0 marker */
    +    /* The library doesn't actually do anything with these,
    +     * but we try to produce a helpful trace message.
    +     */
    +    switch (GETJOCTET(data[5])) {
    +    case 0x10:
    +      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
    +      break;
    +    case 0x11:
    +      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
    +      break;
    +    case 0x13:
    +      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
    +      break;
    +    default:
    +      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
    +               GETJOCTET(data[5]), (int) totallen);
    +      break;
    +    }
    +  } else {
    +    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
    +    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
    +
    +    /*
    +     * In this case we have seen the APP0 marker but the remaining
    +     * APP0 section may be corrupt.  Regardless, we will set the
    +     * saw_JFIF_marker flag as it is important for making the
    +     * correct choice of JPEG color space later (we will assume
    +     * YCbCr in this case).  The version and density fields will
    +     * contain default values, which should be sufficient for our needs.
    +     */
    +    cinfo->saw_JFIF_marker = TRUE;
    +  }
    +}
    +
    +
    +LOCAL(void)
    +examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
    +               unsigned int datalen, INT32 remaining)
    +/* Examine first few bytes from an APP14.
    + * Take appropriate action if it is an Adobe marker.
    + * datalen is # of bytes at data[], remaining is length of rest of marker data.
    + */
    +{
    +  unsigned int version, flags0, flags1, transform;
    +
    +  if (datalen >= APP14_DATA_LEN &&
    +      GETJOCTET(data[0]) == 0x41 &&
    +      GETJOCTET(data[1]) == 0x64 &&
    +      GETJOCTET(data[2]) == 0x6F &&
    +      GETJOCTET(data[3]) == 0x62 &&
    +      GETJOCTET(data[4]) == 0x65) {
    +    /* Found Adobe APP14 marker */
    +    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
    +    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
    +    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
    +    transform = GETJOCTET(data[11]);
    +    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
    +    cinfo->saw_Adobe_marker = TRUE;
    +    cinfo->Adobe_transform = (UINT8) transform;
    +  } else {
    +    /* Start of APP14 does not match "Adobe", or too short */
    +    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
    +  }
    +}
    +
    +
    +METHODDEF(boolean)
    +get_interesting_appn (j_decompress_ptr cinfo)
    +/* Process an APP0 or APP14 marker without saving it */
    +{
    +  INT32 length;
    +  JOCTET b[APPN_DATA_LEN];
    +  unsigned int i, numtoread;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +  length -= 2;
    +
    +  /* get the interesting part of the marker data */
    +  if (length >= APPN_DATA_LEN)
    +    numtoread = APPN_DATA_LEN;
    +  else if (length > 0)
    +    numtoread = (unsigned int) length;
    +  else
    +    numtoread = 0;
    +  for (i = 0; i < numtoread; i++)
    +    INPUT_BYTE(cinfo, b[i], return FALSE);
    +  length -= numtoread;
    +
    +  /* process it */
    +  switch (cinfo->unread_marker) {
    +  case M_APP0:
    +    examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
    +    break;
    +  case M_APP14:
    +    examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
    +    break;
    +  default:
    +    /* can't get here unless jpeg_save_markers chooses wrong processor */
    +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
    +    break;
    +  }
    +
    +  /* skip any remaining data -- could be lots */
    +  INPUT_SYNC(cinfo);
    +  if (length > 0)
    +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
    +
    +  return TRUE;
    +}
    +
    +
    +#ifdef SAVE_MARKERS_SUPPORTED
    +
    +METHODDEF(boolean)
    +save_marker (j_decompress_ptr cinfo)
    +/* Save an APPn or COM marker into the marker list */
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
    +  unsigned int bytes_read, data_length;
    +  JOCTET FAR * data;
    +  INT32 length = 0;
    +  INPUT_VARS(cinfo);
    +
    +  if (cur_marker == NULL) {
    +    /* begin reading a marker */
    +    INPUT_2BYTES(cinfo, length, return FALSE);
    +    length -= 2;
    +    if (length >= 0) {          /* watch out for bogus length word */
    +      /* figure out how much we want to save */
    +      unsigned int limit;
    +      if (cinfo->unread_marker == (int) M_COM)
    +        limit = marker->length_limit_COM;
    +      else
    +        limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
    +      if ((unsigned int) length < limit)
    +        limit = (unsigned int) length;
    +      /* allocate and initialize the marker item */
    +      cur_marker = (jpeg_saved_marker_ptr)
    +        (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                    SIZEOF(struct jpeg_marker_struct) + limit);
    +      cur_marker->next = NULL;
    +      cur_marker->marker = (UINT8) cinfo->unread_marker;
    +      cur_marker->original_length = (unsigned int) length;
    +      cur_marker->data_length = limit;
    +      /* data area is just beyond the jpeg_marker_struct */
    +      data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
    +      marker->cur_marker = cur_marker;
    +      marker->bytes_read = 0;
    +      bytes_read = 0;
    +      data_length = limit;
    +    } else {
    +      /* deal with bogus length word */
    +      bytes_read = data_length = 0;
    +      data = NULL;
    +    }
    +  } else {
    +    /* resume reading a marker */
    +    bytes_read = marker->bytes_read;
    +    data_length = cur_marker->data_length;
    +    data = cur_marker->data + bytes_read;
    +  }
    +
    +  while (bytes_read < data_length) {
    +    INPUT_SYNC(cinfo);          /* move the restart point to here */
    +    marker->bytes_read = bytes_read;
    +    /* If there's not at least one byte in buffer, suspend */
    +    MAKE_BYTE_AVAIL(cinfo, return FALSE);
    +    /* Copy bytes with reasonable rapidity */
    +    while (bytes_read < data_length && bytes_in_buffer > 0) {
    +      *data++ = *next_input_byte++;
    +      bytes_in_buffer--;
    +      bytes_read++;
    +    }
    +  }
    +
    +  /* Done reading what we want to read */
    +  if (cur_marker != NULL) {     /* will be NULL if bogus length word */
    +    /* Add new marker to end of list */
    +    if (cinfo->marker_list == NULL) {
    +      cinfo->marker_list = cur_marker;
    +    } else {
    +      jpeg_saved_marker_ptr prev = cinfo->marker_list;
    +      while (prev->next != NULL)
    +        prev = prev->next;
    +      prev->next = cur_marker;
    +    }
    +    /* Reset pointer & calc remaining data length */
    +    data = cur_marker->data;
    +    length = cur_marker->original_length - data_length;
    +  }
    +  /* Reset to initial state for next marker */
    +  marker->cur_marker = NULL;
    +
    +  /* Process the marker if interesting; else just make a generic trace msg */
    +  switch (cinfo->unread_marker) {
    +  case M_APP0:
    +    examine_app0(cinfo, data, data_length, length);
    +    break;
    +  case M_APP14:
    +    examine_app14(cinfo, data, data_length, length);
    +    break;
    +  default:
    +    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
    +             (int) (data_length + length));
    +    break;
    +  }
    +
    +  /* skip any remaining data -- could be lots */
    +  INPUT_SYNC(cinfo);            /* do before skip_input_data */
    +  if (length > 0)
    +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
    +
    +  return TRUE;
    +}
    +
    +#endif /* SAVE_MARKERS_SUPPORTED */
    +
    +
    +METHODDEF(boolean)
    +skip_variable (j_decompress_ptr cinfo)
    +/* Skip over an unknown or uninteresting variable-length marker */
    +{
    +  INT32 length;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_2BYTES(cinfo, length, return FALSE);
    +  length -= 2;
    +
    +  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
    +
    +  INPUT_SYNC(cinfo);            /* do before skip_input_data */
    +  if (length > 0)
    +    (*cinfo->src->skip_input_data) (cinfo, (long) length);
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Find the next JPEG marker, save it in cinfo->unread_marker.
    + * Returns FALSE if had to suspend before reaching a marker;
    + * in that case cinfo->unread_marker is unchanged.
    + *
    + * Note that the result might not be a valid marker code,
    + * but it will never be 0 or FF.
    + */
    +
    +LOCAL(boolean)
    +next_marker (j_decompress_ptr cinfo)
    +{
    +  int c;
    +  INPUT_VARS(cinfo);
    +
    +  for (;;) {
    +    INPUT_BYTE(cinfo, c, return FALSE);
    +    /* Skip any non-FF bytes.
    +     * This may look a bit inefficient, but it will not occur in a valid file.
    +     * We sync after each discarded byte so that a suspending data source
    +     * can discard the byte from its buffer.
    +     */
    +    while (c != 0xFF) {
    +      cinfo->marker->discarded_bytes++;
    +      INPUT_SYNC(cinfo);
    +      INPUT_BYTE(cinfo, c, return FALSE);
    +    }
    +    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
    +     * pad bytes, so don't count them in discarded_bytes.  We assume there
    +     * will not be so many consecutive FF bytes as to overflow a suspending
    +     * data source's input buffer.
    +     */
    +    do {
    +      INPUT_BYTE(cinfo, c, return FALSE);
    +    } while (c == 0xFF);
    +    if (c != 0)
    +      break;                    /* found a valid marker, exit loop */
    +    /* Reach here if we found a stuffed-zero data sequence (FF/00).
    +     * Discard it and loop back to try again.
    +     */
    +    cinfo->marker->discarded_bytes += 2;
    +    INPUT_SYNC(cinfo);
    +  }
    +
    +  if (cinfo->marker->discarded_bytes != 0) {
    +    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
    +    cinfo->marker->discarded_bytes = 0;
    +  }
    +
    +  cinfo->unread_marker = c;
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +LOCAL(boolean)
    +first_marker (j_decompress_ptr cinfo)
    +/* Like next_marker, but used to obtain the initial SOI marker. */
    +/* For this marker, we do not allow preceding garbage or fill; otherwise,
    + * we might well scan an entire input file before realizing it ain't JPEG.
    + * If an application wants to process non-JFIF files, it must seek to the
    + * SOI before calling the JPEG library.
    + */
    +{
    +  int c, c2;
    +  INPUT_VARS(cinfo);
    +
    +  INPUT_BYTE(cinfo, c, return FALSE);
    +  INPUT_BYTE(cinfo, c2, return FALSE);
    +  if (c != 0xFF || c2 != (int) M_SOI)
    +    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
    +
    +  cinfo->unread_marker = c2;
    +
    +  INPUT_SYNC(cinfo);
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Read markers until SOS or EOI.
    + *
    + * Returns same codes as are defined for jpeg_consume_input:
    + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
    + */
    +
    +METHODDEF(int)
    +read_markers (j_decompress_ptr cinfo)
    +{
    +  /* Outer loop repeats once for each marker. */
    +  for (;;) {
    +    /* Collect the marker proper, unless we already did. */
    +    /* NB: first_marker() enforces the requirement that SOI appear first. */
    +    if (cinfo->unread_marker == 0) {
    +      if (! cinfo->marker->saw_SOI) {
    +        if (! first_marker(cinfo))
    +          return JPEG_SUSPENDED;
    +      } else {
    +        if (! next_marker(cinfo))
    +          return JPEG_SUSPENDED;
    +      }
    +    }
    +    /* At this point cinfo->unread_marker contains the marker code and the
    +     * input point is just past the marker proper, but before any parameters.
    +     * A suspension will cause us to return with this state still true.
    +     */
    +    switch (cinfo->unread_marker) {
    +    case M_SOI:
    +      if (! get_soi(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_SOF0:                /* Baseline */
    +    case M_SOF1:                /* Extended sequential, Huffman */
    +      if (! get_sof(cinfo, FALSE, FALSE))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_SOF2:                /* Progressive, Huffman */
    +      if (! get_sof(cinfo, TRUE, FALSE))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_SOF9:                /* Extended sequential, arithmetic */
    +      if (! get_sof(cinfo, FALSE, TRUE))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_SOF10:               /* Progressive, arithmetic */
    +      if (! get_sof(cinfo, TRUE, TRUE))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    /* Currently unsupported SOFn types */
    +    case M_SOF3:                /* Lossless, Huffman */
    +    case M_SOF5:                /* Differential sequential, Huffman */
    +    case M_SOF6:                /* Differential progressive, Huffman */
    +    case M_SOF7:                /* Differential lossless, Huffman */
    +    case M_JPG:                 /* Reserved for JPEG extensions */
    +    case M_SOF11:               /* Lossless, arithmetic */
    +    case M_SOF13:               /* Differential sequential, arithmetic */
    +    case M_SOF14:               /* Differential progressive, arithmetic */
    +    case M_SOF15:               /* Differential lossless, arithmetic */
    +      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
    +      break;
    +
    +    case M_SOS:
    +      if (! get_sos(cinfo))
    +        return JPEG_SUSPENDED;
    +      cinfo->unread_marker = 0; /* processed the marker */
    +      return JPEG_REACHED_SOS;
    +
    +    case M_EOI:
    +      TRACEMS(cinfo, 1, JTRC_EOI);
    +      cinfo->unread_marker = 0; /* processed the marker */
    +      return JPEG_REACHED_EOI;
    +
    +    case M_DAC:
    +      if (! get_dac(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_DHT:
    +      if (! get_dht(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_DQT:
    +      if (! get_dqt(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_DRI:
    +      if (! get_dri(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_APP0:
    +    case M_APP1:
    +    case M_APP2:
    +    case M_APP3:
    +    case M_APP4:
    +    case M_APP5:
    +    case M_APP6:
    +    case M_APP7:
    +    case M_APP8:
    +    case M_APP9:
    +    case M_APP10:
    +    case M_APP11:
    +    case M_APP12:
    +    case M_APP13:
    +    case M_APP14:
    +    case M_APP15:
    +      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
    +                cinfo->unread_marker - (int) M_APP0]) (cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_COM:
    +      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    case M_RST0:                /* these are all parameterless */
    +    case M_RST1:
    +    case M_RST2:
    +    case M_RST3:
    +    case M_RST4:
    +    case M_RST5:
    +    case M_RST6:
    +    case M_RST7:
    +    case M_TEM:
    +      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
    +      break;
    +
    +    case M_DNL:                 /* Ignore DNL ... perhaps the wrong thing */
    +      if (! skip_variable(cinfo))
    +        return JPEG_SUSPENDED;
    +      break;
    +
    +    default:                    /* must be DHP, EXP, JPGn, or RESn */
    +      /* For now, we treat the reserved markers as fatal errors since they are
    +       * likely to be used to signal incompatible JPEG Part 3 extensions.
    +       * Once the JPEG 3 version-number marker is well defined, this code
    +       * ought to change!
    +       * [To be behaviorally compatible with other popular image display
    +       * applications, we are now treating these unknown markers as warnings,
    +       * rather than errors.  This allows processing to continue, although
    +       * any portions of the image after the bad marker may be corrupted
    +       * and/or rendered gray.  See 4511441.]
    +       */
    +      WARNMS1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
    +      break;
    +    }
    +    /* Successfully processed marker, so reset state variable */
    +    cinfo->unread_marker = 0;
    +  } /* end loop */
    +}
    +
    +
    +/*
    + * Read a restart marker, which is expected to appear next in the datastream;
    + * if the marker is not there, take appropriate recovery action.
    + * Returns FALSE if suspension is required.
    + *
    + * This is called by the entropy decoder after it has read an appropriate
    + * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
    + * has already read a marker from the data source.  Under normal conditions
    + * cinfo->unread_marker will be reset to 0 before returning; if not reset,
    + * it holds a marker which the decoder will be unable to read past.
    + */
    +
    +METHODDEF(boolean)
    +read_restart_marker (j_decompress_ptr cinfo)
    +{
    +  /* Obtain a marker unless we already did. */
    +  /* Note that next_marker will complain if it skips any data. */
    +  if (cinfo->unread_marker == 0) {
    +    if (! next_marker(cinfo))
    +      return FALSE;
    +  }
    +
    +  if (cinfo->unread_marker ==
    +      ((int) M_RST0 + cinfo->marker->next_restart_num)) {
    +    /* Normal case --- swallow the marker and let entropy decoder continue */
    +    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
    +    cinfo->unread_marker = 0;
    +  } else {
    +    /* Uh-oh, the restart markers have been messed up. */
    +    /* Let the data source manager determine how to resync. */
    +    if (! (*cinfo->src->resync_to_restart) (cinfo,
    +                                            cinfo->marker->next_restart_num))
    +      return FALSE;
    +  }
    +
    +  /* Update next-restart state */
    +  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * This is the default resync_to_restart method for data source managers
    + * to use if they don't have any better approach.  Some data source managers
    + * may be able to back up, or may have additional knowledge about the data
    + * which permits a more intelligent recovery strategy; such managers would
    + * presumably supply their own resync method.
    + *
    + * read_restart_marker calls resync_to_restart if it finds a marker other than
    + * the restart marker it was expecting.  (This code is *not* used unless
    + * a nonzero restart interval has been declared.)  cinfo->unread_marker is
    + * the marker code actually found (might be anything, except 0 or FF).
    + * The desired restart marker number (0..7) is passed as a parameter.
    + * This routine is supposed to apply whatever error recovery strategy seems
    + * appropriate in order to position the input stream to the next data segment.
    + * Note that cinfo->unread_marker is treated as a marker appearing before
    + * the current data-source input point; usually it should be reset to zero
    + * before returning.
    + * Returns FALSE if suspension is required.
    + *
    + * This implementation is substantially constrained by wanting to treat the
    + * input as a data stream; this means we can't back up.  Therefore, we have
    + * only the following actions to work with:
    + *   1. Simply discard the marker and let the entropy decoder resume at next
    + *      byte of file.
    + *   2. Read forward until we find another marker, discarding intervening
    + *      data.  (In theory we could look ahead within the current bufferload,
    + *      without having to discard data if we don't find the desired marker.
    + *      This idea is not implemented here, in part because it makes behavior
    + *      dependent on buffer size and chance buffer-boundary positions.)
    + *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
    + *      This will cause the entropy decoder to process an empty data segment,
    + *      inserting dummy zeroes, and then we will reprocess the marker.
    + *
    + * #2 is appropriate if we think the desired marker lies ahead, while #3 is
    + * appropriate if the found marker is a future restart marker (indicating
    + * that we have missed the desired restart marker, probably because it got
    + * corrupted).
    + * We apply #2 or #3 if the found marker is a restart marker no more than
    + * two counts behind or ahead of the expected one.  We also apply #2 if the
    + * found marker is not a legal JPEG marker code (it's certainly bogus data).
    + * If the found marker is a restart marker more than 2 counts away, we do #1
    + * (too much risk that the marker is erroneous; with luck we will be able to
    + * resync at some future point).
    + * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
    + * overrunning the end of a scan.  An implementation limited to single-scan
    + * files might find it better to apply #2 for markers other than EOI, since
    + * any other marker would have to be bogus data in that case.
    + */
    +
    +GLOBAL(boolean)
    +jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
    +{
    +  int marker = cinfo->unread_marker;
    +  int action = 1;
    +
    +  /* Always put up a warning. */
    +  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
    +
    +  /* Outer loop handles repeated decision after scanning forward. */
    +  for (;;) {
    +    if (marker < (int) M_SOF0)
    +      action = 2;               /* invalid marker */
    +    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
    +      action = 3;               /* valid non-restart marker */
    +    else {
    +      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
    +          marker == ((int) M_RST0 + ((desired+2) & 7)))
    +        action = 3;             /* one of the next two expected restarts */
    +      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
    +               marker == ((int) M_RST0 + ((desired-2) & 7)))
    +        action = 2;             /* a prior restart, so advance */
    +      else
    +        action = 1;             /* desired restart or too far away */
    +    }
    +    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
    +    switch (action) {
    +    case 1:
    +      /* Discard marker and let entropy decoder resume processing. */
    +      cinfo->unread_marker = 0;
    +      return TRUE;
    +    case 2:
    +      /* Scan to the next marker, and repeat the decision loop. */
    +      if (! next_marker(cinfo))
    +        return FALSE;
    +      marker = cinfo->unread_marker;
    +      break;
    +    case 3:
    +      /* Return without advancing past this marker. */
    +      /* Entropy decoder will be forced to process an empty segment. */
    +      return TRUE;
    +    }
    +  } /* end loop */
    +}
    +
    +
    +/*
    + * Reset marker processing state to begin a fresh datastream.
    + */
    +
    +METHODDEF(void)
    +reset_marker_reader (j_decompress_ptr cinfo)
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +
    +  cinfo->comp_info = NULL;              /* until allocated by get_sof */
    +  cinfo->input_scan_number = 0;         /* no SOS seen yet */
    +  cinfo->unread_marker = 0;             /* no pending marker */
    +  marker->pub.saw_SOI = FALSE;          /* set internal state too */
    +  marker->pub.saw_SOF = FALSE;
    +  marker->pub.discarded_bytes = 0;
    +  marker->cur_marker = NULL;
    +}
    +
    +
    +/*
    + * Initialize the marker reader module.
    + * This is called only once, when the decompression object is created.
    + */
    +
    +GLOBAL(void)
    +jinit_marker_reader (j_decompress_ptr cinfo)
    +{
    +  my_marker_ptr marker;
    +  int i;
    +
    +  /* Create subobject in permanent pool */
    +  marker = (my_marker_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
    +                                SIZEOF(my_marker_reader));
    +  cinfo->marker = (struct jpeg_marker_reader *) marker;
    +  /* Initialize public method pointers */
    +  marker->pub.reset_marker_reader = reset_marker_reader;
    +  marker->pub.read_markers = read_markers;
    +  marker->pub.read_restart_marker = read_restart_marker;
    +  /* Initialize COM/APPn processing.
    +   * By default, we examine and then discard APP0 and APP14.
    +   * We also may need to save APP1 to detect the case of EXIF images (see 4881314).
    +   * COM and all other APPn are simply discarded.
    +   */
    +  marker->process_COM = skip_variable;
    +  marker->length_limit_COM = 0;
    +  for (i = 0; i < 16; i++) {
    +    marker->process_APPn[i] = skip_variable;
    +    marker->length_limit_APPn[i] = 0;
    +  }
    +  marker->process_APPn[0] = get_interesting_appn;
    +  marker->process_APPn[1] = save_marker;
    +  marker->process_APPn[14] = get_interesting_appn;
    +  /* Reset marker processing state */
    +  reset_marker_reader(cinfo);
    +}
    +
    +
    +/*
    + * Control saving of COM and APPn markers into marker_list.
    + */
    +
    +#ifdef SAVE_MARKERS_SUPPORTED
    +
    +GLOBAL(void)
    +jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
    +                   unsigned int length_limit)
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +  size_t maxlength;
    +  jpeg_marker_parser_method processor;
    +
    +  /* Length limit mustn't be larger than what we can allocate
    +   * (should only be a concern in a 16-bit environment).
    +   */
    +  maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
    +  if (length_limit > maxlength)
    +    length_limit = (unsigned int) maxlength;
    +
    +  /* Choose processor routine to use.
    +   * APP0/APP14 have special requirements.
    +   */
    +  if (length_limit) {
    +    processor = save_marker;
    +    /* If saving APP0/APP14, save at least enough for our internal use. */
    +    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
    +      length_limit = APP0_DATA_LEN;
    +    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
    +      length_limit = APP14_DATA_LEN;
    +  } else {
    +    processor = skip_variable;
    +    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
    +    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
    +      processor = get_interesting_appn;
    +  }
    +
    +  if (marker_code == (int) M_COM) {
    +    marker->process_COM = processor;
    +    marker->length_limit_COM = length_limit;
    +  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
    +    marker->process_APPn[marker_code - (int) M_APP0] = processor;
    +    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
    +  } else
    +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
    +}
    +
    +#endif /* SAVE_MARKERS_SUPPORTED */
    +
    +
    +/*
    + * Install a special processing method for COM or APPn markers.
    + */
    +
    +GLOBAL(void)
    +jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
    +                           jpeg_marker_parser_method routine)
    +{
    +  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
    +
    +  if (marker_code == (int) M_COM)
    +    marker->process_COM = routine;
    +  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
    +    marker->process_APPn[marker_code - (int) M_APP0] = routine;
    +  else
    +    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmaster.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmaster.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmaster.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmaster.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,561 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdmaster.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains master control logic for the JPEG decompressor.
    + * These routines are concerned with selecting the modules to be executed
    + * and with determining the number of passes and the work to be done in each
    + * pass.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private state */
    +
    +typedef struct {
    +  struct jpeg_decomp_master pub; /* public fields */
    +
    +  int pass_number;              /* # of passes completed */
    +
    +  boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
    +
    +  /* Saved references to initialized quantizer modules,
    +   * in case we need to switch modes.
    +   */
    +  struct jpeg_color_quantizer * quantizer_1pass;
    +  struct jpeg_color_quantizer * quantizer_2pass;
    +} my_decomp_master;
    +
    +typedef my_decomp_master * my_master_ptr;
    +
    +
    +/*
    + * Determine whether merged upsample/color conversion should be used.
    + * CRUCIAL: this must match the actual capabilities of jdmerge.c!
    + */
    +
    +LOCAL(boolean)
    +use_merged_upsample (j_decompress_ptr cinfo)
    +{
    +#ifdef UPSAMPLE_MERGING_SUPPORTED
    +  /* Merging is the equivalent of plain box-filter upsampling */
    +  if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
    +    return FALSE;
    +  /* jdmerge.c only supports YCC=>RGB color conversion */
    +  if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
    +      cinfo->out_color_space != JCS_RGB ||
    +      cinfo->out_color_components != RGB_PIXELSIZE)
    +    return FALSE;
    +  /* and it only handles 2h1v or 2h2v sampling ratios */
    +  if (cinfo->comp_info[0].h_samp_factor != 2 ||
    +      cinfo->comp_info[1].h_samp_factor != 1 ||
    +      cinfo->comp_info[2].h_samp_factor != 1 ||
    +      cinfo->comp_info[0].v_samp_factor >  2 ||
    +      cinfo->comp_info[1].v_samp_factor != 1 ||
    +      cinfo->comp_info[2].v_samp_factor != 1)
    +    return FALSE;
    +  /* furthermore, it doesn't work if we've scaled the IDCTs differently */
    +  if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
    +      cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
    +      cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
    +    return FALSE;
    +  /* ??? also need to test for upsample-time rescaling, when & if supported */
    +  return TRUE;                  /* by golly, it'll work... */
    +#else
    +  return FALSE;
    +#endif
    +}
    +
    +
    +/*
    + * Compute output image dimensions and related values.
    + * NOTE: this is exported for possible use by application.
    + * Hence it mustn't do anything that can't be done twice.
    + * Also note that it may be called before the master module is initialized!
    + */
    +
    +GLOBAL(void)
    +jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
    +/* Do computations that are needed before master selection phase */
    +{
    +#ifdef IDCT_SCALING_SUPPORTED
    +  int ci;
    +  jpeg_component_info *compptr;
    +#endif
    +
    +  /* Prevent application from calling me at wrong times */
    +  if (cinfo->global_state != DSTATE_READY)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +#ifdef IDCT_SCALING_SUPPORTED
    +
    +  /* Compute actual output image dimensions and DCT scaling choices. */
    +  if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
    +    /* Provide 1/8 scaling */
    +    cinfo->output_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width, 8L);
    +    cinfo->output_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height, 8L);
    +    cinfo->min_DCT_scaled_size = 1;
    +  } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
    +    /* Provide 1/4 scaling */
    +    cinfo->output_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width, 4L);
    +    cinfo->output_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height, 4L);
    +    cinfo->min_DCT_scaled_size = 2;
    +  } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
    +    /* Provide 1/2 scaling */
    +    cinfo->output_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width, 2L);
    +    cinfo->output_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height, 2L);
    +    cinfo->min_DCT_scaled_size = 4;
    +  } else {
    +    /* Provide 1/1 scaling */
    +    cinfo->output_width = cinfo->image_width;
    +    cinfo->output_height = cinfo->image_height;
    +    cinfo->min_DCT_scaled_size = DCTSIZE;
    +  }
    +  /* In selecting the actual DCT scaling for each component, we try to
    +   * scale up the chroma components via IDCT scaling rather than upsampling.
    +   * This saves time if the upsampler gets to use 1:1 scaling.
    +   * Note this code assumes that the supported DCT scalings are powers of 2.
    +   */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    int ssize = cinfo->min_DCT_scaled_size;
    +    while (ssize < DCTSIZE &&
    +           (compptr->h_samp_factor * ssize * 2 <=
    +            cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
    +           (compptr->v_samp_factor * ssize * 2 <=
    +            cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
    +      ssize = ssize * 2;
    +    }
    +    compptr->DCT_scaled_size = ssize;
    +  }
    +
    +  /* Recompute downsampled dimensions of components;
    +   * application needs to know these if using raw downsampled data.
    +   */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Size in samples, after IDCT scaling */
    +    compptr->downsampled_width = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_width *
    +                    (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
    +                    (long) (cinfo->max_h_samp_factor * DCTSIZE));
    +    compptr->downsampled_height = (JDIMENSION)
    +      jdiv_round_up((long) cinfo->image_height *
    +                    (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
    +                    (long) (cinfo->max_v_samp_factor * DCTSIZE));
    +  }
    +
    +#else /* !IDCT_SCALING_SUPPORTED */
    +
    +  /* Hardwire it to "no scaling" */
    +  cinfo->output_width = cinfo->image_width;
    +  cinfo->output_height = cinfo->image_height;
    +  /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
    +   * and has computed unscaled downsampled_width and downsampled_height.
    +   */
    +
    +#endif /* IDCT_SCALING_SUPPORTED */
    +
    +  /* Report number of components in selected colorspace. */
    +  /* Probably this should be in the color conversion module... */
    +  switch (cinfo->out_color_space) {
    +  case JCS_GRAYSCALE:
    +    cinfo->out_color_components = 1;
    +    break;
    +  case JCS_RGB:
    +#if RGB_PIXELSIZE != 3
    +    cinfo->out_color_components = RGB_PIXELSIZE;
    +    break;
    +#endif /* else share code with YCbCr */
    +  case JCS_YCbCr:
    +    cinfo->out_color_components = 3;
    +    break;
    +  case JCS_CMYK:
    +  case JCS_YCCK:
    +    cinfo->out_color_components = 4;
    +    break;
    +  default:                      /* else must be same colorspace as in file */
    +    cinfo->out_color_components = cinfo->num_components;
    +    break;
    +  }
    +  cinfo->output_components = (cinfo->quantize_colors ? 1 :
    +                              cinfo->out_color_components);
    +
    +  /* See if upsampler will want to emit more than one row at a time */
    +  if (use_merged_upsample(cinfo))
    +    cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
    +  else
    +    cinfo->rec_outbuf_height = 1;
    +}
    +
    +
    +/*
    + * Several decompression processes need to range-limit values to the range
    + * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
    + * due to noise introduced by quantization, roundoff error, etc.  These
    + * processes are inner loops and need to be as fast as possible.  On most
    + * machines, particularly CPUs with pipelines or instruction prefetch,
    + * a (subscript-check-less) C table lookup
    + *              x = sample_range_limit[x];
    + * is faster than explicit tests
    + *              if (x < 0)  x = 0;
    + *              else if (x > MAXJSAMPLE)  x = MAXJSAMPLE;
    + * These processes all use a common table prepared by the routine below.
    + *
    + * For most steps we can mathematically guarantee that the initial value
    + * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
    + * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient.  But for the initial
    + * limiting step (just after the IDCT), a wildly out-of-range value is
    + * possible if the input data is corrupt.  To avoid any chance of indexing
    + * off the end of memory and getting a bad-pointer trap, we perform the
    + * post-IDCT limiting thus:
    + *              x = range_limit[x & MASK];
    + * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
    + * samples.  Under normal circumstances this is more than enough range and
    + * a correct output will be generated; with bogus input data the mask will
    + * cause wraparound, and we will safely generate a bogus-but-in-range output.
    + * For the post-IDCT step, we want to convert the data from signed to unsigned
    + * representation by adding CENTERJSAMPLE at the same time that we limit it.
    + * So the post-IDCT limiting table ends up looking like this:
    + *   CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
    + *   MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
    + *   0          (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
    + *   0,1,...,CENTERJSAMPLE-1
    + * Negative inputs select values from the upper half of the table after
    + * masking.
    + *
    + * We can save some space by overlapping the start of the post-IDCT table
    + * with the simpler range limiting table.  The post-IDCT table begins at
    + * sample_range_limit + CENTERJSAMPLE.
    + *
    + * Note that the table is allocated in near data space on PCs; it's small
    + * enough and used often enough to justify this.
    + */
    +
    +LOCAL(void)
    +prepare_range_limit_table (j_decompress_ptr cinfo)
    +/* Allocate and fill in the sample_range_limit table */
    +{
    +  JSAMPLE * table;
    +  int i;
    +
    +  table = (JSAMPLE *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
    +  table += (MAXJSAMPLE+1);      /* allow negative subscripts of simple table */
    +  cinfo->sample_range_limit = table;
    +  /* First segment of "simple" table: limit[x] = 0 for x < 0 */
    +  MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
    +  /* Main part of "simple" table: limit[x] = x */
    +  for (i = 0; i <= MAXJSAMPLE; i++)
    +    table[i] = (JSAMPLE) i;
    +  table += CENTERJSAMPLE;       /* Point to where post-IDCT table starts */
    +  /* End of simple table, rest of first half of post-IDCT table */
    +  for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
    +    table[i] = MAXJSAMPLE;
    +  /* Second half of post-IDCT table */
    +  MEMZERO(table + (2 * (MAXJSAMPLE+1)),
    +          (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
    +  MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
    +          cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
    +}
    +
    +
    +/*
    + * Master selection of decompression modules.
    + * This is done once at jpeg_start_decompress time.  We determine
    + * which modules will be used and give them appropriate initialization calls.
    + * We also initialize the decompressor input side to begin consuming data.
    + *
    + * Since jpeg_read_header has finished, we know what is in the SOF
    + * and (first) SOS markers.  We also have all the application parameter
    + * settings.
    + */
    +
    +LOCAL(void)
    +master_selection (j_decompress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +  boolean use_c_buffer;
    +  long samplesperrow;
    +  JDIMENSION jd_samplesperrow;
    +
    +  /* Initialize dimensions and other stuff */
    +  jpeg_calc_output_dimensions(cinfo);
    +  prepare_range_limit_table(cinfo);
    +
    +  /* Width of an output scanline must be representable as JDIMENSION. */
    +  samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
    +  jd_samplesperrow = (JDIMENSION) samplesperrow;
    +  if ((long) jd_samplesperrow != samplesperrow)
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +
    +  /* Initialize my private state */
    +  master->pass_number = 0;
    +  master->using_merged_upsample = use_merged_upsample(cinfo);
    +
    +  /* Color quantizer selection */
    +  master->quantizer_1pass = NULL;
    +  master->quantizer_2pass = NULL;
    +  /* No mode changes if not using buffered-image mode. */
    +  if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
    +    cinfo->enable_1pass_quant = FALSE;
    +    cinfo->enable_external_quant = FALSE;
    +    cinfo->enable_2pass_quant = FALSE;
    +  }
    +  if (cinfo->quantize_colors) {
    +    if (cinfo->raw_data_out)
    +      ERREXIT(cinfo, JERR_NOTIMPL);
    +    /* 2-pass quantizer only works in 3-component color space. */
    +    if (cinfo->out_color_components != 3) {
    +      cinfo->enable_1pass_quant = TRUE;
    +      cinfo->enable_external_quant = FALSE;
    +      cinfo->enable_2pass_quant = FALSE;
    +      cinfo->colormap = NULL;
    +    } else if (cinfo->colormap != NULL) {
    +      cinfo->enable_external_quant = TRUE;
    +    } else if (cinfo->two_pass_quantize) {
    +      cinfo->enable_2pass_quant = TRUE;
    +    } else {
    +      cinfo->enable_1pass_quant = TRUE;
    +    }
    +
    +    if (cinfo->enable_1pass_quant) {
    +#ifdef QUANT_1PASS_SUPPORTED
    +      jinit_1pass_quantizer(cinfo);
    +      master->quantizer_1pass = cinfo->cquantize;
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    }
    +
    +    /* We use the 2-pass code to map to external colormaps. */
    +    if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
    +#ifdef QUANT_2PASS_SUPPORTED
    +      jinit_2pass_quantizer(cinfo);
    +      master->quantizer_2pass = cinfo->cquantize;
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    }
    +    /* If both quantizers are initialized, the 2-pass one is left active;
    +     * this is necessary for starting with quantization to an external map.
    +     */
    +  }
    +
    +  /* Post-processing: in particular, color conversion first */
    +  if (! cinfo->raw_data_out) {
    +    if (master->using_merged_upsample) {
    +#ifdef UPSAMPLE_MERGING_SUPPORTED
    +      jinit_merged_upsampler(cinfo); /* does color conversion too */
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    } else {
    +      jinit_color_deconverter(cinfo);
    +      jinit_upsampler(cinfo);
    +    }
    +    jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
    +  }
    +  /* Inverse DCT */
    +  jinit_inverse_dct(cinfo);
    +  /* Entropy decoding: either Huffman or arithmetic coding. */
    +  if (cinfo->arith_code) {
    +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
    +  } else {
    +    if (cinfo->progressive_mode) {
    +#ifdef D_PROGRESSIVE_SUPPORTED
    +      jinit_phuff_decoder(cinfo);
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    } else
    +      jinit_huff_decoder(cinfo);
    +  }
    +
    +  /* Initialize principal buffer controllers. */
    +  use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
    +  jinit_d_coef_controller(cinfo, use_c_buffer);
    +
    +  if (! cinfo->raw_data_out)
    +    jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
    +
    +  /* We can now tell the memory manager to allocate virtual arrays. */
    +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
    +
    +  /* Initialize input side of decompressor to consume first scan. */
    +  (*cinfo->inputctl->start_input_pass) (cinfo);
    +
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +  /* If jpeg_start_decompress will read the whole file, initialize
    +   * progress monitoring appropriately.  The input step is counted
    +   * as one pass.
    +   */
    +  if (cinfo->progress != NULL && ! cinfo->buffered_image &&
    +      cinfo->inputctl->has_multiple_scans) {
    +    int nscans;
    +    /* Estimate number of scans to set pass_limit. */
    +    if (cinfo->progressive_mode) {
    +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
    +      nscans = 2 + 3 * cinfo->num_components;
    +    } else {
    +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
    +      nscans = cinfo->num_components;
    +    }
    +    cinfo->progress->pass_counter = 0L;
    +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
    +    cinfo->progress->completed_passes = 0;
    +    cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
    +    /* Count the input pass as done */
    +    master->pass_number++;
    +  }
    +#endif /* D_MULTISCAN_FILES_SUPPORTED */
    +}
    +
    +
    +/*
    + * Per-pass setup.
    + * This is called at the beginning of each output pass.  We determine which
    + * modules will be active during this pass and give them appropriate
    + * start_pass calls.  We also set is_dummy_pass to indicate whether this
    + * is a "real" output pass or a dummy pass for color quantization.
    + * (In the latter case, jdapistd.c will crank the pass to completion.)
    + */
    +
    +METHODDEF(void)
    +prepare_for_output_pass (j_decompress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +
    +  if (master->pub.is_dummy_pass) {
    +#ifdef QUANT_2PASS_SUPPORTED
    +    /* Final pass of 2-pass quantization */
    +    master->pub.is_dummy_pass = FALSE;
    +    (*cinfo->cquantize->start_pass) (cinfo, FALSE);
    +    (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
    +    (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
    +#else
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif /* QUANT_2PASS_SUPPORTED */
    +  } else {
    +    if (cinfo->quantize_colors && cinfo->colormap == NULL) {
    +      /* Select new quantization method */
    +      if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
    +        cinfo->cquantize = master->quantizer_2pass;
    +        master->pub.is_dummy_pass = TRUE;
    +      } else if (cinfo->enable_1pass_quant) {
    +        cinfo->cquantize = master->quantizer_1pass;
    +      } else {
    +        ERREXIT(cinfo, JERR_MODE_CHANGE);
    +      }
    +    }
    +    (*cinfo->idct->start_pass) (cinfo);
    +    (*cinfo->coef->start_output_pass) (cinfo);
    +    if (! cinfo->raw_data_out) {
    +      if (! master->using_merged_upsample)
    +        (*cinfo->cconvert->start_pass) (cinfo);
    +      (*cinfo->upsample->start_pass) (cinfo);
    +      if (cinfo->quantize_colors)
    +        (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
    +      (*cinfo->post->start_pass) (cinfo,
    +            (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
    +      (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
    +    }
    +  }
    +
    +  /* Set up progress monitor's pass info if present */
    +  if (cinfo->progress != NULL) {
    +    cinfo->progress->completed_passes = master->pass_number;
    +    cinfo->progress->total_passes = master->pass_number +
    +                                    (master->pub.is_dummy_pass ? 2 : 1);
    +    /* In buffered-image mode, we assume one more output pass if EOI not
    +     * yet reached, but no more passes if EOI has been reached.
    +     */
    +    if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
    +      cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Finish up at end of an output pass.
    + */
    +
    +METHODDEF(void)
    +finish_output_pass (j_decompress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +
    +  if (cinfo->quantize_colors)
    +    (*cinfo->cquantize->finish_pass) (cinfo);
    +  master->pass_number++;
    +}
    +
    +
    +#ifdef D_MULTISCAN_FILES_SUPPORTED
    +
    +/*
    + * Switch to a new external colormap between output passes.
    + */
    +
    +GLOBAL(void)
    +jpeg_new_colormap (j_decompress_ptr cinfo)
    +{
    +  my_master_ptr master = (my_master_ptr) cinfo->master;
    +
    +  /* Prevent application from calling me at wrong times */
    +  if (cinfo->global_state != DSTATE_BUFIMAGE)
    +    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +
    +  if (cinfo->quantize_colors && cinfo->enable_external_quant &&
    +      cinfo->colormap != NULL) {
    +    /* Select 2-pass quantizer for external colormap use */
    +    cinfo->cquantize = master->quantizer_2pass;
    +    /* Notify quantizer of colormap change */
    +    (*cinfo->cquantize->new_color_map) (cinfo);
    +    master->pub.is_dummy_pass = FALSE; /* just in case */
    +  } else
    +    ERREXIT(cinfo, JERR_MODE_CHANGE);
    +}
    +
    +#endif /* D_MULTISCAN_FILES_SUPPORTED */
    +
    +
    +/*
    + * Initialize master decompression control and select active modules.
    + * This is performed at the start of jpeg_start_decompress.
    + */
    +
    +GLOBAL(void)
    +jinit_master_decompress (j_decompress_ptr cinfo)
    +{
    +  my_master_ptr master;
    +
    +  master = (my_master_ptr)
    +      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                  SIZEOF(my_decomp_master));
    +  cinfo->master = (struct jpeg_decomp_master *) master;
    +  master->pub.prepare_for_output_pass = prepare_for_output_pass;
    +  master->pub.finish_output_pass = finish_output_pass;
    +
    +  master->pub.is_dummy_pass = FALSE;
    +
    +  master_selection(cinfo);
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmerge.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmerge.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdmerge.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdmerge.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,404 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdmerge.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains code for merged upsampling/color conversion.
    + *
    + * This file combines functions from jdsample.c and jdcolor.c;
    + * read those files first to understand what's going on.
    + *
    + * When the chroma components are to be upsampled by simple replication
    + * (ie, box filtering), we can save some work in color conversion by
    + * calculating all the output pixels corresponding to a pair of chroma
    + * samples at one time.  In the conversion equations
    + *      R = Y           + K1 * Cr
    + *      G = Y + K2 * Cb + K3 * Cr
    + *      B = Y + K4 * Cb
    + * only the Y term varies among the group of pixels corresponding to a pair
    + * of chroma samples, so the rest of the terms can be calculated just once.
    + * At typical sampling ratios, this eliminates half or three-quarters of the
    + * multiplications needed for color conversion.
    + *
    + * This file currently provides implementations for the following cases:
    + *      YCbCr => RGB color conversion only.
    + *      Sampling ratios of 2h1v or 2h2v.
    + *      No scaling needed at upsample time.
    + *      Corner-aligned (non-CCIR601) sampling alignment.
    + * Other special cases could be added, but in most applications these are
    + * the only common cases.  (For uncommon cases we fall back on the more
    + * general code in jdsample.c and jdcolor.c.)
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +#ifdef UPSAMPLE_MERGING_SUPPORTED
    +
    +
    +/* Private subobject */
    +
    +typedef struct {
    +  struct jpeg_upsampler pub;    /* public fields */
    +
    +  /* Pointer to routine to do actual upsampling/conversion of one row group */
    +  JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
    +                           JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    +                           JSAMPARRAY output_buf));
    +
    +  /* Private state for YCC->RGB conversion */
    +  int * Cr_r_tab;               /* => table for Cr to R conversion */
    +  int * Cb_b_tab;               /* => table for Cb to B conversion */
    +  INT32 * Cr_g_tab;             /* => table for Cr to G conversion */
    +  INT32 * Cb_g_tab;             /* => table for Cb to G conversion */
    +
    +  /* For 2:1 vertical sampling, we produce two output rows at a time.
    +   * We need a "spare" row buffer to hold the second output row if the
    +   * application provides just a one-row buffer; we also use the spare
    +   * to discard the dummy last row if the image height is odd.
    +   */
    +  JSAMPROW spare_row;
    +  boolean spare_full;           /* T if spare buffer is occupied */
    +
    +  JDIMENSION out_row_width;     /* samples per output row */
    +  JDIMENSION rows_to_go;        /* counts rows remaining in image */
    +} my_upsampler;
    +
    +typedef my_upsampler * my_upsample_ptr;
    +
    +#define SCALEBITS       16      /* speediest right-shift on some machines */
    +#define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
    +#define FIX(x)          ((INT32) ((x) * (1L<RGB colorspace conversion.
    + * This is taken directly from jdcolor.c; see that file for more info.
    + */
    +
    +LOCAL(void)
    +build_ycc_rgb_table (j_decompress_ptr cinfo)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  int i;
    +  INT32 x;
    +  SHIFT_TEMPS
    +
    +  upsample->Cr_r_tab = (int *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(int));
    +  upsample->Cb_b_tab = (int *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(int));
    +  upsample->Cr_g_tab = (INT32 *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(INT32));
    +  upsample->Cb_g_tab = (INT32 *)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                (MAXJSAMPLE+1) * SIZEOF(INT32));
    +
    +  for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    +    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    +    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    +    /* Cr=>R value is nearest int to 1.40200 * x */
    +    upsample->Cr_r_tab[i] = (int)
    +                    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    +    /* Cb=>B value is nearest int to 1.77200 * x */
    +    upsample->Cb_b_tab[i] = (int)
    +                    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
    +    /* Cr=>G value is scaled-up -0.71414 * x */
    +    upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
    +    /* Cb=>G value is scaled-up -0.34414 * x */
    +    /* We also add in ONE_HALF so that need not do it in inner loop */
    +    upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
    +  }
    +}
    +
    +
    +/*
    + * Initialize for an upsampling pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_merged_upsample (j_decompress_ptr cinfo)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +
    +  /* Mark the spare buffer empty */
    +  upsample->spare_full = FALSE;
    +  /* Initialize total-height counter for detecting bottom of image */
    +  upsample->rows_to_go = cinfo->output_height;
    +}
    +
    +
    +/*
    + * Control routine to do upsampling (and color conversion).
    + *
    + * The control routine just handles the row buffering considerations.
    + */
    +
    +METHODDEF(void)
    +merged_2v_upsample (j_decompress_ptr cinfo,
    +                    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +                    JDIMENSION in_row_groups_avail,
    +                    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                    JDIMENSION out_rows_avail)
    +/* 2:1 vertical sampling case: may need a spare row. */
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  JSAMPROW work_ptrs[2];
    +  JDIMENSION num_rows;          /* number of rows returned to caller */
    +
    +  if (upsample->spare_full) {
    +    /* If we have a spare row saved from a previous cycle, just return it. */
    +    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
    +                      1, upsample->out_row_width);
    +    num_rows = 1;
    +    upsample->spare_full = FALSE;
    +  } else {
    +    /* Figure number of rows to return to caller. */
    +    num_rows = 2;
    +    /* Not more than the distance to the end of the image. */
    +    if (num_rows > upsample->rows_to_go)
    +      num_rows = upsample->rows_to_go;
    +    /* And not more than what the client can accept: */
    +    out_rows_avail -= *out_row_ctr;
    +    if (num_rows > out_rows_avail)
    +      num_rows = out_rows_avail;
    +    /* Create output pointer array for upsampler. */
    +    work_ptrs[0] = output_buf[*out_row_ctr];
    +    if (num_rows > 1) {
    +      work_ptrs[1] = output_buf[*out_row_ctr + 1];
    +    } else {
    +      work_ptrs[1] = upsample->spare_row;
    +      upsample->spare_full = TRUE;
    +    }
    +    /* Now do the upsampling. */
    +    (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
    +  }
    +
    +  /* Adjust counts */
    +  *out_row_ctr += num_rows;
    +  upsample->rows_to_go -= num_rows;
    +  /* When the buffer is emptied, declare this input row group consumed */
    +  if (! upsample->spare_full)
    +    (*in_row_group_ctr)++;
    +}
    +
    +
    +METHODDEF(void)
    +merged_1v_upsample (j_decompress_ptr cinfo,
    +                    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +                    JDIMENSION in_row_groups_avail,
    +                    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                    JDIMENSION out_rows_avail)
    +/* 1:1 vertical sampling case: much easier, never need a spare row. */
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +
    +  /* Just do the upsampling. */
    +  (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
    +                         output_buf + *out_row_ctr);
    +  /* Adjust counts */
    +  (*out_row_ctr)++;
    +  (*in_row_group_ctr)++;
    +}
    +
    +
    +/*
    + * These are the routines invoked by the control routines to do
    + * the actual upsampling/conversion.  One row group is processed per call.
    + *
    + * Note: since we may be writing directly into application-supplied buffers,
    + * we have to be honest about the output width; we can't assume the buffer
    + * has been rounded up to an even width.
    + */
    +
    +
    +/*
    + * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
    + */
    +
    +METHODDEF(void)
    +h2v1_merged_upsample (j_decompress_ptr cinfo,
    +                      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    +                      JSAMPARRAY output_buf)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  register int y, cred, cgreen, cblue;
    +  int cb, cr;
    +  register JSAMPROW outptr;
    +  JSAMPROW inptr0, inptr1, inptr2;
    +  JDIMENSION col;
    +  /* copy these pointers into registers if possible */
    +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
    +  int * Crrtab = upsample->Cr_r_tab;
    +  int * Cbbtab = upsample->Cb_b_tab;
    +  INT32 * Crgtab = upsample->Cr_g_tab;
    +  INT32 * Cbgtab = upsample->Cb_g_tab;
    +  SHIFT_TEMPS
    +
    +  inptr0 = input_buf[0][in_row_group_ctr];
    +  inptr1 = input_buf[1][in_row_group_ctr];
    +  inptr2 = input_buf[2][in_row_group_ctr];
    +  outptr = output_buf[0];
    +  /* Loop for each pair of output pixels */
    +  for (col = cinfo->output_width >> 1; col > 0; col--) {
    +    /* Do the chroma part of the calculation */
    +    cb = GETJSAMPLE(*inptr1++);
    +    cr = GETJSAMPLE(*inptr2++);
    +    cred = Crrtab[cr];
    +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    +    cblue = Cbbtab[cb];
    +    /* Fetch 2 Y values and emit 2 pixels */
    +    y  = GETJSAMPLE(*inptr0++);
    +    outptr[RGB_RED] =   range_limit[y + cred];
    +    outptr[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr += RGB_PIXELSIZE;
    +    y  = GETJSAMPLE(*inptr0++);
    +    outptr[RGB_RED] =   range_limit[y + cred];
    +    outptr[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr += RGB_PIXELSIZE;
    +  }
    +  /* If image width is odd, do the last output column separately */
    +  if (cinfo->output_width & 1) {
    +    cb = GETJSAMPLE(*inptr1);
    +    cr = GETJSAMPLE(*inptr2);
    +    cred = Crrtab[cr];
    +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    +    cblue = Cbbtab[cb];
    +    y  = GETJSAMPLE(*inptr0);
    +    outptr[RGB_RED] =   range_limit[y + cred];
    +    outptr[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr[RGB_BLUE] =  range_limit[y + cblue];
    +  }
    +}
    +
    +
    +/*
    + * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
    + */
    +
    +METHODDEF(void)
    +h2v2_merged_upsample (j_decompress_ptr cinfo,
    +                      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    +                      JSAMPARRAY output_buf)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  register int y, cred, cgreen, cblue;
    +  int cb, cr;
    +  register JSAMPROW outptr0, outptr1;
    +  JSAMPROW inptr00, inptr01, inptr1, inptr2;
    +  JDIMENSION col;
    +  /* copy these pointers into registers if possible */
    +  register JSAMPLE * range_limit = cinfo->sample_range_limit;
    +  int * Crrtab = upsample->Cr_r_tab;
    +  int * Cbbtab = upsample->Cb_b_tab;
    +  INT32 * Crgtab = upsample->Cr_g_tab;
    +  INT32 * Cbgtab = upsample->Cb_g_tab;
    +  SHIFT_TEMPS
    +
    +  inptr00 = input_buf[0][in_row_group_ctr*2];
    +  inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
    +  inptr1 = input_buf[1][in_row_group_ctr];
    +  inptr2 = input_buf[2][in_row_group_ctr];
    +  outptr0 = output_buf[0];
    +  outptr1 = output_buf[1];
    +  /* Loop for each group of output pixels */
    +  for (col = cinfo->output_width >> 1; col > 0; col--) {
    +    /* Do the chroma part of the calculation */
    +    cb = GETJSAMPLE(*inptr1++);
    +    cr = GETJSAMPLE(*inptr2++);
    +    cred = Crrtab[cr];
    +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    +    cblue = Cbbtab[cb];
    +    /* Fetch 4 Y values and emit 4 pixels */
    +    y  = GETJSAMPLE(*inptr00++);
    +    outptr0[RGB_RED] =   range_limit[y + cred];
    +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr0 += RGB_PIXELSIZE;
    +    y  = GETJSAMPLE(*inptr00++);
    +    outptr0[RGB_RED] =   range_limit[y + cred];
    +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr0 += RGB_PIXELSIZE;
    +    y  = GETJSAMPLE(*inptr01++);
    +    outptr1[RGB_RED] =   range_limit[y + cred];
    +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr1 += RGB_PIXELSIZE;
    +    y  = GETJSAMPLE(*inptr01++);
    +    outptr1[RGB_RED] =   range_limit[y + cred];
    +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
    +    outptr1 += RGB_PIXELSIZE;
    +  }
    +  /* If image width is odd, do the last output column separately */
    +  if (cinfo->output_width & 1) {
    +    cb = GETJSAMPLE(*inptr1);
    +    cr = GETJSAMPLE(*inptr2);
    +    cred = Crrtab[cr];
    +    cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    +    cblue = Cbbtab[cb];
    +    y  = GETJSAMPLE(*inptr00);
    +    outptr0[RGB_RED] =   range_limit[y + cred];
    +    outptr0[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr0[RGB_BLUE] =  range_limit[y + cblue];
    +    y  = GETJSAMPLE(*inptr01);
    +    outptr1[RGB_RED] =   range_limit[y + cred];
    +    outptr1[RGB_GREEN] = range_limit[y + cgreen];
    +    outptr1[RGB_BLUE] =  range_limit[y + cblue];
    +  }
    +}
    +
    +
    +/*
    + * Module initialization routine for merged upsampling/color conversion.
    + *
    + * NB: this is called under the conditions determined by use_merged_upsample()
    + * in jdmaster.c.  That routine MUST correspond to the actual capabilities
    + * of this module; no safety checks are made here.
    + */
    +
    +GLOBAL(void)
    +jinit_merged_upsampler (j_decompress_ptr cinfo)
    +{
    +  my_upsample_ptr upsample;
    +
    +  upsample = (my_upsample_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_upsampler));
    +  cinfo->upsample = (struct jpeg_upsampler *) upsample;
    +  upsample->pub.start_pass = start_pass_merged_upsample;
    +  upsample->pub.need_context_rows = FALSE;
    +
    +  upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
    +
    +  if (cinfo->max_v_samp_factor == 2) {
    +    upsample->pub.upsample = merged_2v_upsample;
    +    upsample->upmethod = h2v2_merged_upsample;
    +    /* Allocate a spare row buffer */
    +    upsample->spare_row = (JSAMPROW)
    +      (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
    +  } else {
    +    upsample->pub.upsample = merged_1v_upsample;
    +    upsample->upmethod = h2v1_merged_upsample;
    +    /* No spare row needed */
    +    upsample->spare_row = NULL;
    +  }
    +
    +  build_ycc_rgb_table(cinfo);
    +}
    +
    +#endif /* UPSAMPLE_MERGING_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdphuff.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdphuff.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdphuff.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdphuff.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,677 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdphuff.c
    + *
    + * Copyright (C) 1995-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains Huffman entropy decoding routines for progressive JPEG.
    + *
    + * Much of the complexity here has to do with supporting input suspension.
    + * If the data source module demands suspension, we want to be able to back
    + * up to the start of the current MCU.  To do this, we copy state variables
    + * into local working storage, and update them back to the permanent
    + * storage only upon successful completion of an MCU.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdhuff.h"             /* Declarations shared with jdhuff.c */
    +
    +
    +#ifdef D_PROGRESSIVE_SUPPORTED
    +
    +/*
    + * Expanded entropy decoder object for progressive Huffman decoding.
    + *
    + * The savable_state subrecord contains fields that change within an MCU,
    + * but must not be updated permanently until we complete the MCU.
    + */
    +
    +typedef struct {
    +  unsigned int EOBRUN;                  /* remaining EOBs in EOBRUN */
    +  int last_dc_val[MAX_COMPS_IN_SCAN];   /* last DC coef for each component */
    +} savable_state;
    +
    +/* This macro is to work around compilers with missing or broken
    + * structure assignment.  You'll need to fix this code if you have
    + * such a compiler and you change MAX_COMPS_IN_SCAN.
    + */
    +
    +#ifndef NO_STRUCT_ASSIGN
    +#define ASSIGN_STATE(dest,src)  ((dest) = (src))
    +#else
    +#if MAX_COMPS_IN_SCAN == 4
    +#define ASSIGN_STATE(dest,src)  \
    +        ((dest).EOBRUN = (src).EOBRUN, \
    +         (dest).last_dc_val[0] = (src).last_dc_val[0], \
    +         (dest).last_dc_val[1] = (src).last_dc_val[1], \
    +         (dest).last_dc_val[2] = (src).last_dc_val[2], \
    +         (dest).last_dc_val[3] = (src).last_dc_val[3])
    +#endif
    +#endif
    +
    +
    +typedef struct {
    +  struct jpeg_entropy_decoder pub; /* public fields */
    +
    +  /* These fields are loaded into local variables at start of each MCU.
    +   * In case of suspension, we exit WITHOUT updating them.
    +   */
    +  bitread_perm_state bitstate;  /* Bit buffer at start of MCU */
    +  savable_state saved;          /* Other state at start of MCU */
    +
    +  /* These fields are NOT loaded into local working state. */
    +  unsigned int restarts_to_go;  /* MCUs left in this restart interval */
    +
    +  /* Pointers to derived tables (these workspaces have image lifespan) */
    +  d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
    +
    +  d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
    +} phuff_entropy_decoder;
    +
    +typedef phuff_entropy_decoder * phuff_entropy_ptr;
    +
    +/* Forward declarations */
    +METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
    +                                            JBLOCKROW *MCU_data));
    +METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
    +                                            JBLOCKROW *MCU_data));
    +METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
    +                                             JBLOCKROW *MCU_data));
    +METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
    +                                             JBLOCKROW *MCU_data));
    +
    +
    +/*
    + * Initialize for a Huffman-compressed scan.
    + */
    +
    +METHODDEF(void)
    +start_pass_phuff_decoder (j_decompress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  boolean is_DC_band, bad;
    +  int ci, coefi, tbl;
    +  int *coef_bit_ptr;
    +  jpeg_component_info * compptr;
    +
    +  is_DC_band = (cinfo->Ss == 0);
    +
    +  /* Validate scan parameters */
    +  bad = FALSE;
    +  if (is_DC_band) {
    +    if (cinfo->Se != 0)
    +      bad = TRUE;
    +  } else {
    +    /* need not check Ss/Se < 0 since they came from unsigned bytes */
    +    if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
    +      bad = TRUE;
    +    /* AC scans may have only one component */
    +    if (cinfo->comps_in_scan != 1)
    +      bad = TRUE;
    +  }
    +  if (cinfo->Ah != 0) {
    +    /* Successive approximation refinement scan: must have Al = Ah-1. */
    +    if (cinfo->Al != cinfo->Ah-1)
    +      bad = TRUE;
    +  }
    +  if (cinfo->Al > 13)           /* need not check for < 0 */
    +    bad = TRUE;
    +  /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
    +   * but the spec doesn't say so, and we try to be liberal about what we
    +   * accept.  Note: large Al values could result in out-of-range DC
    +   * coefficients during early scans, leading to bizarre displays due to
    +   * overflows in the IDCT math.  But we won't crash.
    +   */
    +  if (bad)
    +    ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
    +             cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
    +  /* Update progression status, and verify that scan order is legal.
    +   * Note that inter-scan inconsistencies are treated as warnings
    +   * not fatal errors ... not clear if this is right way to behave.
    +   */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    int cindex = cinfo->cur_comp_info[ci]->component_index;
    +    coef_bit_ptr = & cinfo->coef_bits[cindex][0];
    +    if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
    +      WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
    +    for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
    +      int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
    +      if (cinfo->Ah != expected)
    +        WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
    +      coef_bit_ptr[coefi] = cinfo->Al;
    +    }
    +  }
    +
    +  /* Select MCU decoding routine */
    +  if (cinfo->Ah == 0) {
    +    if (is_DC_band)
    +      entropy->pub.decode_mcu = decode_mcu_DC_first;
    +    else
    +      entropy->pub.decode_mcu = decode_mcu_AC_first;
    +  } else {
    +    if (is_DC_band)
    +      entropy->pub.decode_mcu = decode_mcu_DC_refine;
    +    else
    +      entropy->pub.decode_mcu = decode_mcu_AC_refine;
    +  }
    +
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    +    compptr = cinfo->cur_comp_info[ci];
    +    /* Make sure requested tables are present, and compute derived tables.
    +     * We may build same derived table more than once, but it's not expensive.
    +     */
    +    if (is_DC_band) {
    +      if (cinfo->Ah == 0) {     /* DC refinement needs no table */
    +        tbl = compptr->dc_tbl_no;
    +        jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
    +                                & entropy->derived_tbls[tbl]);
    +      }
    +    } else {
    +      tbl = compptr->ac_tbl_no;
    +      jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
    +                              & entropy->derived_tbls[tbl]);
    +      /* remember the single active table */
    +      entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
    +    }
    +    /* Initialize DC predictions to 0 */
    +    entropy->saved.last_dc_val[ci] = 0;
    +  }
    +
    +  /* Initialize bitread state variables */
    +  entropy->bitstate.bits_left = 0;
    +  entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
    +  entropy->pub.insufficient_data = FALSE;
    +
    +  /* Initialize private state variables */
    +  entropy->saved.EOBRUN = 0;
    +
    +  /* Initialize restart counter */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +}
    +
    +
    +/*
    + * Figure F.12: extend sign bit.
    + * On some machines, a shift and add will be faster than a table lookup.
    + */
    +
    +#ifdef AVOID_TABLES
    +
    +#define HUFF_EXTEND(x,s)  ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
    +
    +#else
    +
    +#define HUFF_EXTEND(x,s)  ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
    +
    +static const int extend_test[16] =   /* entry n is 2**(n-1) */
    +  { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
    +    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
    +
    +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
    +  { 0,
    +    (int)(((unsigned)(~0)<<1)  + 1), (int)(((unsigned)(~0)<<2)  + 1),
    +    (int)(((unsigned)(~0)<<3)  + 1), (int)(((unsigned)(~0)<<4)  + 1),
    +    (int)(((unsigned)(~0)<<5)  + 1), (int)(((unsigned)(~0)<<6)  + 1),
    +    (int)(((unsigned)(~0)<<7)  + 1), (int)(((unsigned)(~0)<<8)  + 1),
    +    (int)(((unsigned)(~0)<<9)  + 1), (int)(((unsigned)(~0)<<10) + 1),
    +    (int)(((unsigned)(~0)<<11) + 1), (int)(((unsigned)(~0)<<12) + 1),
    +    (int)(((unsigned)(~0)<<13) + 1), (int)(((unsigned)(~0)<<14) + 1),
    +    (int)(((unsigned)(~0)<<15) + 1) };
    +
    +#endif /* AVOID_TABLES */
    +
    +
    +/*
    + * Check for a restart marker & resynchronize decoder.
    + * Returns FALSE if must suspend.
    + */
    +
    +LOCAL(boolean)
    +process_restart (j_decompress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  int ci;
    +
    +  /* Throw away any unused bits remaining in bit buffer; */
    +  /* include any full bytes in next_marker's count of discarded bytes */
    +  cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
    +  entropy->bitstate.bits_left = 0;
    +
    +  /* Advance past the RSTn marker */
    +  if (! (*cinfo->marker->read_restart_marker) (cinfo))
    +    return FALSE;
    +
    +  /* Re-initialize DC predictions to 0 */
    +  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
    +    entropy->saved.last_dc_val[ci] = 0;
    +  /* Re-init EOB run count, too */
    +  entropy->saved.EOBRUN = 0;
    +
    +  /* Reset restart counter */
    +  entropy->restarts_to_go = cinfo->restart_interval;
    +
    +  /* Reset out-of-data flag, unless read_restart_marker left us smack up
    +   * against a marker.  In that case we will end up treating the next data
    +   * segment as empty, and we can avoid producing bogus output pixels by
    +   * leaving the flag set.
    +   */
    +  if (cinfo->unread_marker == 0)
    +    entropy->pub.insufficient_data = FALSE;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * Huffman MCU decoding.
    + * Each of these routines decodes and returns one MCU's worth of
    + * Huffman-compressed coefficients.
    + * The coefficients are reordered from zigzag order into natural array order,
    + * but are not dequantized.
    + *
    + * The i'th block of the MCU is stored into the block pointed to by
    + * MCU_data[i].  WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
    + *
    + * We return FALSE if data source requested suspension.  In that case no
    + * changes have been made to permanent state.  (Exception: some output
    + * coefficients may already have been assigned.  This is harmless for
    + * spectral selection, since we'll just re-assign them on the next call.
    + * Successive approximation AC refinement has to be more careful, however.)
    + */
    +
    +/*
    + * MCU decoding for DC initial scan (either spectral selection,
    + * or first pass of successive approximation).
    + */
    +
    +METHODDEF(boolean)
    +decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  int Al = cinfo->Al;
    +  register int s, r;
    +  int blkn, ci;
    +  JBLOCKROW block;
    +  BITREAD_STATE_VARS;
    +  savable_state state;
    +  d_derived_tbl * tbl;
    +  jpeg_component_info * compptr;
    +
    +  /* Process restart marker if needed; may have to suspend */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! process_restart(cinfo))
    +        return FALSE;
    +  }
    +
    +  /* If we've run out of data, just leave the MCU set to zeroes.
    +   * This way, we return uniform gray for the remainder of the segment.
    +   */
    +  if (! entropy->pub.insufficient_data) {
    +
    +    /* Load up working state */
    +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
    +    ASSIGN_STATE(state, entropy->saved);
    +
    +    /* Outer loop handles each block in the MCU */
    +
    +    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +      block = MCU_data[blkn];
    +      ci = cinfo->MCU_membership[blkn];
    +      compptr = cinfo->cur_comp_info[ci];
    +      tbl = entropy->derived_tbls[compptr->dc_tbl_no];
    +
    +      /* Decode a single block's worth of coefficients */
    +
    +      /* Section F.2.2.1: decode the DC coefficient difference */
    +      HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
    +      if (s) {
    +        CHECK_BIT_BUFFER(br_state, s, return FALSE);
    +        r = GET_BITS(s);
    +        s = HUFF_EXTEND(r, s);
    +      }
    +
    +      /* Convert DC difference to actual value, update last_dc_val */
    +      s += state.last_dc_val[ci];
    +      state.last_dc_val[ci] = s;
    +      /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
    +      (*block)[0] = (JCOEF) (s << Al);
    +    }
    +
    +    /* Completed MCU, so update state */
    +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    +    ASSIGN_STATE(entropy->saved, state);
    +  }
    +
    +  /* Account for restart interval (no-op if not using restarts) */
    +  entropy->restarts_to_go--;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU decoding for AC initial scan (either spectral selection,
    + * or first pass of successive approximation).
    + */
    +
    +METHODDEF(boolean)
    +decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  int Se = cinfo->Se;
    +  int Al = cinfo->Al;
    +  register int s, k, r;
    +  unsigned int EOBRUN;
    +  JBLOCKROW block;
    +  BITREAD_STATE_VARS;
    +  d_derived_tbl * tbl;
    +
    +  /* Process restart marker if needed; may have to suspend */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! process_restart(cinfo))
    +        return FALSE;
    +  }
    +
    +  /* If we've run out of data, just leave the MCU set to zeroes.
    +   * This way, we return uniform gray for the remainder of the segment.
    +   */
    +  if (! entropy->pub.insufficient_data) {
    +
    +    /* Load up working state.
    +     * We can avoid loading/saving bitread state if in an EOB run.
    +     */
    +    EOBRUN = entropy->saved.EOBRUN;     /* only part of saved state we need */
    +
    +    /* There is always only one block per MCU */
    +
    +    if (EOBRUN > 0)             /* if it's a band of zeroes... */
    +      EOBRUN--;                 /* ...process it now (we do nothing) */
    +    else {
    +      BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
    +      block = MCU_data[0];
    +      tbl = entropy->ac_derived_tbl;
    +
    +      for (k = cinfo->Ss; k <= Se; k++) {
    +        HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
    +        r = s >> 4;
    +        s &= 15;
    +        if (s) {
    +          k += r;
    +          CHECK_BIT_BUFFER(br_state, s, return FALSE);
    +          r = GET_BITS(s);
    +          s = HUFF_EXTEND(r, s);
    +          /* Scale and output coefficient in natural (dezigzagged) order */
    +          (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
    +        } else {
    +          if (r == 15) {        /* ZRL */
    +            k += 15;            /* skip 15 zeroes in band */
    +          } else {              /* EOBr, run length is 2^r + appended bits */
    +            EOBRUN = 1 << r;
    +            if (r) {            /* EOBr, r > 0 */
    +              CHECK_BIT_BUFFER(br_state, r, return FALSE);
    +              r = GET_BITS(r);
    +              EOBRUN += r;
    +            }
    +            EOBRUN--;           /* this band is processed at this moment */
    +            break;              /* force end-of-band */
    +          }
    +        }
    +      }
    +
    +      BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    +    }
    +
    +    /* Completed MCU, so update state */
    +    entropy->saved.EOBRUN = EOBRUN;     /* only part of saved state we need */
    +  }
    +
    +  /* Account for restart interval (no-op if not using restarts) */
    +  entropy->restarts_to_go--;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU decoding for DC successive approximation refinement scan.
    + * Note: we assume such scans can be multi-component, although the spec
    + * is not very clear on the point.
    + */
    +
    +METHODDEF(boolean)
    +decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  int p1 = 1 << cinfo->Al;      /* 1 in the bit position being coded */
    +  int blkn;
    +  JBLOCKROW block;
    +  BITREAD_STATE_VARS;
    +
    +  /* Process restart marker if needed; may have to suspend */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! process_restart(cinfo))
    +        return FALSE;
    +  }
    +
    +  /* Not worth the cycles to check insufficient_data here,
    +   * since we will not change the data anyway if we read zeroes.
    +   */
    +
    +  /* Load up working state */
    +  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
    +
    +  /* Outer loop handles each block in the MCU */
    +
    +  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
    +    block = MCU_data[blkn];
    +
    +    /* Encoded data is simply the next bit of the two's-complement DC value */
    +    CHECK_BIT_BUFFER(br_state, 1, return FALSE);
    +    if (GET_BITS(1))
    +      (*block)[0] |= p1;
    +    /* Note: since we use |=, repeating the assignment later is safe */
    +  }
    +
    +  /* Completed MCU, so update state */
    +  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    +
    +  /* Account for restart interval (no-op if not using restarts) */
    +  entropy->restarts_to_go--;
    +
    +  return TRUE;
    +}
    +
    +
    +/*
    + * MCU decoding for AC successive approximation refinement scan.
    + */
    +
    +METHODDEF(boolean)
    +decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
    +{
    +  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
    +  int Se = cinfo->Se;
    +  int p1 = 1 << cinfo->Al;      /* 1 in the bit position being coded */
    +  int m1 = (-1) << cinfo->Al;   /* -1 in the bit position being coded */
    +  register int s, k, r;
    +  unsigned int EOBRUN;
    +  JBLOCKROW block;
    +  JCOEFPTR thiscoef;
    +  BITREAD_STATE_VARS;
    +  d_derived_tbl * tbl;
    +  int num_newnz;
    +  int newnz_pos[DCTSIZE2];
    +
    +  /* Process restart marker if needed; may have to suspend */
    +  if (cinfo->restart_interval) {
    +    if (entropy->restarts_to_go == 0)
    +      if (! process_restart(cinfo))
    +        return FALSE;
    +  }
    +
    +  /* If we've run out of data, don't modify the MCU.
    +   */
    +  if (! entropy->pub.insufficient_data) {
    +
    +    /* Load up working state */
    +    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
    +    EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
    +
    +    /* There is always only one block per MCU */
    +    block = MCU_data[0];
    +    tbl = entropy->ac_derived_tbl;
    +
    +    /* If we are forced to suspend, we must undo the assignments to any newly
    +     * nonzero coefficients in the block, because otherwise we'd get confused
    +     * next time about which coefficients were already nonzero.
    +     * But we need not undo addition of bits to already-nonzero coefficients;
    +     * instead, we can test the current bit to see if we already did it.
    +     */
    +    num_newnz = 0;
    +
    +    /* initialize coefficient loop counter to start of band */
    +    k = cinfo->Ss;
    +
    +    if (EOBRUN == 0) {
    +      for (; k <= Se; k++) {
    +        HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
    +        r = s >> 4;
    +        s &= 15;
    +        if (s) {
    +          if (s != 1)           /* size of new coef should always be 1 */
    +            WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
    +          CHECK_BIT_BUFFER(br_state, 1, goto undoit);
    +          if (GET_BITS(1))
    +            s = p1;             /* newly nonzero coef is positive */
    +          else
    +            s = m1;             /* newly nonzero coef is negative */
    +        } else {
    +          if (r != 15) {
    +            EOBRUN = 1 << r;    /* EOBr, run length is 2^r + appended bits */
    +            if (r) {
    +              CHECK_BIT_BUFFER(br_state, r, goto undoit);
    +              r = GET_BITS(r);
    +              EOBRUN += r;
    +            }
    +            break;              /* rest of block is handled by EOB logic */
    +          }
    +          /* note s = 0 for processing ZRL */
    +        }
    +        /* Advance over already-nonzero coefs and r still-zero coefs,
    +         * appending correction bits to the nonzeroes.  A correction bit is 1
    +         * if the absolute value of the coefficient must be increased.
    +         */
    +        do {
    +          thiscoef = *block + jpeg_natural_order[k];
    +          if (*thiscoef != 0) {
    +            CHECK_BIT_BUFFER(br_state, 1, goto undoit);
    +            if (GET_BITS(1)) {
    +              if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
    +                if (*thiscoef >= 0)
    +                  *thiscoef += p1;
    +                else
    +                  *thiscoef += m1;
    +              }
    +            }
    +          } else {
    +            if (--r < 0)
    +              break;            /* reached target zero coefficient */
    +          }
    +          k++;
    +        } while (k <= Se);
    +        if (s) {
    +          int pos = jpeg_natural_order[k];
    +          /* Output newly nonzero coefficient */
    +          (*block)[pos] = (JCOEF) s;
    +          /* Remember its position in case we have to suspend */
    +          newnz_pos[num_newnz++] = pos;
    +        }
    +      }
    +    }
    +
    +    if (EOBRUN > 0) {
    +      /* Scan any remaining coefficient positions after the end-of-band
    +       * (the last newly nonzero coefficient, if any).  Append a correction
    +       * bit to each already-nonzero coefficient.  A correction bit is 1
    +       * if the absolute value of the coefficient must be increased.
    +       */
    +      for (; k <= Se; k++) {
    +        thiscoef = *block + jpeg_natural_order[k];
    +        if (*thiscoef != 0) {
    +          CHECK_BIT_BUFFER(br_state, 1, goto undoit);
    +          if (GET_BITS(1)) {
    +            if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
    +              if (*thiscoef >= 0)
    +                *thiscoef += p1;
    +              else
    +                *thiscoef += m1;
    +            }
    +          }
    +        }
    +      }
    +      /* Count one block completed in EOB run */
    +      EOBRUN--;
    +    }
    +
    +    /* Completed MCU, so update state */
    +    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
    +    entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
    +  }
    +
    +  /* Account for restart interval (no-op if not using restarts) */
    +  entropy->restarts_to_go--;
    +
    +  return TRUE;
    +
    +undoit:
    +  /* Re-zero any output coefficients that we made newly nonzero */
    +  while (num_newnz > 0)
    +    (*block)[newnz_pos[--num_newnz]] = 0;
    +
    +  return FALSE;
    +}
    +
    +
    +/*
    + * Module initialization routine for progressive Huffman entropy decoding.
    + */
    +
    +GLOBAL(void)
    +jinit_phuff_decoder (j_decompress_ptr cinfo)
    +{
    +  phuff_entropy_ptr entropy;
    +  int *coef_bit_ptr;
    +  int ci, i;
    +
    +  entropy = (phuff_entropy_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(phuff_entropy_decoder));
    +  cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
    +  entropy->pub.start_pass = start_pass_phuff_decoder;
    +
    +  /* Mark derived tables unallocated */
    +  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    +    entropy->derived_tbls[i] = NULL;
    +  }
    +
    +  /* Create progression status table */
    +  cinfo->coef_bits = (int (*)[DCTSIZE2])
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                cinfo->num_components*DCTSIZE2*SIZEOF(int));
    +  coef_bit_ptr = & cinfo->coef_bits[0][0];
    +  for (ci = 0; ci < cinfo->num_components; ci++)
    +    for (i = 0; i < DCTSIZE2; i++)
    +      *coef_bit_ptr++ = -1;
    +}
    +
    +#endif /* D_PROGRESSIVE_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdpostct.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdpostct.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdpostct.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdpostct.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,294 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdpostct.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the decompression postprocessing controller.
    + * This controller manages the upsampling, color conversion, and color
    + * quantization/reduction steps; specifically, it controls the buffering
    + * between upsample/color conversion and color quantization/reduction.
    + *
    + * If no color quantization/reduction is required, then this module has no
    + * work to do, and it just hands off to the upsample/color conversion code.
    + * An integrated upsample/convert/quantize process would replace this module
    + * entirely.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Private buffer controller object */
    +
    +typedef struct {
    +  struct jpeg_d_post_controller pub; /* public fields */
    +
    +  /* Color quantization source buffer: this holds output data from
    +   * the upsample/color conversion step to be passed to the quantizer.
    +   * For two-pass color quantization, we need a full-image buffer;
    +   * for one-pass operation, a strip buffer is sufficient.
    +   */
    +  jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
    +  JSAMPARRAY buffer;            /* strip buffer, or current strip of virtual */
    +  JDIMENSION strip_height;      /* buffer size in rows */
    +  /* for two-pass mode only: */
    +  JDIMENSION starting_row;      /* row # of first row in current strip */
    +  JDIMENSION next_row;          /* index of next row to fill/empty in strip */
    +} my_post_controller;
    +
    +typedef my_post_controller * my_post_ptr;
    +
    +
    +/* Forward declarations */
    +METHODDEF(void) post_process_1pass
    +        JPP((j_decompress_ptr cinfo,
    +             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +             JDIMENSION in_row_groups_avail,
    +             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +             JDIMENSION out_rows_avail));
    +#ifdef QUANT_2PASS_SUPPORTED
    +METHODDEF(void) post_process_prepass
    +        JPP((j_decompress_ptr cinfo,
    +             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +             JDIMENSION in_row_groups_avail,
    +             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +             JDIMENSION out_rows_avail));
    +METHODDEF(void) post_process_2pass
    +        JPP((j_decompress_ptr cinfo,
    +             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +             JDIMENSION in_row_groups_avail,
    +             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +             JDIMENSION out_rows_avail));
    +#endif
    +
    +
    +/*
    + * Initialize for a processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
    +{
    +  my_post_ptr post = (my_post_ptr) cinfo->post;
    +
    +  switch (pass_mode) {
    +  case JBUF_PASS_THRU:
    +    if (cinfo->quantize_colors) {
    +      /* Single-pass processing with color quantization. */
    +      post->pub.post_process_data = post_process_1pass;
    +      /* We could be doing buffered-image output before starting a 2-pass
    +       * color quantization; in that case, jinit_d_post_controller did not
    +       * allocate a strip buffer.  Use the virtual-array buffer as workspace.
    +       */
    +      if (post->buffer == NULL) {
    +        post->buffer = (*cinfo->mem->access_virt_sarray)
    +          ((j_common_ptr) cinfo, post->whole_image,
    +           (JDIMENSION) 0, post->strip_height, TRUE);
    +      }
    +    } else {
    +      /* For single-pass processing without color quantization,
    +       * I have no work to do; just call the upsampler directly.
    +       */
    +      post->pub.post_process_data = cinfo->upsample->upsample;
    +    }
    +    break;
    +#ifdef QUANT_2PASS_SUPPORTED
    +  case JBUF_SAVE_AND_PASS:
    +    /* First pass of 2-pass quantization */
    +    if (post->whole_image == NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    post->pub.post_process_data = post_process_prepass;
    +    break;
    +  case JBUF_CRANK_DEST:
    +    /* Second pass of 2-pass quantization */
    +    if (post->whole_image == NULL)
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    post->pub.post_process_data = post_process_2pass;
    +    break;
    +#endif /* QUANT_2PASS_SUPPORTED */
    +  default:
    +    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +    break;
    +  }
    +  post->starting_row = post->next_row = 0;
    +}
    +
    +
    +/*
    + * Process some data in the one-pass (strip buffer) case.
    + * This is used for color precision reduction as well as one-pass quantization.
    + */
    +
    +METHODDEF(void)
    +post_process_1pass (j_decompress_ptr cinfo,
    +                    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +                    JDIMENSION in_row_groups_avail,
    +                    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                    JDIMENSION out_rows_avail)
    +{
    +  my_post_ptr post = (my_post_ptr) cinfo->post;
    +  JDIMENSION num_rows, max_rows;
    +
    +  /* Fill the buffer, but not more than what we can dump out in one go. */
    +  /* Note we rely on the upsampler to detect bottom of image. */
    +  max_rows = out_rows_avail - *out_row_ctr;
    +  if (max_rows > post->strip_height)
    +    max_rows = post->strip_height;
    +  num_rows = 0;
    +  (*cinfo->upsample->upsample) (cinfo,
    +                input_buf, in_row_group_ctr, in_row_groups_avail,
    +                post->buffer, &num_rows, max_rows);
    +  /* Quantize and emit data. */
    +  (*cinfo->cquantize->color_quantize) (cinfo,
    +                post->buffer, output_buf + *out_row_ctr, (int) num_rows);
    +  *out_row_ctr += num_rows;
    +}
    +
    +
    +#ifdef QUANT_2PASS_SUPPORTED
    +
    +/*
    + * Process some data in the first pass of 2-pass quantization.
    + */
    +
    +METHODDEF(void)
    +post_process_prepass (j_decompress_ptr cinfo,
    +                      JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +                      JDIMENSION in_row_groups_avail,
    +                      JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                      JDIMENSION out_rows_avail)
    +{
    +  my_post_ptr post = (my_post_ptr) cinfo->post;
    +  JDIMENSION old_next_row, num_rows;
    +
    +  /* Reposition virtual buffer if at start of strip. */
    +  if (post->next_row == 0) {
    +    post->buffer = (*cinfo->mem->access_virt_sarray)
    +        ((j_common_ptr) cinfo, post->whole_image,
    +         post->starting_row, post->strip_height, TRUE);
    +  }
    +
    +  /* Upsample some data (up to a strip height's worth). */
    +  old_next_row = post->next_row;
    +  (*cinfo->upsample->upsample) (cinfo,
    +                input_buf, in_row_group_ctr, in_row_groups_avail,
    +                post->buffer, &post->next_row, post->strip_height);
    +
    +  /* Allow quantizer to scan new data.  No data is emitted, */
    +  /* but we advance out_row_ctr so outer loop can tell when we're done. */
    +  if (post->next_row > old_next_row) {
    +    num_rows = post->next_row - old_next_row;
    +    (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
    +                                         (JSAMPARRAY) NULL, (int) num_rows);
    +    *out_row_ctr += num_rows;
    +  }
    +
    +  /* Advance if we filled the strip. */
    +  if (post->next_row >= post->strip_height) {
    +    post->starting_row += post->strip_height;
    +    post->next_row = 0;
    +  }
    +}
    +
    +
    +/*
    + * Process some data in the second pass of 2-pass quantization.
    + */
    +
    +METHODDEF(void)
    +post_process_2pass (j_decompress_ptr cinfo,
    +                    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +                    JDIMENSION in_row_groups_avail,
    +                    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                    JDIMENSION out_rows_avail)
    +{
    +  my_post_ptr post = (my_post_ptr) cinfo->post;
    +  JDIMENSION num_rows, max_rows;
    +
    +  /* Reposition virtual buffer if at start of strip. */
    +  if (post->next_row == 0) {
    +    post->buffer = (*cinfo->mem->access_virt_sarray)
    +        ((j_common_ptr) cinfo, post->whole_image,
    +         post->starting_row, post->strip_height, FALSE);
    +  }
    +
    +  /* Determine number of rows to emit. */
    +  num_rows = post->strip_height - post->next_row; /* available in strip */
    +  max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
    +  if (num_rows > max_rows)
    +    num_rows = max_rows;
    +  /* We have to check bottom of image here, can't depend on upsampler. */
    +  max_rows = cinfo->output_height - post->starting_row;
    +  if (num_rows > max_rows)
    +    num_rows = max_rows;
    +
    +  /* Quantize and emit data. */
    +  (*cinfo->cquantize->color_quantize) (cinfo,
    +                post->buffer + post->next_row, output_buf + *out_row_ctr,
    +                (int) num_rows);
    +  *out_row_ctr += num_rows;
    +
    +  /* Advance if we filled the strip. */
    +  post->next_row += num_rows;
    +  if (post->next_row >= post->strip_height) {
    +    post->starting_row += post->strip_height;
    +    post->next_row = 0;
    +  }
    +}
    +
    +#endif /* QUANT_2PASS_SUPPORTED */
    +
    +
    +/*
    + * Initialize postprocessing controller.
    + */
    +
    +GLOBAL(void)
    +jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
    +{
    +  my_post_ptr post;
    +
    +  post = (my_post_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_post_controller));
    +  cinfo->post = (struct jpeg_d_post_controller *) post;
    +  post->pub.start_pass = start_pass_dpost;
    +  post->whole_image = NULL;     /* flag for no virtual arrays */
    +  post->buffer = NULL;          /* flag for no strip buffer */
    +
    +  /* Create the quantization buffer, if needed */
    +  if (cinfo->quantize_colors) {
    +    /* The buffer strip height is max_v_samp_factor, which is typically
    +     * an efficient number of rows for upsampling to return.
    +     * (In the presence of output rescaling, we might want to be smarter?)
    +     */
    +    post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
    +    if (need_full_buffer) {
    +      /* Two-pass color quantization: need full-image storage. */
    +      /* We round up the number of rows to a multiple of the strip height. */
    +#ifdef QUANT_2PASS_SUPPORTED
    +      post->whole_image = (*cinfo->mem->request_virt_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
    +         cinfo->output_width * cinfo->out_color_components,
    +         (JDIMENSION) jround_up((long) cinfo->output_height,
    +                                (long) post->strip_height),
    +         post->strip_height);
    +#else
    +      ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    +#endif /* QUANT_2PASS_SUPPORTED */
    +    } else {
    +      /* One-pass color quantization: just make a strip buffer. */
    +      post->buffer = (*cinfo->mem->alloc_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +         cinfo->output_width * cinfo->out_color_components,
    +         post->strip_height);
    +    }
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdsample.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdsample.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdsample.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdsample.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,482 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdsample.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains upsampling routines.
    + *
    + * Upsampling input data is counted in "row groups".  A row group
    + * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
    + * sample rows of each component.  Upsampling will normally produce
    + * max_v_samp_factor pixel rows from each row group (but this could vary
    + * if the upsampler is applying a scale factor of its own).
    + *
    + * An excellent reference for image resampling is
    + *   Digital Image Warping, George Wolberg, 1990.
    + *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Pointer to routine to upsample a single component */
    +typedef JMETHOD(void, upsample1_ptr,
    +                (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                 JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
    +
    +/* Private subobject */
    +
    +typedef struct {
    +  struct jpeg_upsampler pub;    /* public fields */
    +
    +  /* Color conversion buffer.  When using separate upsampling and color
    +   * conversion steps, this buffer holds one upsampled row group until it
    +   * has been color converted and output.
    +   * Note: we do not allocate any storage for component(s) which are full-size,
    +   * ie do not need rescaling.  The corresponding entry of color_buf[] is
    +   * simply set to point to the input data array, thereby avoiding copying.
    +   */
    +  JSAMPARRAY color_buf[MAX_COMPONENTS];
    +
    +  /* Per-component upsampling method pointers */
    +  upsample1_ptr methods[MAX_COMPONENTS];
    +
    +  int next_row_out;             /* counts rows emitted from color_buf */
    +  JDIMENSION rows_to_go;        /* counts rows remaining in image */
    +
    +  /* Height of an input row group for each component. */
    +  int rowgroup_height[MAX_COMPONENTS];
    +
    +  /* These arrays save pixel expansion factors so that int_expand need not
    +   * recompute them each time.  They are unused for other upsampling methods.
    +   */
    +  UINT8 h_expand[MAX_COMPONENTS];
    +  UINT8 v_expand[MAX_COMPONENTS];
    +} my_upsampler;
    +
    +typedef my_upsampler * my_upsample_ptr;
    +
    +
    +/*
    + * Initialize for an upsampling pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_upsample (j_decompress_ptr cinfo)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +
    +  /* Mark the conversion buffer empty */
    +  upsample->next_row_out = cinfo->max_v_samp_factor;
    +  /* Initialize total-height counter for detecting bottom of image */
    +  upsample->rows_to_go = cinfo->output_height;
    +}
    +
    +
    +/*
    + * Control routine to do upsampling (and color conversion).
    + *
    + * In this version we upsample each component independently.
    + * We upsample one row group into the conversion buffer, then apply
    + * color conversion a row at a time.
    + */
    +
    +METHODDEF(void)
    +sep_upsample (j_decompress_ptr cinfo,
    +              JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    +              JDIMENSION in_row_groups_avail,
    +              JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +              JDIMENSION out_rows_avail)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  int ci;
    +  jpeg_component_info * compptr;
    +  JDIMENSION num_rows;
    +
    +  /* Fill the conversion buffer, if it's empty */
    +  if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
    +    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +         ci++, compptr++) {
    +      /* Invoke per-component upsample method.  Notice we pass a POINTER
    +       * to color_buf[ci], so that fullsize_upsample can change it.
    +       */
    +      (*upsample->methods[ci]) (cinfo, compptr,
    +        input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
    +        upsample->color_buf + ci);
    +    }
    +    upsample->next_row_out = 0;
    +  }
    +
    +  /* Color-convert and emit rows */
    +
    +  /* How many we have in the buffer: */
    +  num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
    +  /* Not more than the distance to the end of the image.  Need this test
    +   * in case the image height is not a multiple of max_v_samp_factor:
    +   */
    +  if (num_rows > upsample->rows_to_go)
    +    num_rows = upsample->rows_to_go;
    +  /* And not more than what the client can accept: */
    +  out_rows_avail -= *out_row_ctr;
    +  if (num_rows > out_rows_avail)
    +    num_rows = out_rows_avail;
    +
    +  (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
    +                                     (JDIMENSION) upsample->next_row_out,
    +                                     output_buf + *out_row_ctr,
    +                                     (int) num_rows);
    +
    +  /* Adjust counts */
    +  *out_row_ctr += num_rows;
    +  upsample->rows_to_go -= num_rows;
    +  upsample->next_row_out += num_rows;
    +  /* When the buffer is emptied, declare this input row group consumed */
    +  if (upsample->next_row_out >= cinfo->max_v_samp_factor)
    +    (*in_row_group_ctr)++;
    +}
    +
    +
    +/*
    + * These are the routines invoked by sep_upsample to upsample pixel values
    + * of a single component.  One row group is processed per call.
    + */
    +
    +
    +/*
    + * For full-size components, we just make color_buf[ci] point at the
    + * input buffer, and thus avoid copying any data.  Note that this is
    + * safe only because sep_upsample doesn't declare the input row group
    + * "consumed" until we are done color converting and emitting it.
    + */
    +
    +METHODDEF(void)
    +fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                   JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  *output_data_ptr = input_data;
    +}
    +
    +
    +/*
    + * This is a no-op version used for "uninteresting" components.
    + * These components will not be referenced by color conversion.
    + */
    +
    +METHODDEF(void)
    +noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  *output_data_ptr = NULL;      /* safety check */
    +}
    +
    +
    +/*
    + * This version handles any integral sampling ratios.
    + * This is not used for typical JPEG files, so it need not be fast.
    + * Nor, for that matter, is it particularly accurate: the algorithm is
    + * simple replication of the input pixel onto the corresponding output
    + * pixels.  The hi-falutin sampling literature refers to this as a
    + * "box filter".  A box filter tends to introduce visible artifacts,
    + * so if you are actually going to use 3:1 or 4:1 sampling ratios
    + * you would be well advised to improve this code.
    + */
    +
    +METHODDEF(void)
    +int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +              JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    +  JSAMPARRAY output_data = *output_data_ptr;
    +  register JSAMPROW inptr, outptr;
    +  register JSAMPLE invalue;
    +  register int h;
    +  JSAMPROW outend;
    +  int h_expand, v_expand;
    +  int inrow, outrow;
    +
    +  h_expand = upsample->h_expand[compptr->component_index];
    +  v_expand = upsample->v_expand[compptr->component_index];
    +
    +  inrow = outrow = 0;
    +  while (outrow < cinfo->max_v_samp_factor) {
    +    /* Generate one output row with proper horizontal expansion */
    +    inptr = input_data[inrow];
    +    outptr = output_data[outrow];
    +    outend = outptr + cinfo->output_width;
    +    while (outptr < outend) {
    +      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
    +      for (h = h_expand; h > 0; h--) {
    +        *outptr++ = invalue;
    +      }
    +    }
    +    /* Generate any additional output rows by duplicating the first one */
    +    if (v_expand > 1) {
    +      jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
    +                        v_expand-1, cinfo->output_width);
    +    }
    +    inrow++;
    +    outrow += v_expand;
    +  }
    +}
    +
    +
    +/*
    + * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
    + * It's still a box filter.
    + */
    +
    +METHODDEF(void)
    +h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  JSAMPARRAY output_data = *output_data_ptr;
    +  register JSAMPROW inptr, outptr;
    +  register JSAMPLE invalue;
    +  JSAMPROW outend;
    +  int inrow;
    +
    +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
    +    inptr = input_data[inrow];
    +    outptr = output_data[inrow];
    +    outend = outptr + cinfo->output_width;
    +    while (outptr < outend) {
    +      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
    +      *outptr++ = invalue;
    +      *outptr++ = invalue;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
    + * It's still a box filter.
    + */
    +
    +METHODDEF(void)
    +h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  JSAMPARRAY output_data = *output_data_ptr;
    +  register JSAMPROW inptr, outptr;
    +  register JSAMPLE invalue;
    +  JSAMPROW outend;
    +  int inrow, outrow;
    +
    +  inrow = outrow = 0;
    +  while (outrow < cinfo->max_v_samp_factor) {
    +    inptr = input_data[inrow];
    +    outptr = output_data[outrow];
    +    outend = outptr + cinfo->output_width;
    +    while (outptr < outend) {
    +      invalue = *inptr++;       /* don't need GETJSAMPLE() here */
    +      *outptr++ = invalue;
    +      *outptr++ = invalue;
    +    }
    +    jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
    +                      1, cinfo->output_width);
    +    inrow++;
    +    outrow += 2;
    +  }
    +}
    +
    +
    +/*
    + * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
    + *
    + * The upsampling algorithm is linear interpolation between pixel centers,
    + * also known as a "triangle filter".  This is a good compromise between
    + * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4
    + * of the way between input pixel centers.
    + *
    + * A note about the "bias" calculations: when rounding fractional values to
    + * integer, we do not want to always round 0.5 up to the next integer.
    + * If we did that, we'd introduce a noticeable bias towards larger values.
    + * Instead, this code is arranged so that 0.5 will be rounded up or down at
    + * alternate pixel locations (a simple ordered dither pattern).
    + */
    +
    +METHODDEF(void)
    +h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  JSAMPARRAY output_data = *output_data_ptr;
    +  register JSAMPROW inptr, outptr;
    +  register int invalue;
    +  register JDIMENSION colctr;
    +  int inrow;
    +
    +  for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
    +    inptr = input_data[inrow];
    +    outptr = output_data[inrow];
    +    /* Special case for first column */
    +    invalue = GETJSAMPLE(*inptr++);
    +    *outptr++ = (JSAMPLE) invalue;
    +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
    +
    +    for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
    +      /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
    +      invalue = GETJSAMPLE(*inptr++) * 3;
    +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
    +      *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
    +    }
    +
    +    /* Special case for last column */
    +    invalue = GETJSAMPLE(*inptr);
    +    *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
    +    *outptr++ = (JSAMPLE) invalue;
    +  }
    +}
    +
    +
    +/*
    + * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
    + * Again a triangle filter; see comments for h2v1 case, above.
    + *
    + * It is OK for us to reference the adjacent input rows because we demanded
    + * context from the main buffer controller (see initialization code).
    + */
    +
    +METHODDEF(void)
    +h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                     JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
    +{
    +  JSAMPARRAY output_data = *output_data_ptr;
    +  register JSAMPROW inptr0, inptr1, outptr;
    +#if BITS_IN_JSAMPLE == 8
    +  register int thiscolsum, lastcolsum, nextcolsum;
    +#else
    +  register INT32 thiscolsum, lastcolsum, nextcolsum;
    +#endif
    +  register JDIMENSION colctr;
    +  int inrow, outrow, v;
    +
    +  inrow = outrow = 0;
    +  while (outrow < cinfo->max_v_samp_factor) {
    +    for (v = 0; v < 2; v++) {
    +      /* inptr0 points to nearest input row, inptr1 points to next nearest */
    +      inptr0 = input_data[inrow];
    +      if (v == 0)               /* next nearest is row above */
    +        inptr1 = input_data[inrow-1];
    +      else                      /* next nearest is row below */
    +        inptr1 = input_data[inrow+1];
    +      outptr = output_data[outrow++];
    +
    +      /* Special case for first column */
    +      thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
    +      nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
    +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
    +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
    +      lastcolsum = thiscolsum; thiscolsum = nextcolsum;
    +
    +      for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
    +        /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
    +        /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
    +        nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
    +        *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
    +        *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
    +        lastcolsum = thiscolsum; thiscolsum = nextcolsum;
    +      }
    +
    +      /* Special case for last column */
    +      *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
    +      *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
    +    }
    +    inrow++;
    +  }
    +}
    +
    +
    +/*
    + * Module initialization routine for upsampling.
    + */
    +
    +GLOBAL(void)
    +jinit_upsampler (j_decompress_ptr cinfo)
    +{
    +  my_upsample_ptr upsample;
    +  int ci;
    +  jpeg_component_info * compptr;
    +  boolean need_buffer, do_fancy;
    +  int h_in_group, v_in_group, h_out_group, v_out_group;
    +
    +  upsample = (my_upsample_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_upsampler));
    +  cinfo->upsample = (struct jpeg_upsampler *) upsample;
    +  upsample->pub.start_pass = start_pass_upsample;
    +  upsample->pub.upsample = sep_upsample;
    +  upsample->pub.need_context_rows = FALSE; /* until we find out differently */
    +
    +  if (cinfo->CCIR601_sampling)  /* this isn't supported */
    +    ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
    +
    +  /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
    +   * so don't ask for it.
    +   */
    +  do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
    +
    +  /* Verify we can handle the sampling factors, select per-component methods,
    +   * and create storage as needed.
    +   */
    +  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    +       ci++, compptr++) {
    +    /* Compute size of an "input group" after IDCT scaling.  This many samples
    +     * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
    +     */
    +    h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
    +                 cinfo->min_DCT_scaled_size;
    +    v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
    +                 cinfo->min_DCT_scaled_size;
    +    h_out_group = cinfo->max_h_samp_factor;
    +    v_out_group = cinfo->max_v_samp_factor;
    +    upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
    +    need_buffer = TRUE;
    +    if (! compptr->component_needed) {
    +      /* Don't bother to upsample an uninteresting component. */
    +      upsample->methods[ci] = noop_upsample;
    +      need_buffer = FALSE;
    +    } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
    +      /* Fullsize components can be processed without any work. */
    +      upsample->methods[ci] = fullsize_upsample;
    +      need_buffer = FALSE;
    +    } else if (h_in_group * 2 == h_out_group &&
    +               v_in_group == v_out_group) {
    +      /* Special cases for 2h1v upsampling */
    +      if (do_fancy && compptr->downsampled_width > 2)
    +        upsample->methods[ci] = h2v1_fancy_upsample;
    +      else
    +        upsample->methods[ci] = h2v1_upsample;
    +    } else if (h_in_group * 2 == h_out_group &&
    +               v_in_group * 2 == v_out_group) {
    +      /* Special cases for 2h2v upsampling */
    +      if (do_fancy && compptr->downsampled_width > 2) {
    +        upsample->methods[ci] = h2v2_fancy_upsample;
    +        upsample->pub.need_context_rows = TRUE;
    +      } else
    +        upsample->methods[ci] = h2v2_upsample;
    +    } else if ((h_out_group % h_in_group) == 0 &&
    +               (v_out_group % v_in_group) == 0) {
    +      /* Generic integral-factors upsampling method */
    +      upsample->methods[ci] = int_upsample;
    +      upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
    +      upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
    +    } else
    +      ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
    +    if (need_buffer) {
    +      upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
    +        ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +         (JDIMENSION) jround_up((long) cinfo->output_width,
    +                                (long) cinfo->max_h_samp_factor),
    +         (JDIMENSION) cinfo->max_v_samp_factor);
    +    }
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdtrans.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdtrans.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jdtrans.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jdtrans.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,147 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jdtrans.c
    + *
    + * Copyright (C) 1995-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains library routines for transcoding decompression,
    + * that is, reading raw DCT coefficient arrays from an input JPEG file.
    + * The routines in jdapimin.c will also be needed by a transcoder.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/* Forward declarations */
    +LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
    +
    +
    +/*
    + * Read the coefficient arrays from a JPEG file.
    + * jpeg_read_header must be completed before calling this.
    + *
    + * The entire image is read into a set of virtual coefficient-block arrays,
    + * one per component.  The return value is a pointer to the array of
    + * virtual-array descriptors.  These can be manipulated directly via the
    + * JPEG memory manager, or handed off to jpeg_write_coefficients().
    + * To release the memory occupied by the virtual arrays, call
    + * jpeg_finish_decompress() when done with the data.
    + *
    + * An alternative usage is to simply obtain access to the coefficient arrays
    + * during a buffered-image-mode decompression operation.  This is allowed
    + * after any jpeg_finish_output() call.  The arrays can be accessed until
    + * jpeg_finish_decompress() is called.  (Note that any call to the library
    + * may reposition the arrays, so don't rely on access_virt_barray() results
    + * to stay valid across library calls.)
    + *
    + * Returns NULL if suspended.  This case need be checked only if
    + * a suspending data source is used.
    + */
    +
    +GLOBAL(jvirt_barray_ptr *)
    +jpeg_read_coefficients (j_decompress_ptr cinfo)
    +{
    +  if (cinfo->global_state == DSTATE_READY) {
    +    /* First call: initialize active modules */
    +    transdecode_master_selection(cinfo);
    +    cinfo->global_state = DSTATE_RDCOEFS;
    +  }
    +  if (cinfo->global_state == DSTATE_RDCOEFS) {
    +    /* Absorb whole file into the coef buffer */
    +    for (;;) {
    +      int retcode;
    +      /* Call progress monitor hook if present */
    +      if (cinfo->progress != NULL)
    +        (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
    +      /* Absorb some more input */
    +      retcode = (*cinfo->inputctl->consume_input) (cinfo);
    +      if (retcode == JPEG_SUSPENDED)
    +        return NULL;
    +      if (retcode == JPEG_REACHED_EOI)
    +        break;
    +      /* Advance progress counter if appropriate */
    +      if (cinfo->progress != NULL &&
    +          (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
    +        if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
    +          /* startup underestimated number of scans; ratchet up one scan */
    +          cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
    +        }
    +      }
    +    }
    +    /* Set state so that jpeg_finish_decompress does the right thing */
    +    cinfo->global_state = DSTATE_STOPPING;
    +  }
    +  /* At this point we should be in state DSTATE_STOPPING if being used
    +   * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
    +   * to the coefficients during a full buffered-image-mode decompression.
    +   */
    +  if ((cinfo->global_state == DSTATE_STOPPING ||
    +       cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
    +    return cinfo->coef->coef_arrays;
    +  }
    +  /* Oops, improper usage */
    +  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
    +  return NULL;                  /* keep compiler happy */
    +}
    +
    +
    +/*
    + * Master selection of decompression modules for transcoding.
    + * This substitutes for jdmaster.c's initialization of the full decompressor.
    + */
    +
    +LOCAL(void)
    +transdecode_master_selection (j_decompress_ptr cinfo)
    +{
    +  /* This is effectively a buffered-image operation. */
    +  cinfo->buffered_image = TRUE;
    +
    +  /* Entropy decoding: either Huffman or arithmetic coding. */
    +  if (cinfo->arith_code) {
    +    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
    +  } else {
    +    if (cinfo->progressive_mode) {
    +#ifdef D_PROGRESSIVE_SUPPORTED
    +      jinit_phuff_decoder(cinfo);
    +#else
    +      ERREXIT(cinfo, JERR_NOT_COMPILED);
    +#endif
    +    } else
    +      jinit_huff_decoder(cinfo);
    +  }
    +
    +  /* Always get a full-image coefficient buffer. */
    +  jinit_d_coef_controller(cinfo, TRUE);
    +
    +  /* We can now tell the memory manager to allocate virtual arrays. */
    +  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
    +
    +  /* Initialize input side of decompressor to consume first scan. */
    +  (*cinfo->inputctl->start_input_pass) (cinfo);
    +
    +  /* Initialize progress monitoring. */
    +  if (cinfo->progress != NULL) {
    +    int nscans;
    +    /* Estimate number of scans to set pass_limit. */
    +    if (cinfo->progressive_mode) {
    +      /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
    +      nscans = 2 + 3 * cinfo->num_components;
    +    } else if (cinfo->inputctl->has_multiple_scans) {
    +      /* For a nonprogressive multiscan file, estimate 1 scan per component. */
    +      nscans = cinfo->num_components;
    +    } else {
    +      nscans = 1;
    +    }
    +    cinfo->progress->pass_counter = 0L;
    +    cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
    +    cinfo->progress->completed_passes = 0;
    +    cinfo->progress->total_passes = 1;
    +  }
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jerror.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jerror.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jerror.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jerror.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,272 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jerror.c
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains simple error-reporting and trace-message routines.
    + * These are suitable for Unix-like systems and others where writing to
    + * stderr is the right thing to do.  Many applications will want to replace
    + * some or all of these routines.
    + *
    + * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
    + * you get a Windows-specific hack to display error messages in a dialog box.
    + * It ain't much, but it beats dropping error messages into the bit bucket,
    + * which is what happens to output to stderr under most Windows C compilers.
    + *
    + * These routines are used by both the compression and decompression code.
    + */
    +
    +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jversion.h"
    +#include "jerror.h"
    +
    +#ifdef USE_WINDOWS_MESSAGEBOX
    +#include 
    +#endif
    +
    +#ifndef EXIT_FAILURE            /* define exit() codes if not provided */
    +#define EXIT_FAILURE  1
    +#endif
    +
    +
    +/*
    + * Create the message string table.
    + * We do this from the master message list in jerror.h by re-reading
    + * jerror.h with a suitable definition for macro JMESSAGE.
    + * The message table is made an external symbol just in case any applications
    + * want to refer to it directly.
    + */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_std_message_table  jMsgTable
    +#endif
    +
    +#define JMESSAGE(code,string)   string ,
    +
    +const char * const jpeg_std_message_table[] = {
    +#include "jerror.h"
    +  NULL
    +};
    +
    +
    +/*
    + * Error exit handler: must not return to caller.
    + *
    + * Applications may override this if they want to get control back after
    + * an error.  Typically one would longjmp somewhere instead of exiting.
    + * The setjmp buffer can be made a private field within an expanded error
    + * handler object.  Note that the info needed to generate an error message
    + * is stored in the error object, so you can generate the message now or
    + * later, at your convenience.
    + * You should make sure that the JPEG object is cleaned up (with jpeg_abort
    + * or jpeg_destroy) at some point.
    + */
    +
    +METHODDEF(void)
    +error_exit (j_common_ptr cinfo)
    +{
    +  /* Always display the message */
    +  (*cinfo->err->output_message) (cinfo);
    +
    +  /* Let the memory manager delete any temp files before we die */
    +  jpeg_destroy(cinfo);
    +
    +  /*
    +   * This should never happen since the Java library replaces the
    +   * error_exit pointer in the error handler structs it uses.
    +   *
    +   * exit(EXIT_FAILURE);
    +   */
    +}
    +
    +
    +/*
    + * Actual output of an error or trace message.
    + * Applications may override this method to send JPEG messages somewhere
    + * other than stderr.
    + *
    + * On Windows, printing to stderr is generally completely useless,
    + * so we provide optional code to produce an error-dialog popup.
    + * Most Windows applications will still prefer to override this routine,
    + * but if they don't, it'll do something at least marginally useful.
    + *
    + * NOTE: to use the library in an environment that doesn't support the
    + * C stdio library, you may have to delete the call to fprintf() entirely,
    + * not just not use this routine.
    + */
    +
    +METHODDEF(void)
    +output_message (j_common_ptr cinfo)
    +{
    +  char buffer[JMSG_LENGTH_MAX];
    +
    +  /* Create the message */
    +  (*cinfo->err->format_message) (cinfo, buffer);
    +
    +#ifdef USE_WINDOWS_MESSAGEBOX
    +  /* Display it in a message dialog box */
    +  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
    +             MB_OK | MB_ICONERROR);
    +#else
    +  /* Send it to stderr, adding a newline */
    +  fprintf(stderr, "%s\n", buffer);
    +#endif
    +}
    +
    +
    +/*
    + * Decide whether to emit a trace or warning message.
    + * msg_level is one of:
    + *   -1: recoverable corrupt-data warning, may want to abort.
    + *    0: important advisory messages (always display to user).
    + *    1: first level of tracing detail.
    + *    2,3,...: successively more detailed tracing messages.
    + * An application might override this method if it wanted to abort on warnings
    + * or change the policy about which messages to display.
    + */
    +
    +METHODDEF(void)
    +emit_message (j_common_ptr cinfo, int msg_level)
    +{
    +  struct jpeg_error_mgr * err = cinfo->err;
    +
    +  if (msg_level < 0) {
    +    /* It's a warning message.  Since corrupt files may generate many warnings,
    +     * the policy implemented here is to show only the first warning,
    +     * unless trace_level >= 3.
    +     */
    +    if (err->num_warnings == 0 || err->trace_level >= 3)
    +      (*err->output_message) (cinfo);
    +    /* Always count warnings in num_warnings. */
    +    err->num_warnings++;
    +  } else {
    +    /* It's a trace message.  Show it if trace_level >= msg_level. */
    +    if (err->trace_level >= msg_level)
    +      (*err->output_message) (cinfo);
    +  }
    +}
    +
    +
    +/*
    + * Format a message string for the most recent JPEG error or message.
    + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
    + * characters.  Note that no '\n' character is added to the string.
    + * Few applications should need to override this method.
    + */
    +
    +METHODDEF(void)
    +format_message (j_common_ptr cinfo, char * buffer)
    +{
    +
    +/* Had to kill this function altogether
    +   to avoid linking to VM when building the splash screen with static libjpeg */
    +
    +#ifndef SPLASHSCREEN
    +  int jio_snprintf(char *str, size_t count, const char *fmt, ...);
    +  struct jpeg_error_mgr * err = cinfo->err;
    +  int msg_code = err->msg_code;
    +  const char * msgtext = NULL;
    +  const char * msgptr;
    +  char ch;
    +  boolean isstring;
    +
    +  /* Look up message string in proper table */
    +  if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
    +    msgtext = err->jpeg_message_table[msg_code];
    +  } else if (err->addon_message_table != NULL &&
    +             msg_code >= err->first_addon_message &&
    +             msg_code <= err->last_addon_message) {
    +    msgtext = err->addon_message_table[msg_code - err->first_addon_message];
    +  }
    +
    +  /* Defend against bogus message number */
    +  if (msgtext == NULL) {
    +    err->msg_parm.i[0] = msg_code;
    +    msgtext = err->jpeg_message_table[0];
    +  }
    +
    +  /* Check for string parameter, as indicated by %s in the message text */
    +  isstring = FALSE;
    +  msgptr = msgtext;
    +  while ((ch = *msgptr++) != '\0') {
    +    if (ch == '%') {
    +      if (*msgptr == 's') isstring = TRUE;
    +      break;
    +    }
    +  }
    +
    +  /* Format the message into the passed buffer */
    +  if (isstring)
    +    /* Buffer size is JMSG_LENGTH_MAX, quietly truncate on overflow */
    +    (void) jio_snprintf(buffer, JMSG_LENGTH_MAX, msgtext, err->msg_parm.s);
    +  else
    +    /* Buffer size is JMSG_LENGTH_MAX, quietly truncate on overflow */
    +    (void) jio_snprintf(buffer, JMSG_LENGTH_MAX, msgtext,
    +                        err->msg_parm.i[0], err->msg_parm.i[1],
    +                        err->msg_parm.i[2], err->msg_parm.i[3],
    +                        err->msg_parm.i[4], err->msg_parm.i[5],
    +                        err->msg_parm.i[6], err->msg_parm.i[7]);
    +#else /* SPLASHSCREEN */
    +        *buffer = '\0';
    +#endif /* SPLASHSCREEN */
    +}
    +
    +
    +/*
    + * Reset error state variables at start of a new image.
    + * This is called during compression startup to reset trace/error
    + * processing to default state, without losing any application-specific
    + * method pointers.  An application might possibly want to override
    + * this method if it has additional error processing state.
    + */
    +
    +METHODDEF(void)
    +reset_error_mgr (j_common_ptr cinfo)
    +{
    +  cinfo->err->num_warnings = 0;
    +  /* trace_level is not reset since it is an application-supplied parameter */
    +  cinfo->err->msg_code = 0;     /* may be useful as a flag for "no error" */
    +}
    +
    +
    +/*
    + * Fill in the standard error-handling methods in a jpeg_error_mgr object.
    + * Typical call is:
    + *      struct jpeg_compress_struct cinfo;
    + *      struct jpeg_error_mgr err;
    + *
    + *      cinfo.err = jpeg_std_error(&err);
    + * after which the application may override some of the methods.
    + */
    +
    +GLOBAL(struct jpeg_error_mgr *)
    +jpeg_std_error (struct jpeg_error_mgr * err)
    +{
    +  err->error_exit = error_exit;
    +  err->emit_message = emit_message;
    +  err->output_message = output_message;
    +  err->format_message = format_message;
    +  err->reset_error_mgr = reset_error_mgr;
    +
    +  err->trace_level = 0;         /* default = no tracing */
    +  err->num_warnings = 0;        /* no warnings emitted yet */
    +  err->msg_code = 0;            /* may be useful as a flag for "no error" */
    +
    +  /* Initialize message table pointers */
    +  err->jpeg_message_table = jpeg_std_message_table;
    +  err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
    +
    +  err->addon_message_table = NULL;
    +  err->first_addon_message = 0; /* for safety */
    +  err->last_addon_message = 0;
    +
    +  return err;
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jerror.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jerror.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jerror.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jerror.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,295 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jerror.h
    + *
    + * Copyright (C) 1994-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file defines the error and message codes for the JPEG library.
    + * Edit this file to add new codes, or to translate the message strings to
    + * some other language.
    + * A set of error-reporting macros are defined too.  Some applications using
    + * the JPEG library may wish to include this file to get the error codes
    + * and/or the macros.
    + */
    +
    +/*
    + * To define the enum list of message codes, include this file without
    + * defining macro JMESSAGE.  To create a message string table, include it
    + * again with a suitable JMESSAGE definition (see jerror.c for an example).
    + */
    +#ifndef JMESSAGE
    +#ifndef JERROR_H
    +/* First time through, define the enum list */
    +#define JMAKE_ENUM_LIST
    +#else
    +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
    +#define JMESSAGE(code,string)
    +#endif /* JERROR_H */
    +#endif /* JMESSAGE */
    +
    +#ifdef JMAKE_ENUM_LIST
    +
    +typedef enum {
    +
    +#define JMESSAGE(code,string)   code ,
    +
    +#endif /* JMAKE_ENUM_LIST */
    +
    +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
    +
    +/* For maintenance convenience, list is alphabetical by message code name */
    +JMESSAGE(JERR_ARITH_NOTIMPL,
    +         "Sorry, there are legal restrictions on arithmetic coding")
    +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
    +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
    +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
    +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
    +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
    +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
    +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
    +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
    +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
    +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
    +JMESSAGE(JERR_BAD_LIB_VERSION,
    +         "Wrong JPEG library version: library is %d, caller expects %d")
    +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
    +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
    +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
    +JMESSAGE(JERR_BAD_PROGRESSION,
    +         "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
    +JMESSAGE(JERR_BAD_PROG_SCRIPT,
    +         "Invalid progressive parameters at scan script entry %d")
    +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
    +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
    +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
    +JMESSAGE(JERR_BAD_STRUCT_SIZE,
    +         "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
    +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
    +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
    +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
    +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
    +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
    +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
    +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
    +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
    +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
    +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
    +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
    +JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
    +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
    +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
    +JMESSAGE(JERR_FILE_READ, "Input file read error")
    +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
    +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
    +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
    +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
    +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
    +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
    +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
    +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
    +         "Cannot transcode due to multiple use of quantization table %d")
    +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
    +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
    +JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
    +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
    +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
    +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
    +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
    +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
    +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
    +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
    +JMESSAGE(JERR_QUANT_COMPONENTS,
    +         "Cannot quantize more than %d color components")
    +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
    +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
    +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
    +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
    +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
    +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
    +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
    +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
    +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
    +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
    +JMESSAGE(JERR_TFILE_WRITE,
    +         "Write failed on temporary file --- out of disk space?")
    +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
    +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
    +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
    +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
    +JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
    +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
    +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
    +JMESSAGE(JMSG_VERSION, JVERSION)
    +JMESSAGE(JTRC_16BIT_TABLES,
    +         "Caution: quantization tables are too coarse for baseline JPEG")
    +JMESSAGE(JTRC_ADOBE,
    +         "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
    +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
    +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
    +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
    +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
    +JMESSAGE(JTRC_DQT, "Define Quantization Table %d  precision %d")
    +JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
    +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
    +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
    +JMESSAGE(JTRC_EOI, "End Of Image")
    +JMESSAGE(JTRC_HUFFBITS, "        %3d %3d %3d %3d %3d %3d %3d %3d")
    +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d  %d")
    +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
    +         "Warning: thumbnail image size does not match data length %u")
    +JMESSAGE(JTRC_JFIF_EXTENSION,
    +         "JFIF extension marker: type 0x%02x, length %u")
    +JMESSAGE(JTRC_JFIF_THUMBNAIL, "    with %d x %d thumbnail image")
    +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
    +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
    +JMESSAGE(JTRC_QUANTVALS, "        %4u %4u %4u %4u %4u %4u %4u %4u")
    +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
    +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
    +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
    +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
    +JMESSAGE(JTRC_RST, "RST%d")
    +JMESSAGE(JTRC_SMOOTH_NOTIMPL,
    +         "Smoothing not supported with nonstandard sampling ratios")
    +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
    +JMESSAGE(JTRC_SOF_COMPONENT, "    Component %d: %dhx%dv q=%d")
    +JMESSAGE(JTRC_SOI, "Start of Image")
    +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
    +JMESSAGE(JTRC_SOS_COMPONENT, "    Component %d: dc=%d ac=%d")
    +JMESSAGE(JTRC_SOS_PARAMS, "  Ss=%d, Se=%d, Ah=%d, Al=%d")
    +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
    +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
    +JMESSAGE(JTRC_THUMB_JPEG,
    +         "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
    +JMESSAGE(JTRC_THUMB_PALETTE,
    +         "JFIF extension marker: palette thumbnail image, length %u")
    +JMESSAGE(JTRC_THUMB_RGB,
    +         "JFIF extension marker: RGB thumbnail image, length %u")
    +JMESSAGE(JTRC_UNKNOWN_IDS,
    +         "Unrecognized component IDs %d %d %d, assuming YCbCr")
    +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
    +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
    +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
    +JMESSAGE(JWRN_BOGUS_PROGRESSION,
    +         "Inconsistent progression sequence for component %d coefficient %d")
    +JMESSAGE(JWRN_EXTRANEOUS_DATA,
    +         "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
    +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
    +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
    +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
    +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
    +JMESSAGE(JWRN_MUST_RESYNC,
    +         "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
    +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
    +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
    +
    +#ifdef JMAKE_ENUM_LIST
    +
    +  JMSG_LASTMSGCODE
    +} J_MESSAGE_CODE;
    +
    +#undef JMAKE_ENUM_LIST
    +#endif /* JMAKE_ENUM_LIST */
    +
    +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
    +#undef JMESSAGE
    +
    +
    +#ifndef JERROR_H
    +#define JERROR_H
    +
    +/* Macros to simplify using the error and trace message stuff */
    +/* The first parameter is either type of cinfo pointer */
    +
    +/* Fatal errors (print message and exit) */
    +#define ERREXIT(cinfo,code)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +#define ERREXIT1(cinfo,code,p1)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +#define ERREXIT2(cinfo,code,p1,p2)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (cinfo)->err->msg_parm.i[1] = (p2), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +#define ERREXIT3(cinfo,code,p1,p2,p3)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (cinfo)->err->msg_parm.i[1] = (p2), \
    +   (cinfo)->err->msg_parm.i[2] = (p3), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +#define ERREXIT4(cinfo,code,p1,p2,p3,p4)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (cinfo)->err->msg_parm.i[1] = (p2), \
    +   (cinfo)->err->msg_parm.i[2] = (p3), \
    +   (cinfo)->err->msg_parm.i[3] = (p4), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +#define ERREXITS(cinfo,code,str)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
    +   (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
    +
    +#define MAKESTMT(stuff)         do { stuff } while (0)
    +
    +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
    +#define WARNMS(cinfo,code)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
    +#define WARNMS1(cinfo,code,p1)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
    +#define WARNMS2(cinfo,code,p1,p2)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (cinfo)->err->msg_parm.i[1] = (p2), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
    +
    +/* Informational/debugging messages */
    +#define TRACEMS(cinfo,lvl,code)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
    +#define TRACEMS1(cinfo,lvl,code,p1)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
    +#define TRACEMS2(cinfo,lvl,code,p1,p2)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   (cinfo)->err->msg_parm.i[0] = (p1), \
    +   (cinfo)->err->msg_parm.i[1] = (p2), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
    +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3)  \
    +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
    +           _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
    +           (cinfo)->err->msg_code = (code); \
    +           (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
    +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4)  \
    +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
    +           _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
    +           (cinfo)->err->msg_code = (code); \
    +           (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
    +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5)  \
    +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
    +           _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
    +           _mp[4] = (p5); \
    +           (cinfo)->err->msg_code = (code); \
    +           (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
    +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8)  \
    +  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
    +           _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
    +           _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
    +           (cinfo)->err->msg_code = (code); \
    +           (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
    +#define TRACEMSS(cinfo,lvl,code,str)  \
    +  ((cinfo)->err->msg_code = (code), \
    +   strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
    +   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
    +
    +#endif /* JERROR_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctflt.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctflt.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctflt.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctflt.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,172 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jfdctflt.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a floating-point implementation of the
    + * forward DCT (Discrete Cosine Transform).
    + *
    + * This implementation should be more accurate than either of the integer
    + * DCT implementations.  However, it may not give the same results on all
    + * machines because of differences in roundoff behavior.  Speed will depend
    + * on the hardware's floating point capacity.
    + *
    + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
    + * on each column.  Direct algorithms are also available, but they are
    + * much more complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
    + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
    + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
    + * JPEG textbook (see REFERENCES section in file README).  The following code
    + * is based directly on figure 4-8 in P&M.
    + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
    + * possible to arrange the computation so that many of the multiplies are
    + * simple scalings of the final outputs.  These multiplies can then be
    + * folded into the multiplications or divisions by the JPEG quantization
    + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
    + * to be done in the DCT itself.
    + * The primary disadvantage of this method is that with a fixed-point
    + * implementation, accuracy is lost due to imprecise representation of the
    + * scaled quantization values.  However, that problem does not arise if
    + * we use floating point arithmetic.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_FLOAT_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/*
    + * Perform the forward DCT on one block of samples.
    + */
    +
    +GLOBAL(void)
    +jpeg_fdct_float (FAST_FLOAT * data)
    +{
    +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
    +  FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
    +  FAST_FLOAT *dataptr;
    +  int ctr;
    +
    +  /* Pass 1: process rows. */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[0] + dataptr[7];
    +    tmp7 = dataptr[0] - dataptr[7];
    +    tmp1 = dataptr[1] + dataptr[6];
    +    tmp6 = dataptr[1] - dataptr[6];
    +    tmp2 = dataptr[2] + dataptr[5];
    +    tmp5 = dataptr[2] - dataptr[5];
    +    tmp3 = dataptr[3] + dataptr[4];
    +    tmp4 = dataptr[3] - dataptr[4];
    +
    +    /* Even part */
    +
    +    tmp10 = tmp0 + tmp3;        /* phase 2 */
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[0] = tmp10 + tmp11; /* phase 3 */
    +    dataptr[4] = tmp10 - tmp11;
    +
    +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
    +    dataptr[2] = tmp13 + z1;    /* phase 5 */
    +    dataptr[6] = tmp13 - z1;
    +
    +    /* Odd part */
    +
    +    tmp10 = tmp4 + tmp5;        /* phase 2 */
    +    tmp11 = tmp5 + tmp6;
    +    tmp12 = tmp6 + tmp7;
    +
    +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
    +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
    +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
    +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
    +
    +    z11 = tmp7 + z3;            /* phase 5 */
    +    z13 = tmp7 - z3;
    +
    +    dataptr[5] = z13 + z2;      /* phase 6 */
    +    dataptr[3] = z13 - z2;
    +    dataptr[1] = z11 + z4;
    +    dataptr[7] = z11 - z4;
    +
    +    dataptr += DCTSIZE;         /* advance pointer to next row */
    +  }
    +
    +  /* Pass 2: process columns. */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
    +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
    +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
    +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
    +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
    +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
    +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
    +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
    +
    +    /* Even part */
    +
    +    tmp10 = tmp0 + tmp3;        /* phase 2 */
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
    +    dataptr[DCTSIZE*4] = tmp10 - tmp11;
    +
    +    z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
    +    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
    +    dataptr[DCTSIZE*6] = tmp13 - z1;
    +
    +    /* Odd part */
    +
    +    tmp10 = tmp4 + tmp5;        /* phase 2 */
    +    tmp11 = tmp5 + tmp6;
    +    tmp12 = tmp6 + tmp7;
    +
    +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    +    z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
    +    z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
    +    z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
    +    z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
    +
    +    z11 = tmp7 + z3;            /* phase 5 */
    +    z13 = tmp7 - z3;
    +
    +    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
    +    dataptr[DCTSIZE*3] = z13 - z2;
    +    dataptr[DCTSIZE*1] = z11 + z4;
    +    dataptr[DCTSIZE*7] = z11 - z4;
    +
    +    dataptr++;                  /* advance pointer to next column */
    +  }
    +}
    +
    +#endif /* DCT_FLOAT_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctfst.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctfst.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctfst.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctfst.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,228 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jfdctfst.c
    + *
    + * Copyright (C) 1994-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a fast, not so accurate integer implementation of the
    + * forward DCT (Discrete Cosine Transform).
    + *
    + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
    + * on each column.  Direct algorithms are also available, but they are
    + * much more complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
    + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
    + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
    + * JPEG textbook (see REFERENCES section in file README).  The following code
    + * is based directly on figure 4-8 in P&M.
    + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
    + * possible to arrange the computation so that many of the multiplies are
    + * simple scalings of the final outputs.  These multiplies can then be
    + * folded into the multiplications or divisions by the JPEG quantization
    + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
    + * to be done in the DCT itself.
    + * The primary disadvantage of this method is that with fixed-point math,
    + * accuracy is lost due to imprecise representation of the scaled
    + * quantization values.  The smaller the quantization table entry, the less
    + * precise the scaled value, so this implementation does worse with high-
    + * quality-setting files than with low-quality ones.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_IFAST_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/* Scaling decisions are generally the same as in the LL&M algorithm;
    + * see jfdctint.c for more details.  However, we choose to descale
    + * (right shift) multiplication products as soon as they are formed,
    + * rather than carrying additional fractional bits into subsequent additions.
    + * This compromises accuracy slightly, but it lets us save a few shifts.
    + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
    + * everywhere except in the multiplications proper; this saves a good deal
    + * of work on 16-bit-int machines.
    + *
    + * Again to save a few shifts, the intermediate results between pass 1 and
    + * pass 2 are not upscaled, but are represented only to integral precision.
    + *
    + * A final compromise is to represent the multiplicative constants to only
    + * 8 fractional bits, rather than 13.  This saves some shifting work on some
    + * machines, and may also reduce the cost of multiplication (since there
    + * are fewer one-bits in the constants).
    + */
    +
    +#define CONST_BITS  8
    +
    +
    +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
    + * causing a lot of useless floating-point operations at run time.
    + * To get around this we use the following pre-calculated constants.
    + * If you change CONST_BITS you may want to add appropriate values.
    + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
    + */
    +
    +#if CONST_BITS == 8
    +#define FIX_0_382683433  ((INT32)   98)         /* FIX(0.382683433) */
    +#define FIX_0_541196100  ((INT32)  139)         /* FIX(0.541196100) */
    +#define FIX_0_707106781  ((INT32)  181)         /* FIX(0.707106781) */
    +#define FIX_1_306562965  ((INT32)  334)         /* FIX(1.306562965) */
    +#else
    +#define FIX_0_382683433  FIX(0.382683433)
    +#define FIX_0_541196100  FIX(0.541196100)
    +#define FIX_0_707106781  FIX(0.707106781)
    +#define FIX_1_306562965  FIX(1.306562965)
    +#endif
    +
    +
    +/* We can gain a little more speed, with a further compromise in accuracy,
    + * by omitting the addition in a descaling shift.  This yields an incorrectly
    + * rounded result half the time...
    + */
    +
    +#ifndef USE_ACCURATE_ROUNDING
    +#undef DESCALE
    +#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
    +#endif
    +
    +
    +/* Multiply a DCTELEM variable by an INT32 constant, and immediately
    + * descale to yield a DCTELEM result.
    + */
    +
    +#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
    +
    +
    +/*
    + * Perform the forward DCT on one block of samples.
    + */
    +
    +GLOBAL(void)
    +jpeg_fdct_ifast (DCTELEM * data)
    +{
    +  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    +  DCTELEM tmp10, tmp11, tmp12, tmp13;
    +  DCTELEM z1, z2, z3, z4, z5, z11, z13;
    +  DCTELEM *dataptr;
    +  int ctr;
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process rows. */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[0] + dataptr[7];
    +    tmp7 = dataptr[0] - dataptr[7];
    +    tmp1 = dataptr[1] + dataptr[6];
    +    tmp6 = dataptr[1] - dataptr[6];
    +    tmp2 = dataptr[2] + dataptr[5];
    +    tmp5 = dataptr[2] - dataptr[5];
    +    tmp3 = dataptr[3] + dataptr[4];
    +    tmp4 = dataptr[3] - dataptr[4];
    +
    +    /* Even part */
    +
    +    tmp10 = tmp0 + tmp3;        /* phase 2 */
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[0] = tmp10 + tmp11; /* phase 3 */
    +    dataptr[4] = tmp10 - tmp11;
    +
    +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
    +    dataptr[2] = tmp13 + z1;    /* phase 5 */
    +    dataptr[6] = tmp13 - z1;
    +
    +    /* Odd part */
    +
    +    tmp10 = tmp4 + tmp5;        /* phase 2 */
    +    tmp11 = tmp5 + tmp6;
    +    tmp12 = tmp6 + tmp7;
    +
    +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    +    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
    +    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
    +    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
    +    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
    +
    +    z11 = tmp7 + z3;            /* phase 5 */
    +    z13 = tmp7 - z3;
    +
    +    dataptr[5] = z13 + z2;      /* phase 6 */
    +    dataptr[3] = z13 - z2;
    +    dataptr[1] = z11 + z4;
    +    dataptr[7] = z11 - z4;
    +
    +    dataptr += DCTSIZE;         /* advance pointer to next row */
    +  }
    +
    +  /* Pass 2: process columns. */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
    +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
    +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
    +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
    +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
    +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
    +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
    +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
    +
    +    /* Even part */
    +
    +    tmp10 = tmp0 + tmp3;        /* phase 2 */
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
    +    dataptr[DCTSIZE*4] = tmp10 - tmp11;
    +
    +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
    +    dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
    +    dataptr[DCTSIZE*6] = tmp13 - z1;
    +
    +    /* Odd part */
    +
    +    tmp10 = tmp4 + tmp5;        /* phase 2 */
    +    tmp11 = tmp5 + tmp6;
    +    tmp12 = tmp6 + tmp7;
    +
    +    /* The rotator is modified from fig 4-8 to avoid extra negations. */
    +    z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
    +    z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
    +    z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
    +    z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
    +
    +    z11 = tmp7 + z3;            /* phase 5 */
    +    z13 = tmp7 - z3;
    +
    +    dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
    +    dataptr[DCTSIZE*3] = z13 - z2;
    +    dataptr[DCTSIZE*1] = z11 + z4;
    +    dataptr[DCTSIZE*7] = z11 - z4;
    +
    +    dataptr++;                  /* advance pointer to next column */
    +  }
    +}
    +
    +#endif /* DCT_IFAST_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctint.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctint.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jfdctint.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jfdctint.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,287 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jfdctint.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a slow-but-accurate integer implementation of the
    + * forward DCT (Discrete Cosine Transform).
    + *
    + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
    + * on each column.  Direct algorithms are also available, but they are
    + * much more complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on an algorithm described in
    + *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
    + *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
    + *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
    + * The primary algorithm described there uses 11 multiplies and 29 adds.
    + * We use their alternate method with 12 multiplies and 32 adds.
    + * The advantage of this method is that no data path contains more than one
    + * multiplication; this allows a very simple and accurate implementation in
    + * scaled fixed-point arithmetic, with a minimal number of shifts.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_ISLOW_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/*
    + * The poop on this scaling stuff is as follows:
    + *
    + * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
    + * larger than the true DCT outputs.  The final outputs are therefore
    + * a factor of N larger than desired; since N=8 this can be cured by
    + * a simple right shift at the end of the algorithm.  The advantage of
    + * this arrangement is that we save two multiplications per 1-D DCT,
    + * because the y0 and y4 outputs need not be divided by sqrt(N).
    + * In the IJG code, this factor of 8 is removed by the quantization step
    + * (in jcdctmgr.c), NOT in this module.
    + *
    + * We have to do addition and subtraction of the integer inputs, which
    + * is no problem, and multiplication by fractional constants, which is
    + * a problem to do in integer arithmetic.  We multiply all the constants
    + * by CONST_SCALE and convert them to integer constants (thus retaining
    + * CONST_BITS bits of precision in the constants).  After doing a
    + * multiplication we have to divide the product by CONST_SCALE, with proper
    + * rounding, to produce the correct output.  This division can be done
    + * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
    + * as long as possible so that partial sums can be added together with
    + * full fractional precision.
    + *
    + * The outputs of the first pass are scaled up by PASS1_BITS bits so that
    + * they are represented to better-than-integral precision.  These outputs
    + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
    + * with the recommended scaling.  (For 12-bit sample data, the intermediate
    + * array is INT32 anyway.)
    + *
    + * To avoid overflow of the 32-bit intermediate results in pass 2, we must
    + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
    + * shows that the values given below are the most effective.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define CONST_BITS  13
    +#define PASS1_BITS  2
    +#else
    +#define CONST_BITS  13
    +#define PASS1_BITS  1           /* lose a little precision to avoid overflow */
    +#endif
    +
    +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
    + * causing a lot of useless floating-point operations at run time.
    + * To get around this we use the following pre-calculated constants.
    + * If you change CONST_BITS you may want to add appropriate values.
    + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
    + */
    +
    +#if CONST_BITS == 13
    +#define FIX_0_298631336  ((INT32)  2446)        /* FIX(0.298631336) */
    +#define FIX_0_390180644  ((INT32)  3196)        /* FIX(0.390180644) */
    +#define FIX_0_541196100  ((INT32)  4433)        /* FIX(0.541196100) */
    +#define FIX_0_765366865  ((INT32)  6270)        /* FIX(0.765366865) */
    +#define FIX_0_899976223  ((INT32)  7373)        /* FIX(0.899976223) */
    +#define FIX_1_175875602  ((INT32)  9633)        /* FIX(1.175875602) */
    +#define FIX_1_501321110  ((INT32)  12299)       /* FIX(1.501321110) */
    +#define FIX_1_847759065  ((INT32)  15137)       /* FIX(1.847759065) */
    +#define FIX_1_961570560  ((INT32)  16069)       /* FIX(1.961570560) */
    +#define FIX_2_053119869  ((INT32)  16819)       /* FIX(2.053119869) */
    +#define FIX_2_562915447  ((INT32)  20995)       /* FIX(2.562915447) */
    +#define FIX_3_072711026  ((INT32)  25172)       /* FIX(3.072711026) */
    +#else
    +#define FIX_0_298631336  FIX(0.298631336)
    +#define FIX_0_390180644  FIX(0.390180644)
    +#define FIX_0_541196100  FIX(0.541196100)
    +#define FIX_0_765366865  FIX(0.765366865)
    +#define FIX_0_899976223  FIX(0.899976223)
    +#define FIX_1_175875602  FIX(1.175875602)
    +#define FIX_1_501321110  FIX(1.501321110)
    +#define FIX_1_847759065  FIX(1.847759065)
    +#define FIX_1_961570560  FIX(1.961570560)
    +#define FIX_2_053119869  FIX(2.053119869)
    +#define FIX_2_562915447  FIX(2.562915447)
    +#define FIX_3_072711026  FIX(3.072711026)
    +#endif
    +
    +
    +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
    + * For 8-bit samples with the recommended scaling, all the variable
    + * and constant values involved are no more than 16 bits wide, so a
    + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
    + * For 12-bit samples, a full 32-bit multiplication will be needed.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
    +#else
    +#define MULTIPLY(var,const)  ((var) * (const))
    +#endif
    +
    +
    +/*
    + * Perform the forward DCT on one block of samples.
    + */
    +
    +GLOBAL(void)
    +jpeg_fdct_islow (DCTELEM * data)
    +{
    +  INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    +  INT32 tmp10, tmp11, tmp12, tmp13;
    +  INT32 z1, z2, z3, z4, z5;
    +  DCTELEM *dataptr;
    +  int ctr;
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process rows. */
    +  /* Note results are scaled up by sqrt(8) compared to a true DCT; */
    +  /* furthermore, we scale the results by 2**PASS1_BITS. */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[0] + dataptr[7];
    +    tmp7 = dataptr[0] - dataptr[7];
    +    tmp1 = dataptr[1] + dataptr[6];
    +    tmp6 = dataptr[1] - dataptr[6];
    +    tmp2 = dataptr[2] + dataptr[5];
    +    tmp5 = dataptr[2] - dataptr[5];
    +    tmp3 = dataptr[3] + dataptr[4];
    +    tmp4 = dataptr[3] - dataptr[4];
    +
    +    /* Even part per LL&M figure 1 --- note that published figure is faulty;
    +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
    +     */
    +
    +    tmp10 = tmp0 + tmp3;
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
    +    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
    +
    +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
    +    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
    +                                   CONST_BITS-PASS1_BITS);
    +    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
    +                                   CONST_BITS-PASS1_BITS);
    +
    +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
    +     * cK represents cos(K*pi/16).
    +     * i0..i3 in the paper are tmp4..tmp7 here.
    +     */
    +
    +    z1 = tmp4 + tmp7;
    +    z2 = tmp5 + tmp6;
    +    z3 = tmp4 + tmp6;
    +    z4 = tmp5 + tmp7;
    +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
    +
    +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
    +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
    +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
    +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
    +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
    +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
    +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
    +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
    +
    +    z3 += z5;
    +    z4 += z5;
    +
    +    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
    +    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
    +    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
    +    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
    +
    +    dataptr += DCTSIZE;         /* advance pointer to next row */
    +  }
    +
    +  /* Pass 2: process columns.
    +   * We remove the PASS1_BITS scaling, but leave the results scaled up
    +   * by an overall factor of 8.
    +   */
    +
    +  dataptr = data;
    +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
    +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
    +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
    +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
    +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
    +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
    +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
    +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
    +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
    +
    +    /* Even part per LL&M figure 1 --- note that published figure is faulty;
    +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
    +     */
    +
    +    tmp10 = tmp0 + tmp3;
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
    +    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
    +
    +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
    +    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
    +                                           CONST_BITS+PASS1_BITS);
    +    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
    +                                           CONST_BITS+PASS1_BITS);
    +
    +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
    +     * cK represents cos(K*pi/16).
    +     * i0..i3 in the paper are tmp4..tmp7 here.
    +     */
    +
    +    z1 = tmp4 + tmp7;
    +    z2 = tmp5 + tmp6;
    +    z3 = tmp4 + tmp6;
    +    z4 = tmp5 + tmp7;
    +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
    +
    +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
    +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
    +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
    +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
    +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
    +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
    +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
    +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
    +
    +    z3 += z5;
    +    z4 += z5;
    +
    +    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
    +                                           CONST_BITS+PASS1_BITS);
    +    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
    +                                           CONST_BITS+PASS1_BITS);
    +    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
    +                                           CONST_BITS+PASS1_BITS);
    +    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
    +                                           CONST_BITS+PASS1_BITS);
    +
    +    dataptr++;                  /* advance pointer to next column */
    +  }
    +}
    +
    +#endif /* DCT_ISLOW_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctflt.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctflt.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctflt.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctflt.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,246 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jidctflt.c
    + *
    + * Copyright (C) 1994-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a floating-point implementation of the
    + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
    + * must also perform dequantization of the input coefficients.
    + *
    + * This implementation should be more accurate than either of the integer
    + * IDCT implementations.  However, it may not give the same results on all
    + * machines because of differences in roundoff behavior.  Speed will depend
    + * on the hardware's floating point capacity.
    + *
    + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
    + * on each row (or vice versa, but it's more convenient to emit a row at
    + * a time).  Direct algorithms are also available, but they are much more
    + * complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
    + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
    + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
    + * JPEG textbook (see REFERENCES section in file README).  The following code
    + * is based directly on figure 4-8 in P&M.
    + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
    + * possible to arrange the computation so that many of the multiplies are
    + * simple scalings of the final outputs.  These multiplies can then be
    + * folded into the multiplications or divisions by the JPEG quantization
    + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
    + * to be done in the DCT itself.
    + * The primary disadvantage of this method is that with a fixed-point
    + * implementation, accuracy is lost due to imprecise representation of the
    + * scaled quantization values.  However, that problem does not arise if
    + * we use floating point arithmetic.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_FLOAT_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/* Dequantize a coefficient by multiplying it by the multiplier-table
    + * entry; produce a float result.
    + */
    +
    +#define DEQUANTIZE(coef,quantval)  (((FAST_FLOAT) (coef)) * (quantval))
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                 JCOEFPTR coef_block,
    +                 JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    +  FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
    +  FAST_FLOAT z5, z10, z11, z12, z13;
    +  JCOEFPTR inptr;
    +  FLOAT_MULT_TYPE * quantptr;
    +  FAST_FLOAT * wsptr;
    +  JSAMPROW outptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  int ctr;
    +  FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process columns from input, store into work array. */
    +
    +  inptr = coef_block;
    +  quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
    +  wsptr = workspace;
    +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
    +    /* Due to quantization, we will usually find that many of the input
    +     * coefficients are zero, especially the AC terms.  We can exploit this
    +     * by short-circuiting the IDCT calculation for any column in which all
    +     * the AC terms are zero.  In that case each output is equal to the
    +     * DC coefficient (with scale factor as needed).
    +     * With typical images and quantization tables, half or more of the
    +     * column DCT calculations can be simplified this way.
    +     */
    +
    +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
    +        inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
    +        inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
    +        inptr[DCTSIZE*7] == 0) {
    +      /* AC terms all zero */
    +      FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +
    +      wsptr[DCTSIZE*0] = dcval;
    +      wsptr[DCTSIZE*1] = dcval;
    +      wsptr[DCTSIZE*2] = dcval;
    +      wsptr[DCTSIZE*3] = dcval;
    +      wsptr[DCTSIZE*4] = dcval;
    +      wsptr[DCTSIZE*5] = dcval;
    +      wsptr[DCTSIZE*6] = dcval;
    +      wsptr[DCTSIZE*7] = dcval;
    +
    +      inptr++;                  /* advance pointers to next column */
    +      quantptr++;
    +      wsptr++;
    +      continue;
    +    }
    +
    +    /* Even part */
    +
    +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
    +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
    +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
    +
    +    tmp10 = tmp0 + tmp2;        /* phase 3 */
    +    tmp11 = tmp0 - tmp2;
    +
    +    tmp13 = tmp1 + tmp3;        /* phases 5-3 */
    +    tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
    +
    +    tmp0 = tmp10 + tmp13;       /* phase 2 */
    +    tmp3 = tmp10 - tmp13;
    +    tmp1 = tmp11 + tmp12;
    +    tmp2 = tmp11 - tmp12;
    +
    +    /* Odd part */
    +
    +    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
    +    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
    +    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
    +    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
    +
    +    z13 = tmp6 + tmp5;          /* phase 6 */
    +    z10 = tmp6 - tmp5;
    +    z11 = tmp4 + tmp7;
    +    z12 = tmp4 - tmp7;
    +
    +    tmp7 = z11 + z13;           /* phase 5 */
    +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
    +
    +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
    +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
    +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
    +
    +    tmp6 = tmp12 - tmp7;        /* phase 2 */
    +    tmp5 = tmp11 - tmp6;
    +    tmp4 = tmp10 + tmp5;
    +
    +    wsptr[DCTSIZE*0] = tmp0 + tmp7;
    +    wsptr[DCTSIZE*7] = tmp0 - tmp7;
    +    wsptr[DCTSIZE*1] = tmp1 + tmp6;
    +    wsptr[DCTSIZE*6] = tmp1 - tmp6;
    +    wsptr[DCTSIZE*2] = tmp2 + tmp5;
    +    wsptr[DCTSIZE*5] = tmp2 - tmp5;
    +    wsptr[DCTSIZE*4] = tmp3 + tmp4;
    +    wsptr[DCTSIZE*3] = tmp3 - tmp4;
    +
    +    inptr++;                    /* advance pointers to next column */
    +    quantptr++;
    +    wsptr++;
    +  }
    +
    +  /* Pass 2: process rows from work array, store into output array. */
    +  /* Note that we must descale the results by a factor of 8 == 2**3. */
    +
    +  wsptr = workspace;
    +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
    +    outptr = output_buf[ctr] + output_col;
    +    /* Rows of zeroes can be exploited in the same way as we did with columns.
    +     * However, the column calculation has created many nonzero AC terms, so
    +     * the simplification applies less often (typically 5% to 10% of the time).
    +     * And testing floats for zero is relatively expensive, so we don't bother.
    +     */
    +
    +    /* Even part */
    +
    +    tmp10 = wsptr[0] + wsptr[4];
    +    tmp11 = wsptr[0] - wsptr[4];
    +
    +    tmp13 = wsptr[2] + wsptr[6];
    +    tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
    +
    +    tmp0 = tmp10 + tmp13;
    +    tmp3 = tmp10 - tmp13;
    +    tmp1 = tmp11 + tmp12;
    +    tmp2 = tmp11 - tmp12;
    +
    +    /* Odd part */
    +
    +    z13 = wsptr[5] + wsptr[3];
    +    z10 = wsptr[5] - wsptr[3];
    +    z11 = wsptr[1] + wsptr[7];
    +    z12 = wsptr[1] - wsptr[7];
    +
    +    tmp7 = z11 + z13;
    +    tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
    +
    +    z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
    +    tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
    +    tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
    +
    +    tmp6 = tmp12 - tmp7;
    +    tmp5 = tmp11 - tmp6;
    +    tmp4 = tmp10 + tmp5;
    +
    +    /* Final output stage: scale down by a factor of 8 and range-limit */
    +
    +    outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
    +                            & RANGE_MASK];
    +    outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
    +                            & RANGE_MASK];
    +    outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
    +                            & RANGE_MASK];
    +    outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
    +                            & RANGE_MASK];
    +    outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
    +                            & RANGE_MASK];
    +    outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
    +                            & RANGE_MASK];
    +    outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
    +                            & RANGE_MASK];
    +    outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
    +                            & RANGE_MASK];
    +
    +    wsptr += DCTSIZE;           /* advance pointer to next row */
    +  }
    +}
    +
    +#endif /* DCT_FLOAT_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctfst.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctfst.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctfst.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctfst.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,372 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jidctfst.c
    + *
    + * Copyright (C) 1994-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a fast, not so accurate integer implementation of the
    + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
    + * must also perform dequantization of the input coefficients.
    + *
    + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
    + * on each row (or vice versa, but it's more convenient to emit a row at
    + * a time).  Direct algorithms are also available, but they are much more
    + * complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on Arai, Agui, and Nakajima's algorithm for
    + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in
    + * Japanese, but the algorithm is described in the Pennebaker & Mitchell
    + * JPEG textbook (see REFERENCES section in file README).  The following code
    + * is based directly on figure 4-8 in P&M.
    + * While an 8-point DCT cannot be done in less than 11 multiplies, it is
    + * possible to arrange the computation so that many of the multiplies are
    + * simple scalings of the final outputs.  These multiplies can then be
    + * folded into the multiplications or divisions by the JPEG quantization
    + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds
    + * to be done in the DCT itself.
    + * The primary disadvantage of this method is that with fixed-point math,
    + * accuracy is lost due to imprecise representation of the scaled
    + * quantization values.  The smaller the quantization table entry, the less
    + * precise the scaled value, so this implementation does worse with high-
    + * quality-setting files than with low-quality ones.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_IFAST_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/* Scaling decisions are generally the same as in the LL&M algorithm;
    + * see jidctint.c for more details.  However, we choose to descale
    + * (right shift) multiplication products as soon as they are formed,
    + * rather than carrying additional fractional bits into subsequent additions.
    + * This compromises accuracy slightly, but it lets us save a few shifts.
    + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
    + * everywhere except in the multiplications proper; this saves a good deal
    + * of work on 16-bit-int machines.
    + *
    + * The dequantized coefficients are not integers because the AA&N scaling
    + * factors have been incorporated.  We represent them scaled up by PASS1_BITS,
    + * so that the first and second IDCT rounds have the same input scaling.
    + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
    + * avoid a descaling shift; this compromises accuracy rather drastically
    + * for small quantization table entries, but it saves a lot of shifts.
    + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
    + * so we use a much larger scaling factor to preserve accuracy.
    + *
    + * A final compromise is to represent the multiplicative constants to only
    + * 8 fractional bits, rather than 13.  This saves some shifting work on some
    + * machines, and may also reduce the cost of multiplication (since there
    + * are fewer one-bits in the constants).
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define CONST_BITS  8
    +#define PASS1_BITS  2
    +#else
    +#define CONST_BITS  8
    +#define PASS1_BITS  1           /* lose a little precision to avoid overflow */
    +#endif
    +
    +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
    + * causing a lot of useless floating-point operations at run time.
    + * To get around this we use the following pre-calculated constants.
    + * If you change CONST_BITS you may want to add appropriate values.
    + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
    + */
    +
    +#if CONST_BITS == 8
    +#define FIX_1_082392200  ((INT32)  277)         /* FIX(1.082392200) */
    +#define FIX_1_414213562  ((INT32)  362)         /* FIX(1.414213562) */
    +#define FIX_1_847759065  ((INT32)  473)         /* FIX(1.847759065) */
    +#define FIX_2_613125930  ((INT32)  669)         /* FIX(2.613125930) */
    +#else
    +#define FIX_1_082392200  FIX(1.082392200)
    +#define FIX_1_414213562  FIX(1.414213562)
    +#define FIX_1_847759065  FIX(1.847759065)
    +#define FIX_2_613125930  FIX(2.613125930)
    +#endif
    +
    +
    +/* We can gain a little more speed, with a further compromise in accuracy,
    + * by omitting the addition in a descaling shift.  This yields an incorrectly
    + * rounded result half the time...
    + */
    +
    +#ifndef USE_ACCURATE_ROUNDING
    +#undef DESCALE
    +#define DESCALE(x,n)  RIGHT_SHIFT(x, n)
    +#endif
    +
    +
    +/* Multiply a DCTELEM variable by an INT32 constant, and immediately
    + * descale to yield a DCTELEM result.
    + */
    +
    +#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
    +
    +
    +/* Dequantize a coefficient by multiplying it by the multiplier-table
    + * entry; produce a DCTELEM result.  For 8-bit data a 16x16->16
    + * multiplication will do.  For 12-bit data, the multiplier table is
    + * declared INT32, so a 32-bit multiply will be used.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define DEQUANTIZE(coef,quantval)  (((IFAST_MULT_TYPE) (coef)) * (quantval))
    +#else
    +#define DEQUANTIZE(coef,quantval)  \
    +        DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
    +#endif
    +
    +
    +/* Like DESCALE, but applies to a DCTELEM and produces an int.
    + * We assume that int right shift is unsigned if INT32 right shift is.
    + */
    +
    +#ifdef RIGHT_SHIFT_IS_UNSIGNED
    +#define ISHIFT_TEMPS    DCTELEM ishift_temp;
    +#if BITS_IN_JSAMPLE == 8
    +#define DCTELEMBITS  16         /* DCTELEM may be 16 or 32 bits */
    +#else
    +#define DCTELEMBITS  32         /* DCTELEM must be 32 bits */
    +#endif
    +#define IRIGHT_SHIFT(x,shft)  \
    +    ((ishift_temp = (x)) < 0 ? \
    +     (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
    +     (ishift_temp >> (shft)))
    +#else
    +#define ISHIFT_TEMPS
    +#define IRIGHT_SHIFT(x,shft)    ((x) >> (shft))
    +#endif
    +
    +#ifdef USE_ACCURATE_ROUNDING
    +#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
    +#else
    +#define IDESCALE(x,n)  ((int) IRIGHT_SHIFT(x, n))
    +#endif
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                 JCOEFPTR coef_block,
    +                 JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    +  DCTELEM tmp10, tmp11, tmp12, tmp13;
    +  DCTELEM z5, z10, z11, z12, z13;
    +  JCOEFPTR inptr;
    +  IFAST_MULT_TYPE * quantptr;
    +  int * wsptr;
    +  JSAMPROW outptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  int ctr;
    +  int workspace[DCTSIZE2];      /* buffers data between passes */
    +  SHIFT_TEMPS                   /* for DESCALE */
    +  ISHIFT_TEMPS                  /* for IDESCALE */
    +
    +  /* Pass 1: process columns from input, store into work array. */
    +
    +  inptr = coef_block;
    +  quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
    +  wsptr = workspace;
    +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
    +    /* Due to quantization, we will usually find that many of the input
    +     * coefficients are zero, especially the AC terms.  We can exploit this
    +     * by short-circuiting the IDCT calculation for any column in which all
    +     * the AC terms are zero.  In that case each output is equal to the
    +     * DC coefficient (with scale factor as needed).
    +     * With typical images and quantization tables, half or more of the
    +     * column DCT calculations can be simplified this way.
    +     */
    +
    +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
    +        inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
    +        inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
    +        inptr[DCTSIZE*7] == 0) {
    +      /* AC terms all zero */
    +      int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +
    +      wsptr[DCTSIZE*0] = dcval;
    +      wsptr[DCTSIZE*1] = dcval;
    +      wsptr[DCTSIZE*2] = dcval;
    +      wsptr[DCTSIZE*3] = dcval;
    +      wsptr[DCTSIZE*4] = dcval;
    +      wsptr[DCTSIZE*5] = dcval;
    +      wsptr[DCTSIZE*6] = dcval;
    +      wsptr[DCTSIZE*7] = dcval;
    +
    +      inptr++;                  /* advance pointers to next column */
    +      quantptr++;
    +      wsptr++;
    +      continue;
    +    }
    +
    +    /* Even part */
    +
    +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
    +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
    +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
    +
    +    tmp10 = tmp0 + tmp2;        /* phase 3 */
    +    tmp11 = tmp0 - tmp2;
    +
    +    tmp13 = tmp1 + tmp3;        /* phases 5-3 */
    +    tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
    +
    +    tmp0 = tmp10 + tmp13;       /* phase 2 */
    +    tmp3 = tmp10 - tmp13;
    +    tmp1 = tmp11 + tmp12;
    +    tmp2 = tmp11 - tmp12;
    +
    +    /* Odd part */
    +
    +    tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
    +    tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
    +    tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
    +    tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
    +
    +    z13 = tmp6 + tmp5;          /* phase 6 */
    +    z10 = tmp6 - tmp5;
    +    z11 = tmp4 + tmp7;
    +    z12 = tmp4 - tmp7;
    +
    +    tmp7 = z11 + z13;           /* phase 5 */
    +    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
    +
    +    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
    +    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
    +    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
    +
    +    tmp6 = tmp12 - tmp7;        /* phase 2 */
    +    tmp5 = tmp11 - tmp6;
    +    tmp4 = tmp10 + tmp5;
    +
    +    wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
    +    wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
    +    wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
    +    wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
    +    wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
    +    wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
    +    wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
    +    wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
    +
    +    inptr++;                    /* advance pointers to next column */
    +    quantptr++;
    +    wsptr++;
    +  }
    +
    +  /* Pass 2: process rows from work array, store into output array. */
    +  /* Note that we must descale the results by a factor of 8 == 2**3, */
    +  /* and also undo the PASS1_BITS scaling. */
    +
    +  wsptr = workspace;
    +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
    +    outptr = output_buf[ctr] + output_col;
    +    /* Rows of zeroes can be exploited in the same way as we did with columns.
    +     * However, the column calculation has created many nonzero AC terms, so
    +     * the simplification applies less often (typically 5% to 10% of the time).
    +     * On machines with very fast multiplication, it's possible that the
    +     * test takes more time than it's worth.  In that case this section
    +     * may be commented out.
    +     */
    +
    +#ifndef NO_ZERO_ROW_TEST
    +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
    +        wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
    +      /* AC terms all zero */
    +      JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
    +                                  & RANGE_MASK];
    +
    +      outptr[0] = dcval;
    +      outptr[1] = dcval;
    +      outptr[2] = dcval;
    +      outptr[3] = dcval;
    +      outptr[4] = dcval;
    +      outptr[5] = dcval;
    +      outptr[6] = dcval;
    +      outptr[7] = dcval;
    +
    +      wsptr += DCTSIZE;         /* advance pointer to next row */
    +      continue;
    +    }
    +#endif
    +
    +    /* Even part */
    +
    +    tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
    +    tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
    +
    +    tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
    +    tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
    +            - tmp13;
    +
    +    tmp0 = tmp10 + tmp13;
    +    tmp3 = tmp10 - tmp13;
    +    tmp1 = tmp11 + tmp12;
    +    tmp2 = tmp11 - tmp12;
    +
    +    /* Odd part */
    +
    +    z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
    +    z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
    +    z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
    +    z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
    +
    +    tmp7 = z11 + z13;           /* phase 5 */
    +    tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
    +
    +    z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
    +    tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
    +    tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
    +
    +    tmp6 = tmp12 - tmp7;        /* phase 2 */
    +    tmp5 = tmp11 - tmp6;
    +    tmp4 = tmp10 + tmp5;
    +
    +    /* Final output stage: scale down by a factor of 8 and range-limit */
    +
    +    outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
    +                            & RANGE_MASK];
    +
    +    wsptr += DCTSIZE;           /* advance pointer to next row */
    +  }
    +}
    +
    +#endif /* DCT_IFAST_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctint.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctint.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctint.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctint.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,393 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jidctint.c
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains a slow-but-accurate integer implementation of the
    + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine
    + * must also perform dequantization of the input coefficients.
    + *
    + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
    + * on each row (or vice versa, but it's more convenient to emit a row at
    + * a time).  Direct algorithms are also available, but they are much more
    + * complex and seem not to be any faster when reduced to code.
    + *
    + * This implementation is based on an algorithm described in
    + *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
    + *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
    + *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
    + * The primary algorithm described there uses 11 multiplies and 29 adds.
    + * We use their alternate method with 12 multiplies and 32 adds.
    + * The advantage of this method is that no data path contains more than one
    + * multiplication; this allows a very simple and accurate implementation in
    + * scaled fixed-point arithmetic, with a minimal number of shifts.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef DCT_ISLOW_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/*
    + * The poop on this scaling stuff is as follows:
    + *
    + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
    + * larger than the true IDCT outputs.  The final outputs are therefore
    + * a factor of N larger than desired; since N=8 this can be cured by
    + * a simple right shift at the end of the algorithm.  The advantage of
    + * this arrangement is that we save two multiplications per 1-D IDCT,
    + * because the y0 and y4 inputs need not be divided by sqrt(N).
    + *
    + * We have to do addition and subtraction of the integer inputs, which
    + * is no problem, and multiplication by fractional constants, which is
    + * a problem to do in integer arithmetic.  We multiply all the constants
    + * by CONST_SCALE and convert them to integer constants (thus retaining
    + * CONST_BITS bits of precision in the constants).  After doing a
    + * multiplication we have to divide the product by CONST_SCALE, with proper
    + * rounding, to produce the correct output.  This division can be done
    + * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
    + * as long as possible so that partial sums can be added together with
    + * full fractional precision.
    + *
    + * The outputs of the first pass are scaled up by PASS1_BITS bits so that
    + * they are represented to better-than-integral precision.  These outputs
    + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
    + * with the recommended scaling.  (To scale up 12-bit sample data further, an
    + * intermediate INT32 array would be needed.)
    + *
    + * To avoid overflow of the 32-bit intermediate results in pass 2, we must
    + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis
    + * shows that the values given below are the most effective.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define CONST_BITS  13
    +#define PASS1_BITS  2
    +#else
    +#define CONST_BITS  13
    +#define PASS1_BITS  1           /* lose a little precision to avoid overflow */
    +#endif
    +
    +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
    + * causing a lot of useless floating-point operations at run time.
    + * To get around this we use the following pre-calculated constants.
    + * If you change CONST_BITS you may want to add appropriate values.
    + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
    + */
    +
    +#if CONST_BITS == 13
    +#define FIX_0_298631336  ((INT32)  2446)        /* FIX(0.298631336) */
    +#define FIX_0_390180644  ((INT32)  3196)        /* FIX(0.390180644) */
    +#define FIX_0_541196100  ((INT32)  4433)        /* FIX(0.541196100) */
    +#define FIX_0_765366865  ((INT32)  6270)        /* FIX(0.765366865) */
    +#define FIX_0_899976223  ((INT32)  7373)        /* FIX(0.899976223) */
    +#define FIX_1_175875602  ((INT32)  9633)        /* FIX(1.175875602) */
    +#define FIX_1_501321110  ((INT32)  12299)       /* FIX(1.501321110) */
    +#define FIX_1_847759065  ((INT32)  15137)       /* FIX(1.847759065) */
    +#define FIX_1_961570560  ((INT32)  16069)       /* FIX(1.961570560) */
    +#define FIX_2_053119869  ((INT32)  16819)       /* FIX(2.053119869) */
    +#define FIX_2_562915447  ((INT32)  20995)       /* FIX(2.562915447) */
    +#define FIX_3_072711026  ((INT32)  25172)       /* FIX(3.072711026) */
    +#else
    +#define FIX_0_298631336  FIX(0.298631336)
    +#define FIX_0_390180644  FIX(0.390180644)
    +#define FIX_0_541196100  FIX(0.541196100)
    +#define FIX_0_765366865  FIX(0.765366865)
    +#define FIX_0_899976223  FIX(0.899976223)
    +#define FIX_1_175875602  FIX(1.175875602)
    +#define FIX_1_501321110  FIX(1.501321110)
    +#define FIX_1_847759065  FIX(1.847759065)
    +#define FIX_1_961570560  FIX(1.961570560)
    +#define FIX_2_053119869  FIX(2.053119869)
    +#define FIX_2_562915447  FIX(2.562915447)
    +#define FIX_3_072711026  FIX(3.072711026)
    +#endif
    +
    +
    +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
    + * For 8-bit samples with the recommended scaling, all the variable
    + * and constant values involved are no more than 16 bits wide, so a
    + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
    + * For 12-bit samples, a full 32-bit multiplication will be needed.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
    +#else
    +#define MULTIPLY(var,const)  ((var) * (const))
    +#endif
    +
    +
    +/* Dequantize a coefficient by multiplying it by the multiplier-table
    + * entry; produce an int result.  In this module, both inputs and result
    + * are 16 bits or less, so either int or short multiply will work.
    + */
    +
    +#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                 JCOEFPTR coef_block,
    +                 JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  INT32 tmp0, tmp1, tmp2, tmp3;
    +  INT32 tmp10, tmp11, tmp12, tmp13;
    +  INT32 z1, z2, z3, z4, z5;
    +  JCOEFPTR inptr;
    +  ISLOW_MULT_TYPE * quantptr;
    +  int * wsptr;
    +  JSAMPROW outptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  int ctr;
    +  int workspace[DCTSIZE2];      /* buffers data between passes */
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process columns from input, store into work array. */
    +  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
    +  /* furthermore, we scale the results by 2**PASS1_BITS. */
    +
    +  inptr = coef_block;
    +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
    +  wsptr = workspace;
    +  for (ctr = DCTSIZE; ctr > 0; ctr--) {
    +    /* Due to quantization, we will usually find that many of the input
    +     * coefficients are zero, especially the AC terms.  We can exploit this
    +     * by short-circuiting the IDCT calculation for any column in which all
    +     * the AC terms are zero.  In that case each output is equal to the
    +     * DC coefficient (with scale factor as needed).
    +     * With typical images and quantization tables, half or more of the
    +     * column DCT calculations can be simplified this way.
    +     */
    +
    +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
    +        inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
    +        inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
    +        inptr[DCTSIZE*7] == 0) {
    +      /* AC terms all zero */
    +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
    +
    +      wsptr[DCTSIZE*0] = dcval;
    +      wsptr[DCTSIZE*1] = dcval;
    +      wsptr[DCTSIZE*2] = dcval;
    +      wsptr[DCTSIZE*3] = dcval;
    +      wsptr[DCTSIZE*4] = dcval;
    +      wsptr[DCTSIZE*5] = dcval;
    +      wsptr[DCTSIZE*6] = dcval;
    +      wsptr[DCTSIZE*7] = dcval;
    +
    +      inptr++;                  /* advance pointers to next column */
    +      quantptr++;
    +      wsptr++;
    +      continue;
    +    }
    +
    +    /* Even part: reverse the even part of the forward DCT. */
    +    /* The rotator is sqrt(2)*c(-6). */
    +
    +    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
    +    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
    +
    +    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
    +    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
    +    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
    +
    +    z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +    z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
    +
    +    tmp0 = (z2 + z3) << CONST_BITS;
    +    tmp1 = (z2 - z3) << CONST_BITS;
    +
    +    tmp10 = tmp0 + tmp3;
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    /* Odd part per figure 8; the matrix is unitary and hence its
    +     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
    +     */
    +
    +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
    +    tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
    +    tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
    +    tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
    +
    +    z1 = tmp0 + tmp3;
    +    z2 = tmp1 + tmp2;
    +    z3 = tmp0 + tmp2;
    +    z4 = tmp1 + tmp3;
    +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
    +
    +    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
    +    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
    +    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
    +    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
    +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
    +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
    +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
    +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
    +
    +    z3 += z5;
    +    z4 += z5;
    +
    +    tmp0 += z1 + z3;
    +    tmp1 += z2 + z4;
    +    tmp2 += z2 + z3;
    +    tmp3 += z1 + z4;
    +
    +    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
    +
    +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
    +    wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
    +
    +    inptr++;                    /* advance pointers to next column */
    +    quantptr++;
    +    wsptr++;
    +  }
    +
    +  /* Pass 2: process rows from work array, store into output array. */
    +  /* Note that we must descale the results by a factor of 8 == 2**3, */
    +  /* and also undo the PASS1_BITS scaling. */
    +
    +  wsptr = workspace;
    +  for (ctr = 0; ctr < DCTSIZE; ctr++) {
    +    outptr = output_buf[ctr] + output_col;
    +    /* Rows of zeroes can be exploited in the same way as we did with columns.
    +     * However, the column calculation has created many nonzero AC terms, so
    +     * the simplification applies less often (typically 5% to 10% of the time).
    +     * On machines with very fast multiplication, it's possible that the
    +     * test takes more time than it's worth.  In that case this section
    +     * may be commented out.
    +     */
    +
    +#ifndef NO_ZERO_ROW_TEST
    +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
    +        wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
    +      /* AC terms all zero */
    +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
    +                                  & RANGE_MASK];
    +
    +      outptr[0] = dcval;
    +      outptr[1] = dcval;
    +      outptr[2] = dcval;
    +      outptr[3] = dcval;
    +      outptr[4] = dcval;
    +      outptr[5] = dcval;
    +      outptr[6] = dcval;
    +      outptr[7] = dcval;
    +
    +      wsptr += DCTSIZE;         /* advance pointer to next row */
    +      continue;
    +    }
    +#endif
    +
    +    /* Even part: reverse the even part of the forward DCT. */
    +    /* The rotator is sqrt(2)*c(-6). */
    +
    +    z2 = (INT32) wsptr[2];
    +    z3 = (INT32) wsptr[6];
    +
    +    z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
    +    tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
    +    tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
    +
    +    tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
    +    tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
    +
    +    tmp10 = tmp0 + tmp3;
    +    tmp13 = tmp0 - tmp3;
    +    tmp11 = tmp1 + tmp2;
    +    tmp12 = tmp1 - tmp2;
    +
    +    /* Odd part per figure 8; the matrix is unitary and hence its
    +     * transpose is its inverse.  i0..i3 are y7,y5,y3,y1 respectively.
    +     */
    +
    +    tmp0 = (INT32) wsptr[7];
    +    tmp1 = (INT32) wsptr[5];
    +    tmp2 = (INT32) wsptr[3];
    +    tmp3 = (INT32) wsptr[1];
    +
    +    z1 = tmp0 + tmp3;
    +    z2 = tmp1 + tmp2;
    +    z3 = tmp0 + tmp2;
    +    z4 = tmp1 + tmp3;
    +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
    +
    +    tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
    +    tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
    +    tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
    +    tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
    +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
    +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
    +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
    +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
    +
    +    z3 += z5;
    +    z4 += z5;
    +
    +    tmp0 += z1 + z3;
    +    tmp1 += z2 + z4;
    +    tmp2 += z2 + z3;
    +    tmp3 += z1 + z4;
    +
    +    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
    +
    +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +    outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
    +                                          CONST_BITS+PASS1_BITS+3)
    +                            & RANGE_MASK];
    +
    +    wsptr += DCTSIZE;           /* advance pointer to next row */
    +  }
    +}
    +
    +#endif /* DCT_ISLOW_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctred.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctred.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jidctred.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jidctred.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,402 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jidctred.c
    + *
    + * Copyright (C) 1994-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains inverse-DCT routines that produce reduced-size output:
    + * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
    + *
    + * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
    + * algorithm used in jidctint.c.  We simply replace each 8-to-8 1-D IDCT step
    + * with an 8-to-4 step that produces the four averages of two adjacent outputs
    + * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
    + * These steps were derived by computing the corresponding values at the end
    + * of the normal LL&M code, then simplifying as much as possible.
    + *
    + * 1x1 is trivial: just take the DC coefficient divided by 8.
    + *
    + * See jidctint.c for additional comments.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jdct.h"               /* Private declarations for DCT subsystem */
    +
    +#ifdef IDCT_SCALING_SUPPORTED
    +
    +
    +/*
    + * This module is specialized to the case DCTSIZE = 8.
    + */
    +
    +#if DCTSIZE != 8
    +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
    +#endif
    +
    +
    +/* Scaling is the same as in jidctint.c. */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define CONST_BITS  13
    +#define PASS1_BITS  2
    +#else
    +#define CONST_BITS  13
    +#define PASS1_BITS  1           /* lose a little precision to avoid overflow */
    +#endif
    +
    +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
    + * causing a lot of useless floating-point operations at run time.
    + * To get around this we use the following pre-calculated constants.
    + * If you change CONST_BITS you may want to add appropriate values.
    + * (With a reasonable C compiler, you can just rely on the FIX() macro...)
    + */
    +
    +#if CONST_BITS == 13
    +#define FIX_0_211164243  ((INT32)  1730)        /* FIX(0.211164243) */
    +#define FIX_0_509795579  ((INT32)  4176)        /* FIX(0.509795579) */
    +#define FIX_0_601344887  ((INT32)  4926)        /* FIX(0.601344887) */
    +#define FIX_0_720959822  ((INT32)  5906)        /* FIX(0.720959822) */
    +#define FIX_0_765366865  ((INT32)  6270)        /* FIX(0.765366865) */
    +#define FIX_0_850430095  ((INT32)  6967)        /* FIX(0.850430095) */
    +#define FIX_0_899976223  ((INT32)  7373)        /* FIX(0.899976223) */
    +#define FIX_1_061594337  ((INT32)  8697)        /* FIX(1.061594337) */
    +#define FIX_1_272758580  ((INT32)  10426)       /* FIX(1.272758580) */
    +#define FIX_1_451774981  ((INT32)  11893)       /* FIX(1.451774981) */
    +#define FIX_1_847759065  ((INT32)  15137)       /* FIX(1.847759065) */
    +#define FIX_2_172734803  ((INT32)  17799)       /* FIX(2.172734803) */
    +#define FIX_2_562915447  ((INT32)  20995)       /* FIX(2.562915447) */
    +#define FIX_3_624509785  ((INT32)  29692)       /* FIX(3.624509785) */
    +#else
    +#define FIX_0_211164243  FIX(0.211164243)
    +#define FIX_0_509795579  FIX(0.509795579)
    +#define FIX_0_601344887  FIX(0.601344887)
    +#define FIX_0_720959822  FIX(0.720959822)
    +#define FIX_0_765366865  FIX(0.765366865)
    +#define FIX_0_850430095  FIX(0.850430095)
    +#define FIX_0_899976223  FIX(0.899976223)
    +#define FIX_1_061594337  FIX(1.061594337)
    +#define FIX_1_272758580  FIX(1.272758580)
    +#define FIX_1_451774981  FIX(1.451774981)
    +#define FIX_1_847759065  FIX(1.847759065)
    +#define FIX_2_172734803  FIX(2.172734803)
    +#define FIX_2_562915447  FIX(2.562915447)
    +#define FIX_3_624509785  FIX(3.624509785)
    +#endif
    +
    +
    +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
    + * For 8-bit samples with the recommended scaling, all the variable
    + * and constant values involved are no more than 16 bits wide, so a
    + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
    + * For 12-bit samples, a full 32-bit multiplication will be needed.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const)
    +#else
    +#define MULTIPLY(var,const)  ((var) * (const))
    +#endif
    +
    +
    +/* Dequantize a coefficient by multiplying it by the multiplier-table
    + * entry; produce an int result.  In this module, both inputs and result
    + * are 16 bits or less, so either int or short multiply will work.
    + */
    +
    +#define DEQUANTIZE(coef,quantval)  (((ISLOW_MULT_TYPE) (coef)) * (quantval))
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients,
    + * producing a reduced-size 4x4 output block.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JCOEFPTR coef_block,
    +               JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  INT32 tmp0, tmp2, tmp10, tmp12;
    +  INT32 z1, z2, z3, z4;
    +  JCOEFPTR inptr;
    +  ISLOW_MULT_TYPE * quantptr;
    +  int * wsptr;
    +  JSAMPROW outptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  int ctr;
    +  int workspace[DCTSIZE*4];     /* buffers data between passes */
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process columns from input, store into work array. */
    +
    +  inptr = coef_block;
    +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
    +  wsptr = workspace;
    +  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
    +    /* Don't bother to process column 4, because second pass won't use it */
    +    if (ctr == DCTSIZE-4)
    +      continue;
    +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
    +        inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
    +        inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
    +      /* AC terms all zero; we need not examine term 4 for 4x4 output */
    +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
    +
    +      wsptr[DCTSIZE*0] = dcval;
    +      wsptr[DCTSIZE*1] = dcval;
    +      wsptr[DCTSIZE*2] = dcval;
    +      wsptr[DCTSIZE*3] = dcval;
    +
    +      continue;
    +    }
    +
    +    /* Even part */
    +
    +    tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +    tmp0 <<= (CONST_BITS+1);
    +
    +    z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
    +    z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
    +
    +    tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
    +
    +    tmp10 = tmp0 + tmp2;
    +    tmp12 = tmp0 - tmp2;
    +
    +    /* Odd part */
    +
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
    +    z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
    +    z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
    +    z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
    +
    +    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
    +         + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
    +         + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
    +         + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
    +
    +    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
    +         + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
    +         + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
    +         + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
    +
    +    /* Final output stage */
    +
    +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
    +    wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
    +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
    +    wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
    +  }
    +
    +  /* Pass 2: process 4 rows from work array, store into output array. */
    +
    +  wsptr = workspace;
    +  for (ctr = 0; ctr < 4; ctr++) {
    +    outptr = output_buf[ctr] + output_col;
    +    /* It's not clear whether a zero row test is worthwhile here ... */
    +
    +#ifndef NO_ZERO_ROW_TEST
    +    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
    +        wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
    +      /* AC terms all zero */
    +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
    +                                  & RANGE_MASK];
    +
    +      outptr[0] = dcval;
    +      outptr[1] = dcval;
    +      outptr[2] = dcval;
    +      outptr[3] = dcval;
    +
    +      wsptr += DCTSIZE;         /* advance pointer to next row */
    +      continue;
    +    }
    +#endif
    +
    +    /* Even part */
    +
    +    tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
    +
    +    tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
    +         + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
    +
    +    tmp10 = tmp0 + tmp2;
    +    tmp12 = tmp0 - tmp2;
    +
    +    /* Odd part */
    +
    +    z1 = (INT32) wsptr[7];
    +    z2 = (INT32) wsptr[5];
    +    z3 = (INT32) wsptr[3];
    +    z4 = (INT32) wsptr[1];
    +
    +    tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
    +         + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
    +         + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
    +         + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
    +
    +    tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
    +         + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
    +         + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
    +         + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
    +
    +    /* Final output stage */
    +
    +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
    +                                          CONST_BITS+PASS1_BITS+3+1)
    +                            & RANGE_MASK];
    +    outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
    +                                          CONST_BITS+PASS1_BITS+3+1)
    +                            & RANGE_MASK];
    +    outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
    +                                          CONST_BITS+PASS1_BITS+3+1)
    +                            & RANGE_MASK];
    +    outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
    +                                          CONST_BITS+PASS1_BITS+3+1)
    +                            & RANGE_MASK];
    +
    +    wsptr += DCTSIZE;           /* advance pointer to next row */
    +  }
    +}
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients,
    + * producing a reduced-size 2x2 output block.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JCOEFPTR coef_block,
    +               JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  INT32 tmp0, tmp10, z1;
    +  JCOEFPTR inptr;
    +  ISLOW_MULT_TYPE * quantptr;
    +  int * wsptr;
    +  JSAMPROW outptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  int ctr;
    +  int workspace[DCTSIZE*2];     /* buffers data between passes */
    +  SHIFT_TEMPS
    +
    +  /* Pass 1: process columns from input, store into work array. */
    +
    +  inptr = coef_block;
    +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
    +  wsptr = workspace;
    +  for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
    +    /* Don't bother to process columns 2,4,6 */
    +    if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
    +      continue;
    +    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
    +        inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
    +      /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
    +      int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
    +
    +      wsptr[DCTSIZE*0] = dcval;
    +      wsptr[DCTSIZE*1] = dcval;
    +
    +      continue;
    +    }
    +
    +    /* Even part */
    +
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
    +    tmp10 = z1 << (CONST_BITS+2);
    +
    +    /* Odd part */
    +
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
    +    tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
    +    tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
    +    tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
    +    z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
    +    tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
    +
    +    /* Final output stage */
    +
    +    wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
    +    wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
    +  }
    +
    +  /* Pass 2: process 2 rows from work array, store into output array. */
    +
    +  wsptr = workspace;
    +  for (ctr = 0; ctr < 2; ctr++) {
    +    outptr = output_buf[ctr] + output_col;
    +    /* It's not clear whether a zero row test is worthwhile here ... */
    +
    +#ifndef NO_ZERO_ROW_TEST
    +    if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
    +      /* AC terms all zero */
    +      JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
    +                                  & RANGE_MASK];
    +
    +      outptr[0] = dcval;
    +      outptr[1] = dcval;
    +
    +      wsptr += DCTSIZE;         /* advance pointer to next row */
    +      continue;
    +    }
    +#endif
    +
    +    /* Even part */
    +
    +    tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
    +
    +    /* Odd part */
    +
    +    tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
    +         + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
    +         + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
    +         + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
    +
    +    /* Final output stage */
    +
    +    outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
    +                                          CONST_BITS+PASS1_BITS+3+2)
    +                            & RANGE_MASK];
    +    outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
    +                                          CONST_BITS+PASS1_BITS+3+2)
    +                            & RANGE_MASK];
    +
    +    wsptr += DCTSIZE;           /* advance pointer to next row */
    +  }
    +}
    +
    +
    +/*
    + * Perform dequantization and inverse DCT on one block of coefficients,
    + * producing a reduced-size 1x1 output block.
    + */
    +
    +GLOBAL(void)
    +jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +               JCOEFPTR coef_block,
    +               JSAMPARRAY output_buf, JDIMENSION output_col)
    +{
    +  int dcval;
    +  ISLOW_MULT_TYPE * quantptr;
    +  JSAMPLE *range_limit = IDCT_range_limit(cinfo);
    +  SHIFT_TEMPS
    +
    +  /* We hardly need an inverse DCT routine for this: just take the
    +   * average pixel value, which is one-eighth of the DC coefficient.
    +   */
    +  quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
    +  dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
    +  dcval = (int) DESCALE((INT32) dcval, 3);
    +
    +  output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
    +}
    +
    +#endif /* IDCT_SCALING_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemmgr.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemmgr.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemmgr.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemmgr.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1131 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jmemmgr.c
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains the JPEG system-independent memory management
    + * routines.  This code is usable across a wide variety of machines; most
    + * of the system dependencies have been isolated in a separate file.
    + * The major functions provided here are:
    + *   * pool-based allocation and freeing of memory;
    + *   * policy decisions about how to divide available memory among the
    + *     virtual arrays;
    + *   * control logic for swapping virtual arrays between main memory and
    + *     backing storage.
    + * The separate system-dependent file provides the actual backing-storage
    + * access code, and it contains the policy decision about how much total
    + * main memory to use.
    + * This file is system-dependent in the sense that some of its functions
    + * are unnecessary in some systems.  For example, if there is enough virtual
    + * memory so that backing storage will never be used, much of the virtual
    + * array control logic could be removed.  (Of course, if you have that much
    + * memory then you shouldn't care about a little bit of unused code...)
    + */
    +
    +#define JPEG_INTERNALS
    +#define AM_MEMORY_MANAGER       /* we define jvirt_Xarray_control structs */
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jmemsys.h"            /* import the system-dependent declarations */
    +
    +#ifndef NO_GETENV
    +#ifndef HAVE_STDLIB_H           /*  should declare getenv() */
    +extern char * getenv JPP((const char * name));
    +#endif
    +#endif
    +
    +
    +/*
    + * Some important notes:
    + *   The allocation routines provided here must never return NULL.
    + *   They should exit to error_exit if unsuccessful.
    + *
    + *   It's not a good idea to try to merge the sarray and barray routines,
    + *   even though they are textually almost the same, because samples are
    + *   usually stored as bytes while coefficients are shorts or ints.  Thus,
    + *   in machines where byte pointers have a different representation from
    + *   word pointers, the resulting machine code could not be the same.
    + */
    +
    +
    +/*
    + * Many machines require storage alignment: longs must start on 4-byte
    + * boundaries, doubles on 8-byte boundaries, etc.  On such machines, malloc()
    + * always returns pointers that are multiples of the worst-case alignment
    + * requirement, and we had better do so too.
    + * There isn't any really portable way to determine the worst-case alignment
    + * requirement.  This module assumes that the alignment requirement is
    + * multiples of sizeof(ALIGN_TYPE).
    + * By default, we define ALIGN_TYPE as double.  This is necessary on some
    + * workstations (where doubles really do need 8-byte alignment) and will work
    + * fine on nearly everything.  If your machine has lesser alignment needs,
    + * you can save a few bytes by making ALIGN_TYPE smaller.
    + * The only place I know of where this will NOT work is certain Macintosh
    + * 680x0 compilers that define double as a 10-byte IEEE extended float.
    + * Doing 10-byte alignment is counterproductive because longwords won't be
    + * aligned well.  Put "#define ALIGN_TYPE long" in jconfig.h if you have
    + * such a compiler.
    + */
    +
    +#ifndef ALIGN_TYPE              /* so can override from jconfig.h */
    +#define ALIGN_TYPE  double
    +#endif
    +
    +
    +/*
    + * We allocate objects from "pools", where each pool is gotten with a single
    + * request to jpeg_get_small() or jpeg_get_large().  There is no per-object
    + * overhead within a pool, except for alignment padding.  Each pool has a
    + * header with a link to the next pool of the same class.
    + * Small and large pool headers are identical except that the latter's
    + * link pointer must be FAR on 80x86 machines.
    + * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
    + * field.  This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
    + * of the alignment requirement of ALIGN_TYPE.
    + */
    +
    +typedef union small_pool_struct * small_pool_ptr;
    +
    +typedef union small_pool_struct {
    +  struct {
    +    small_pool_ptr next;        /* next in list of pools */
    +    size_t bytes_used;          /* how many bytes already used within pool */
    +    size_t bytes_left;          /* bytes still available in this pool */
    +  } hdr;
    +  ALIGN_TYPE dummy;             /* included in union to ensure alignment */
    +} small_pool_hdr;
    +
    +typedef union large_pool_struct FAR * large_pool_ptr;
    +
    +typedef union large_pool_struct {
    +  struct {
    +    large_pool_ptr next;        /* next in list of pools */
    +    size_t bytes_used;          /* how many bytes already used within pool */
    +    size_t bytes_left;          /* bytes still available in this pool */
    +  } hdr;
    +  ALIGN_TYPE dummy;             /* included in union to ensure alignment */
    +} large_pool_hdr;
    +
    +
    +/*
    + * Here is the full definition of a memory manager object.
    + */
    +
    +typedef struct {
    +  struct jpeg_memory_mgr pub;   /* public fields */
    +
    +  /* Each pool identifier (lifetime class) names a linked list of pools. */
    +  small_pool_ptr small_list[JPOOL_NUMPOOLS];
    +  large_pool_ptr large_list[JPOOL_NUMPOOLS];
    +
    +  /* Since we only have one lifetime class of virtual arrays, only one
    +   * linked list is necessary (for each datatype).  Note that the virtual
    +   * array control blocks being linked together are actually stored somewhere
    +   * in the small-pool list.
    +   */
    +  jvirt_sarray_ptr virt_sarray_list;
    +  jvirt_barray_ptr virt_barray_list;
    +
    +  /* This counts total space obtained from jpeg_get_small/large */
    +  size_t total_space_allocated;
    +
    +  /* alloc_sarray and alloc_barray set this value for use by virtual
    +   * array routines.
    +   */
    +  JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
    +} my_memory_mgr;
    +
    +typedef my_memory_mgr * my_mem_ptr;
    +
    +
    +/*
    + * The control blocks for virtual arrays.
    + * Note that these blocks are allocated in the "small" pool area.
    + * System-dependent info for the associated backing store (if any) is hidden
    + * inside the backing_store_info struct.
    + */
    +
    +struct jvirt_sarray_control {
    +  JSAMPARRAY mem_buffer;        /* => the in-memory buffer */
    +  JDIMENSION rows_in_array;     /* total virtual array height */
    +  JDIMENSION samplesperrow;     /* width of array (and of memory buffer) */
    +  JDIMENSION maxaccess;         /* max rows accessed by access_virt_sarray */
    +  JDIMENSION rows_in_mem;       /* height of memory buffer */
    +  JDIMENSION rowsperchunk;      /* allocation chunk size in mem_buffer */
    +  JDIMENSION cur_start_row;     /* first logical row # in the buffer */
    +  JDIMENSION first_undef_row;   /* row # of first uninitialized row */
    +  boolean pre_zero;             /* pre-zero mode requested? */
    +  boolean dirty;                /* do current buffer contents need written? */
    +  boolean b_s_open;             /* is backing-store data valid? */
    +  jvirt_sarray_ptr next;        /* link to next virtual sarray control block */
    +  backing_store_info b_s_info;  /* System-dependent control info */
    +};
    +
    +struct jvirt_barray_control {
    +  JBLOCKARRAY mem_buffer;       /* => the in-memory buffer */
    +  JDIMENSION rows_in_array;     /* total virtual array height */
    +  JDIMENSION blocksperrow;      /* width of array (and of memory buffer) */
    +  JDIMENSION maxaccess;         /* max rows accessed by access_virt_barray */
    +  JDIMENSION rows_in_mem;       /* height of memory buffer */
    +  JDIMENSION rowsperchunk;      /* allocation chunk size in mem_buffer */
    +  JDIMENSION cur_start_row;     /* first logical row # in the buffer */
    +  JDIMENSION first_undef_row;   /* row # of first uninitialized row */
    +  boolean pre_zero;             /* pre-zero mode requested? */
    +  boolean dirty;                /* do current buffer contents need written? */
    +  boolean b_s_open;             /* is backing-store data valid? */
    +  jvirt_barray_ptr next;        /* link to next virtual barray control block */
    +  backing_store_info b_s_info;  /* System-dependent control info */
    +};
    +
    +
    +#ifdef MEM_STATS                /* optional extra stuff for statistics */
    +
    +LOCAL(void)
    +print_mem_stats (j_common_ptr cinfo, int pool_id)
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  small_pool_ptr shdr_ptr;
    +  large_pool_ptr lhdr_ptr;
    +
    +  /* Since this is only a debugging stub, we can cheat a little by using
    +   * fprintf directly rather than going through the trace message code.
    +   * This is helpful because message parm array can't handle longs.
    +   */
    +  fprintf(stderr, "Freeing pool %d, total space = %ld\n",
    +          pool_id, mem->total_space_allocated);
    +
    +  for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
    +       lhdr_ptr = lhdr_ptr->hdr.next) {
    +    fprintf(stderr, "  Large chunk used %ld\n",
    +            (long) lhdr_ptr->hdr.bytes_used);
    +  }
    +
    +  for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
    +       shdr_ptr = shdr_ptr->hdr.next) {
    +    fprintf(stderr, "  Small chunk used %ld free %ld\n",
    +            (long) shdr_ptr->hdr.bytes_used,
    +            (long) shdr_ptr->hdr.bytes_left);
    +  }
    +}
    +
    +#endif /* MEM_STATS */
    +
    +
    +LOCAL(void)
    +out_of_memory (j_common_ptr cinfo, int which)
    +/* Report an out-of-memory error and stop execution */
    +/* If we compiled MEM_STATS support, report alloc requests before dying */
    +{
    +#ifdef MEM_STATS
    +  cinfo->err->trace_level = 2;  /* force self_destruct to report stats */
    +#endif
    +  ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
    +}
    +
    +
    +/*
    + * Allocation of "small" objects.
    + *
    + * For these, we use pooled storage.  When a new pool must be created,
    + * we try to get enough space for the current request plus a "slop" factor,
    + * where the slop will be the amount of leftover space in the new pool.
    + * The speed vs. space tradeoff is largely determined by the slop values.
    + * A different slop value is provided for each pool class (lifetime),
    + * and we also distinguish the first pool of a class from later ones.
    + * NOTE: the values given work fairly well on both 16- and 32-bit-int
    + * machines, but may be too small if longs are 64 bits or more.
    + */
    +
    +static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
    +{
    +        1600,                   /* first PERMANENT pool */
    +        16000                   /* first IMAGE pool */
    +};
    +
    +static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
    +{
    +        0,                      /* additional PERMANENT pools */
    +        5000                    /* additional IMAGE pools */
    +};
    +
    +#define MIN_SLOP  50            /* greater than 0 to avoid futile looping */
    +
    +
    +METHODDEF(void *)
    +alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
    +/* Allocate a "small" object */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  small_pool_ptr hdr_ptr, prev_hdr_ptr;
    +  char * data_ptr;
    +  size_t odd_bytes, min_request, slop;
    +
    +  /* Check for unsatisfiable request (do now to ensure no overflow below) */
    +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
    +    out_of_memory(cinfo, 1);    /* request exceeds malloc's ability */
    +
    +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
    +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
    +  if (odd_bytes > 0)
    +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
    +
    +  /* See if space is available in any existing pool */
    +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
    +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
    +  prev_hdr_ptr = NULL;
    +  hdr_ptr = mem->small_list[pool_id];
    +  while (hdr_ptr != NULL) {
    +    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
    +      break;                    /* found pool with enough space */
    +    prev_hdr_ptr = hdr_ptr;
    +    hdr_ptr = hdr_ptr->hdr.next;
    +  }
    +
    +  /* Time to make a new pool? */
    +  if (hdr_ptr == NULL) {
    +    /* min_request is what we need now, slop is what will be leftover */
    +    min_request = sizeofobject + SIZEOF(small_pool_hdr);
    +    if (prev_hdr_ptr == NULL)   /* first pool in class? */
    +      slop = first_pool_slop[pool_id];
    +    else
    +      slop = extra_pool_slop[pool_id];
    +    /* Don't ask for more than MAX_ALLOC_CHUNK */
    +    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
    +      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
    +    /* Try to get space, if fail reduce slop and try again */
    +    for (;;) {
    +      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
    +      if (hdr_ptr != NULL)
    +        break;
    +      slop /= 2;
    +      if (slop < MIN_SLOP)      /* give up when it gets real small */
    +        out_of_memory(cinfo, 2); /* jpeg_get_small failed */
    +    }
    +    mem->total_space_allocated += min_request + slop;
    +    /* Success, initialize the new pool header and add to end of list */
    +    hdr_ptr->hdr.next = NULL;
    +    hdr_ptr->hdr.bytes_used = 0;
    +    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
    +    if (prev_hdr_ptr == NULL)   /* first pool in class? */
    +      mem->small_list[pool_id] = hdr_ptr;
    +    else
    +      prev_hdr_ptr->hdr.next = hdr_ptr;
    +  }
    +
    +  /* OK, allocate the object from the current pool */
    +  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
    +  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
    +  hdr_ptr->hdr.bytes_used += sizeofobject;
    +  hdr_ptr->hdr.bytes_left -= sizeofobject;
    +
    +  return (void *) data_ptr;
    +}
    +
    +
    +/*
    + * Allocation of "large" objects.
    + *
    + * The external semantics of these are the same as "small" objects,
    + * except that FAR pointers are used on 80x86.  However the pool
    + * management heuristics are quite different.  We assume that each
    + * request is large enough that it may as well be passed directly to
    + * jpeg_get_large; the pool management just links everything together
    + * so that we can free it all on demand.
    + * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
    + * structures.  The routines that create these structures (see below)
    + * deliberately bunch rows together to ensure a large request size.
    + */
    +
    +METHODDEF(void FAR *)
    +alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
    +/* Allocate a "large" object */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  large_pool_ptr hdr_ptr;
    +  size_t odd_bytes;
    +
    +  /* Check for unsatisfiable request (do now to ensure no overflow below) */
    +  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
    +    out_of_memory(cinfo, 3);    /* request exceeds malloc's ability */
    +
    +  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
    +  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
    +  if (odd_bytes > 0)
    +    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
    +
    +  /* Always make a new pool */
    +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
    +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
    +
    +  hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
    +                                            SIZEOF(large_pool_hdr));
    +  if (hdr_ptr == NULL)
    +    out_of_memory(cinfo, 4);    /* jpeg_get_large failed */
    +  mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
    +
    +  /* Success, initialize the new pool header and add to list */
    +  hdr_ptr->hdr.next = mem->large_list[pool_id];
    +  /* We maintain space counts in each pool header for statistical purposes,
    +   * even though they are not needed for allocation.
    +   */
    +  hdr_ptr->hdr.bytes_used = sizeofobject;
    +  hdr_ptr->hdr.bytes_left = 0;
    +  mem->large_list[pool_id] = hdr_ptr;
    +
    +  return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
    +}
    +
    +
    +/*
    + * Creation of 2-D sample arrays.
    + * The pointers are in near heap, the samples themselves in FAR heap.
    + *
    + * To minimize allocation overhead and to allow I/O of large contiguous
    + * blocks, we allocate the sample rows in groups of as many rows as possible
    + * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
    + * NB: the virtual array control routines, later in this file, know about
    + * this chunking of rows.  The rowsperchunk value is left in the mem manager
    + * object so that it can be saved away if this sarray is the workspace for
    + * a virtual array.
    + */
    +
    +METHODDEF(JSAMPARRAY)
    +alloc_sarray (j_common_ptr cinfo, int pool_id,
    +              JDIMENSION samplesperrow, JDIMENSION numrows)
    +/* Allocate a 2-D sample array */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  JSAMPARRAY result;
    +  JSAMPROW workspace;
    +  JDIMENSION rowsperchunk, currow, i;
    +  long ltemp;
    +
    +  if (samplesperrow == 0) {
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +  }
    +  /* Calculate max # of rows allowed in one allocation chunk */
    +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
    +          ((long) samplesperrow * SIZEOF(JSAMPLE));
    +  if (ltemp <= 0)
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +  if (ltemp < (long) numrows)
    +    rowsperchunk = (JDIMENSION) ltemp;
    +  else
    +    rowsperchunk = numrows;
    +  mem->last_rowsperchunk = rowsperchunk;
    +
    +  /* Get space for row pointers (small object) */
    +  result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
    +                                    (size_t) (numrows * SIZEOF(JSAMPROW)));
    +
    +  /* Get the rows themselves (large objects) */
    +  currow = 0;
    +  while (currow < numrows) {
    +    rowsperchunk = MIN(rowsperchunk, numrows - currow);
    +    workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
    +        (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
    +                  * SIZEOF(JSAMPLE)));
    +    for (i = rowsperchunk; i > 0; i--) {
    +      result[currow++] = workspace;
    +      workspace += samplesperrow;
    +    }
    +  }
    +
    +  return result;
    +}
    +
    +
    +/*
    + * Creation of 2-D coefficient-block arrays.
    + * This is essentially the same as the code for sample arrays, above.
    + */
    +
    +METHODDEF(JBLOCKARRAY)
    +alloc_barray (j_common_ptr cinfo, int pool_id,
    +              JDIMENSION blocksperrow, JDIMENSION numrows)
    +/* Allocate a 2-D coefficient-block array */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  JBLOCKARRAY result;
    +  JBLOCKROW workspace;
    +  JDIMENSION rowsperchunk, currow, i;
    +  long ltemp;
    +
    +  if (blocksperrow == 0) {
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +  }
    +
    +  /* Calculate max # of rows allowed in one allocation chunk */
    +  ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
    +          ((long) blocksperrow * SIZEOF(JBLOCK));
    +  if (ltemp <= 0)
    +    ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
    +  if (ltemp < (long) numrows)
    +    rowsperchunk = (JDIMENSION) ltemp;
    +  else
    +    rowsperchunk = numrows;
    +  mem->last_rowsperchunk = rowsperchunk;
    +
    +  /* Get space for row pointers (small object) */
    +  result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
    +                                     (size_t) (numrows * SIZEOF(JBLOCKROW)));
    +
    +  /* Get the rows themselves (large objects) */
    +  currow = 0;
    +  while (currow < numrows) {
    +    rowsperchunk = MIN(rowsperchunk, numrows - currow);
    +    workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
    +        (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
    +                  * SIZEOF(JBLOCK)));
    +    for (i = rowsperchunk; i > 0; i--) {
    +      result[currow++] = workspace;
    +      workspace += blocksperrow;
    +    }
    +  }
    +
    +  return result;
    +}
    +
    +
    +/*
    + * About virtual array management:
    + *
    + * The above "normal" array routines are only used to allocate strip buffers
    + * (as wide as the image, but just a few rows high).  Full-image-sized buffers
    + * are handled as "virtual" arrays.  The array is still accessed a strip at a
    + * time, but the memory manager must save the whole array for repeated
    + * accesses.  The intended implementation is that there is a strip buffer in
    + * memory (as high as is possible given the desired memory limit), plus a
    + * backing file that holds the rest of the array.
    + *
    + * The request_virt_array routines are told the total size of the image and
    + * the maximum number of rows that will be accessed at once.  The in-memory
    + * buffer must be at least as large as the maxaccess value.
    + *
    + * The request routines create control blocks but not the in-memory buffers.
    + * That is postponed until realize_virt_arrays is called.  At that time the
    + * total amount of space needed is known (approximately, anyway), so free
    + * memory can be divided up fairly.
    + *
    + * The access_virt_array routines are responsible for making a specific strip
    + * area accessible (after reading or writing the backing file, if necessary).
    + * Note that the access routines are told whether the caller intends to modify
    + * the accessed strip; during a read-only pass this saves having to rewrite
    + * data to disk.  The access routines are also responsible for pre-zeroing
    + * any newly accessed rows, if pre-zeroing was requested.
    + *
    + * In current usage, the access requests are usually for nonoverlapping
    + * strips; that is, successive access start_row numbers differ by exactly
    + * num_rows = maxaccess.  This means we can get good performance with simple
    + * buffer dump/reload logic, by making the in-memory buffer be a multiple
    + * of the access height; then there will never be accesses across bufferload
    + * boundaries.  The code will still work with overlapping access requests,
    + * but it doesn't handle bufferload overlaps very efficiently.
    + */
    +
    +
    +METHODDEF(jvirt_sarray_ptr)
    +request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
    +                     JDIMENSION samplesperrow, JDIMENSION numrows,
    +                     JDIMENSION maxaccess)
    +/* Request a virtual 2-D sample array */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  jvirt_sarray_ptr result;
    +
    +  /* Only IMAGE-lifetime virtual arrays are currently supported */
    +  if (pool_id != JPOOL_IMAGE)
    +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
    +
    +  /* get control block */
    +  result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
    +                                          SIZEOF(struct jvirt_sarray_control));
    +
    +  result->mem_buffer = NULL;    /* marks array not yet realized */
    +  result->rows_in_array = numrows;
    +  result->samplesperrow = samplesperrow;
    +  result->maxaccess = maxaccess;
    +  result->pre_zero = pre_zero;
    +  result->b_s_open = FALSE;     /* no associated backing-store object */
    +  result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
    +  mem->virt_sarray_list = result;
    +
    +  return result;
    +}
    +
    +
    +METHODDEF(jvirt_barray_ptr)
    +request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
    +                     JDIMENSION blocksperrow, JDIMENSION numrows,
    +                     JDIMENSION maxaccess)
    +/* Request a virtual 2-D coefficient-block array */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  jvirt_barray_ptr result;
    +
    +  /* Only IMAGE-lifetime virtual arrays are currently supported */
    +  if (pool_id != JPOOL_IMAGE)
    +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
    +
    +  /* get control block */
    +  result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
    +                                          SIZEOF(struct jvirt_barray_control));
    +
    +  result->mem_buffer = NULL;    /* marks array not yet realized */
    +  result->rows_in_array = numrows;
    +  result->blocksperrow = blocksperrow;
    +  result->maxaccess = maxaccess;
    +  result->pre_zero = pre_zero;
    +  result->b_s_open = FALSE;     /* no associated backing-store object */
    +  result->next = mem->virt_barray_list; /* add to list of virtual arrays */
    +  mem->virt_barray_list = result;
    +
    +  return result;
    +}
    +
    +
    +METHODDEF(void)
    +realize_virt_arrays (j_common_ptr cinfo)
    +/* Allocate the in-memory buffers for any unrealized virtual arrays */
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  size_t space_per_minheight, maximum_space, avail_mem;
    +  size_t minheights, max_minheights;
    +  jvirt_sarray_ptr sptr;
    +  jvirt_barray_ptr bptr;
    +
    +  /* Compute the minimum space needed (maxaccess rows in each buffer)
    +   * and the maximum space needed (full image height in each buffer).
    +   * These may be of use to the system-dependent jpeg_mem_available routine.
    +   */
    +  space_per_minheight = 0;
    +  maximum_space = 0;
    +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
    +    if (sptr->mem_buffer == NULL) { /* if not realized yet */
    +      space_per_minheight += (long) sptr->maxaccess *
    +                             (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
    +      maximum_space += (long) sptr->rows_in_array *
    +                       (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
    +    }
    +  }
    +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
    +    if (bptr->mem_buffer == NULL) { /* if not realized yet */
    +      space_per_minheight += (long) bptr->maxaccess *
    +                             (long) bptr->blocksperrow * SIZEOF(JBLOCK);
    +      maximum_space += (long) bptr->rows_in_array *
    +                       (long) bptr->blocksperrow * SIZEOF(JBLOCK);
    +    }
    +  }
    +
    +  if (space_per_minheight <= 0)
    +    return;                     /* no unrealized arrays, no work */
    +
    +  /* Determine amount of memory to actually use; this is system-dependent. */
    +  avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
    +                                 mem->total_space_allocated);
    +
    +  /* If the maximum space needed is available, make all the buffers full
    +   * height; otherwise parcel it out with the same number of minheights
    +   * in each buffer.
    +   */
    +  if (avail_mem >= maximum_space)
    +    max_minheights = 1000000000L;
    +  else {
    +    max_minheights = avail_mem / space_per_minheight;
    +    /* If there doesn't seem to be enough space, try to get the minimum
    +     * anyway.  This allows a "stub" implementation of jpeg_mem_available().
    +     */
    +    if (max_minheights <= 0)
    +      max_minheights = 1;
    +  }
    +
    +  /* Allocate the in-memory buffers and initialize backing store as needed. */
    +
    +  for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
    +    if (sptr->mem_buffer == NULL) { /* if not realized yet */
    +      minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
    +      if (minheights <= max_minheights) {
    +        /* This buffer fits in memory */
    +        sptr->rows_in_mem = sptr->rows_in_array;
    +      } else {
    +        /* It doesn't fit in memory, create backing store. */
    +        sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
    +        jpeg_open_backing_store(cinfo, & sptr->b_s_info,
    +                                (long) sptr->rows_in_array *
    +                                (long) sptr->samplesperrow *
    +                                (long) SIZEOF(JSAMPLE));
    +        sptr->b_s_open = TRUE;
    +      }
    +      sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
    +                                      sptr->samplesperrow, sptr->rows_in_mem);
    +      sptr->rowsperchunk = mem->last_rowsperchunk;
    +      sptr->cur_start_row = 0;
    +      sptr->first_undef_row = 0;
    +      sptr->dirty = FALSE;
    +    }
    +  }
    +
    +  for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
    +    if (bptr->mem_buffer == NULL) { /* if not realized yet */
    +      minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
    +      if (minheights <= max_minheights) {
    +        /* This buffer fits in memory */
    +        bptr->rows_in_mem = bptr->rows_in_array;
    +      } else {
    +        /* It doesn't fit in memory, create backing store. */
    +        bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
    +        jpeg_open_backing_store(cinfo, & bptr->b_s_info,
    +                                (long) bptr->rows_in_array *
    +                                (long) bptr->blocksperrow *
    +                                (long) SIZEOF(JBLOCK));
    +        bptr->b_s_open = TRUE;
    +      }
    +      bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
    +                                      bptr->blocksperrow, bptr->rows_in_mem);
    +      bptr->rowsperchunk = mem->last_rowsperchunk;
    +      bptr->cur_start_row = 0;
    +      bptr->first_undef_row = 0;
    +      bptr->dirty = FALSE;
    +    }
    +  }
    +}
    +
    +
    +LOCAL(void)
    +do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
    +/* Do backing store read or write of a virtual sample array */
    +{
    +  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
    +
    +  bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
    +  file_offset = ptr->cur_start_row * bytesperrow;
    +  /* Loop to read or write each allocation chunk in mem_buffer */
    +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
    +    /* One chunk, but check for short chunk at end of buffer */
    +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
    +    /* Transfer no more than is currently defined */
    +    thisrow = (long) ptr->cur_start_row + i;
    +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
    +    /* Transfer no more than fits in file */
    +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
    +    if (rows <= 0)              /* this chunk might be past end of file! */
    +      break;
    +    byte_count = rows * bytesperrow;
    +    if (writing)
    +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
    +                                            (void FAR *) ptr->mem_buffer[i],
    +                                            file_offset, byte_count);
    +    else
    +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
    +                                           (void FAR *) ptr->mem_buffer[i],
    +                                           file_offset, byte_count);
    +    file_offset += byte_count;
    +  }
    +}
    +
    +
    +LOCAL(void)
    +do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
    +/* Do backing store read or write of a virtual coefficient-block array */
    +{
    +  long bytesperrow, file_offset, byte_count, rows, thisrow, i;
    +
    +  bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
    +  file_offset = ptr->cur_start_row * bytesperrow;
    +  /* Loop to read or write each allocation chunk in mem_buffer */
    +  for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
    +    /* One chunk, but check for short chunk at end of buffer */
    +    rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
    +    /* Transfer no more than is currently defined */
    +    thisrow = (long) ptr->cur_start_row + i;
    +    rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
    +    /* Transfer no more than fits in file */
    +    rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
    +    if (rows <= 0)              /* this chunk might be past end of file! */
    +      break;
    +    byte_count = rows * bytesperrow;
    +    if (writing)
    +      (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
    +                                            (void FAR *) ptr->mem_buffer[i],
    +                                            file_offset, byte_count);
    +    else
    +      (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
    +                                           (void FAR *) ptr->mem_buffer[i],
    +                                           file_offset, byte_count);
    +    file_offset += byte_count;
    +  }
    +}
    +
    +
    +METHODDEF(JSAMPARRAY)
    +access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
    +                    JDIMENSION start_row, JDIMENSION num_rows,
    +                    boolean writable)
    +/* Access the part of a virtual sample array starting at start_row */
    +/* and extending for num_rows rows.  writable is true if  */
    +/* caller intends to modify the accessed area. */
    +{
    +  JDIMENSION end_row = start_row + num_rows;
    +  JDIMENSION undef_row;
    +
    +  /* debugging check */
    +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
    +      ptr->mem_buffer == NULL)
    +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +
    +  /* Make the desired part of the virtual array accessible */
    +  if (start_row < ptr->cur_start_row ||
    +      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
    +    if (! ptr->b_s_open)
    +      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
    +    /* Flush old buffer contents if necessary */
    +    if (ptr->dirty) {
    +      do_sarray_io(cinfo, ptr, TRUE);
    +      ptr->dirty = FALSE;
    +    }
    +    /* Decide what part of virtual array to access.
    +     * Algorithm: if target address > current window, assume forward scan,
    +     * load starting at target address.  If target address < current window,
    +     * assume backward scan, load so that target area is top of window.
    +     * Note that when switching from forward write to forward read, will have
    +     * start_row = 0, so the limiting case applies and we load from 0 anyway.
    +     */
    +    if (start_row > ptr->cur_start_row) {
    +      ptr->cur_start_row = start_row;
    +    } else {
    +      /* use long arithmetic here to avoid overflow & unsigned problems */
    +      long ltemp;
    +
    +      ltemp = (long) end_row - (long) ptr->rows_in_mem;
    +      if (ltemp < 0)
    +        ltemp = 0;              /* don't fall off front end of file */
    +      ptr->cur_start_row = (JDIMENSION) ltemp;
    +    }
    +    /* Read in the selected part of the array.
    +     * During the initial write pass, we will do no actual read
    +     * because the selected part is all undefined.
    +     */
    +    do_sarray_io(cinfo, ptr, FALSE);
    +  }
    +  /* Ensure the accessed part of the array is defined; prezero if needed.
    +   * To improve locality of access, we only prezero the part of the array
    +   * that the caller is about to access, not the entire in-memory array.
    +   */
    +  if (ptr->first_undef_row < end_row) {
    +    if (ptr->first_undef_row < start_row) {
    +      if (writable)             /* writer skipped over a section of array */
    +        ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +      undef_row = start_row;    /* but reader is allowed to read ahead */
    +    } else {
    +      undef_row = ptr->first_undef_row;
    +    }
    +    if (writable)
    +      ptr->first_undef_row = end_row;
    +    if (ptr->pre_zero) {
    +      size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
    +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
    +      end_row -= ptr->cur_start_row;
    +      while (undef_row < end_row) {
    +        jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
    +        undef_row++;
    +      }
    +    } else {
    +      if (! writable)           /* reader looking at undefined data */
    +        ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +    }
    +  }
    +  /* Flag the buffer dirty if caller will write in it */
    +  if (writable)
    +    ptr->dirty = TRUE;
    +  /* Return address of proper part of the buffer */
    +  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
    +}
    +
    +
    +METHODDEF(JBLOCKARRAY)
    +access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
    +                    JDIMENSION start_row, JDIMENSION num_rows,
    +                    boolean writable)
    +/* Access the part of a virtual block array starting at start_row */
    +/* and extending for num_rows rows.  writable is true if  */
    +/* caller intends to modify the accessed area. */
    +{
    +  JDIMENSION end_row = start_row + num_rows;
    +  JDIMENSION undef_row;
    +
    +  /* debugging check */
    +  if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
    +      ptr->mem_buffer == NULL)
    +    ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +
    +  /* Make the desired part of the virtual array accessible */
    +  if (start_row < ptr->cur_start_row ||
    +      end_row > ptr->cur_start_row+ptr->rows_in_mem) {
    +    if (! ptr->b_s_open)
    +      ERREXIT(cinfo, JERR_VIRTUAL_BUG);
    +    /* Flush old buffer contents if necessary */
    +    if (ptr->dirty) {
    +      do_barray_io(cinfo, ptr, TRUE);
    +      ptr->dirty = FALSE;
    +    }
    +    /* Decide what part of virtual array to access.
    +     * Algorithm: if target address > current window, assume forward scan,
    +     * load starting at target address.  If target address < current window,
    +     * assume backward scan, load so that target area is top of window.
    +     * Note that when switching from forward write to forward read, will have
    +     * start_row = 0, so the limiting case applies and we load from 0 anyway.
    +     */
    +    if (start_row > ptr->cur_start_row) {
    +      ptr->cur_start_row = start_row;
    +    } else {
    +      /* use long arithmetic here to avoid overflow & unsigned problems */
    +      long ltemp;
    +
    +      ltemp = (long) end_row - (long) ptr->rows_in_mem;
    +      if (ltemp < 0)
    +        ltemp = 0;              /* don't fall off front end of file */
    +      ptr->cur_start_row = (JDIMENSION) ltemp;
    +    }
    +    /* Read in the selected part of the array.
    +     * During the initial write pass, we will do no actual read
    +     * because the selected part is all undefined.
    +     */
    +    do_barray_io(cinfo, ptr, FALSE);
    +  }
    +  /* Ensure the accessed part of the array is defined; prezero if needed.
    +   * To improve locality of access, we only prezero the part of the array
    +   * that the caller is about to access, not the entire in-memory array.
    +   */
    +  if (ptr->first_undef_row < end_row) {
    +    if (ptr->first_undef_row < start_row) {
    +      if (writable)             /* writer skipped over a section of array */
    +        ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +      undef_row = start_row;    /* but reader is allowed to read ahead */
    +    } else {
    +      undef_row = ptr->first_undef_row;
    +    }
    +    if (writable)
    +      ptr->first_undef_row = end_row;
    +    if (ptr->pre_zero) {
    +      size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
    +      undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
    +      end_row -= ptr->cur_start_row;
    +      while (undef_row < end_row) {
    +        jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
    +        undef_row++;
    +      }
    +    } else {
    +      if (! writable)           /* reader looking at undefined data */
    +        ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
    +    }
    +  }
    +  /* Flag the buffer dirty if caller will write in it */
    +  if (writable)
    +    ptr->dirty = TRUE;
    +  /* Return address of proper part of the buffer */
    +  return ptr->mem_buffer + (start_row - ptr->cur_start_row);
    +}
    +
    +
    +/*
    + * Release all objects belonging to a specified pool.
    + */
    +
    +METHODDEF(void)
    +free_pool (j_common_ptr cinfo, int pool_id)
    +{
    +  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
    +  small_pool_ptr shdr_ptr;
    +  large_pool_ptr lhdr_ptr;
    +  size_t space_freed;
    +
    +  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
    +    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
    +
    +#ifdef MEM_STATS
    +  if (cinfo->err->trace_level > 1)
    +    print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
    +#endif
    +
    +  /* If freeing IMAGE pool, close any virtual arrays first */
    +  if (pool_id == JPOOL_IMAGE) {
    +    jvirt_sarray_ptr sptr;
    +    jvirt_barray_ptr bptr;
    +
    +    for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
    +      if (sptr->b_s_open) {     /* there may be no backing store */
    +        sptr->b_s_open = FALSE; /* prevent recursive close if error */
    +        (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
    +      }
    +    }
    +    mem->virt_sarray_list = NULL;
    +    for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
    +      if (bptr->b_s_open) {     /* there may be no backing store */
    +        bptr->b_s_open = FALSE; /* prevent recursive close if error */
    +        (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
    +      }
    +    }
    +    mem->virt_barray_list = NULL;
    +  }
    +
    +  /* Release large objects */
    +  lhdr_ptr = mem->large_list[pool_id];
    +  mem->large_list[pool_id] = NULL;
    +
    +  while (lhdr_ptr != NULL) {
    +    large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
    +    space_freed = lhdr_ptr->hdr.bytes_used +
    +                  lhdr_ptr->hdr.bytes_left +
    +                  SIZEOF(large_pool_hdr);
    +    jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
    +    mem->total_space_allocated -= space_freed;
    +    lhdr_ptr = next_lhdr_ptr;
    +  }
    +
    +  /* Release small objects */
    +  shdr_ptr = mem->small_list[pool_id];
    +  mem->small_list[pool_id] = NULL;
    +
    +  while (shdr_ptr != NULL) {
    +    small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
    +    space_freed = shdr_ptr->hdr.bytes_used +
    +                  shdr_ptr->hdr.bytes_left +
    +                  SIZEOF(small_pool_hdr);
    +    jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
    +    mem->total_space_allocated -= space_freed;
    +    shdr_ptr = next_shdr_ptr;
    +  }
    +}
    +
    +
    +/*
    + * Close up shop entirely.
    + * Note that this cannot be called unless cinfo->mem is non-NULL.
    + */
    +
    +METHODDEF(void)
    +self_destruct (j_common_ptr cinfo)
    +{
    +  int pool;
    +
    +  /* Close all backing store, release all memory.
    +   * Releasing pools in reverse order might help avoid fragmentation
    +   * with some (brain-damaged) malloc libraries.
    +   */
    +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
    +    free_pool(cinfo, pool);
    +  }
    +
    +  /* Release the memory manager control block too. */
    +  jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
    +  cinfo->mem = NULL;            /* ensures I will be called only once */
    +
    +  jpeg_mem_term(cinfo);         /* system-dependent cleanup */
    +}
    +
    +
    +/*
    + * Memory manager initialization.
    + * When this is called, only the error manager pointer is valid in cinfo!
    + */
    +
    +GLOBAL(void)
    +jinit_memory_mgr (j_common_ptr cinfo)
    +{
    +  my_mem_ptr mem;
    +  size_t max_to_use;
    +  int pool;
    +  size_t test_mac;
    +
    +  cinfo->mem = NULL;            /* for safety if init fails */
    +
    +  /* Check for configuration errors.
    +   * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
    +   * doesn't reflect any real hardware alignment requirement.
    +   * The test is a little tricky: for X>0, X and X-1 have no one-bits
    +   * in common if and only if X is a power of 2, ie has only one one-bit.
    +   * Some compilers may give an "unreachable code" warning here; ignore it.
    +   */
    +  if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
    +    ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
    +  /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
    +   * a multiple of SIZEOF(ALIGN_TYPE).
    +   * Again, an "unreachable code" warning may be ignored here.
    +   * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
    +   */
    +  test_mac = (size_t) MAX_ALLOC_CHUNK;
    +  if ((long) test_mac != MAX_ALLOC_CHUNK ||
    +      (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
    +    ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
    +
    +  max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
    +
    +  /* Attempt to allocate memory manager's control block */
    +  mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
    +
    +  if (mem == NULL) {
    +    jpeg_mem_term(cinfo);       /* system-dependent cleanup */
    +    ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
    +  }
    +
    +  /* OK, fill in the method pointers */
    +  mem->pub.alloc_small = alloc_small;
    +  mem->pub.alloc_large = alloc_large;
    +  mem->pub.alloc_sarray = alloc_sarray;
    +  mem->pub.alloc_barray = alloc_barray;
    +  mem->pub.request_virt_sarray = request_virt_sarray;
    +  mem->pub.request_virt_barray = request_virt_barray;
    +  mem->pub.realize_virt_arrays = realize_virt_arrays;
    +  mem->pub.access_virt_sarray = access_virt_sarray;
    +  mem->pub.access_virt_barray = access_virt_barray;
    +  mem->pub.free_pool = free_pool;
    +  mem->pub.self_destruct = self_destruct;
    +
    +  /* Make MAX_ALLOC_CHUNK accessible to other modules */
    +  mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
    +
    +  /* Initialize working state */
    +  mem->pub.max_memory_to_use = max_to_use;
    +
    +  for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
    +    mem->small_list[pool] = NULL;
    +    mem->large_list[pool] = NULL;
    +  }
    +  mem->virt_sarray_list = NULL;
    +  mem->virt_barray_list = NULL;
    +
    +  mem->total_space_allocated = SIZEOF(my_memory_mgr);
    +
    +  /* Declare ourselves open for business */
    +  cinfo->mem = & mem->pub;
    +
    +  /* Check for an environment variable JPEGMEM; if found, override the
    +   * default max_memory setting from jpeg_mem_init.  Note that the
    +   * surrounding application may again override this value.
    +   * If your system doesn't support getenv(), define NO_GETENV to disable
    +   * this feature.
    +   */
    +#ifndef NO_GETENV
    +  { char * memenv;
    +
    +    if ((memenv = getenv("JPEGMEM")) != NULL) {
    +      char ch = 'x';
    +      unsigned int mem_max = 0u;
    +
    +      if (sscanf(memenv, "%u%c", &mem_max, &ch) > 0) {
    +        max_to_use = (size_t)mem_max;
    +        if (ch == 'm' || ch == 'M')
    +          max_to_use *= 1000L;
    +        mem->pub.max_memory_to_use = max_to_use * 1000L;
    +      }
    +    }
    +  }
    +#endif
    +
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemnobs.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemnobs.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemnobs.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemnobs.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,116 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jmemnobs.c
    + *
    + * Copyright (C) 1992-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file provides a really simple implementation of the system-
    + * dependent portion of the JPEG memory manager.  This implementation
    + * assumes that no backing-store files are needed: all required space
    + * can be obtained from malloc().
    + * This is very portable in the sense that it'll compile on almost anything,
    + * but you'd better have lots of main memory (or virtual memory) if you want
    + * to process big images.
    + * Note that the max_memory_to_use option is ignored by this implementation.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +#include "jmemsys.h"            /* import the system-dependent declarations */
    +
    +#ifndef HAVE_STDLIB_H           /*  should declare malloc(),free() */
    +extern void * malloc JPP((size_t size));
    +extern void free JPP((void *ptr));
    +#endif
    +
    +
    +/*
    + * Memory allocation and freeing are controlled by the regular library
    + * routines malloc() and free().
    + */
    +
    +GLOBAL(void *)
    +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
    +{
    +  return (void *) malloc(sizeofobject);
    +}
    +
    +GLOBAL(void)
    +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
    +{
    +  free(object);
    +}
    +
    +
    +/*
    + * "Large" objects are treated the same as "small" ones.
    + * NB: although we include FAR keywords in the routine declarations,
    + * this file won't actually work in 80x86 small/medium model; at least,
    + * you probably won't be able to process useful-size images in only 64KB.
    + */
    +
    +GLOBAL(void FAR *)
    +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
    +{
    +  return (void FAR *) malloc(sizeofobject);
    +}
    +
    +GLOBAL(void)
    +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
    +{
    +  free(object);
    +}
    +
    +
    +/*
    + * This routine computes the total memory space available for allocation.
    + */
    +
    +GLOBAL(size_t)
    +jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
    +                    size_t max_bytes_needed, size_t already_allocated)
    +{
    +  if (cinfo->mem->max_memory_to_use)
    +    return cinfo->mem->max_memory_to_use - already_allocated;
    +
    +  /* Here we say, "we got all you want bud!" */
    +  return max_bytes_needed;
    +}
    +
    +
    +/*
    + * Backing store (temporary file) management.
    + * Since jpeg_mem_available always promised the moon,
    + * this should never be called and we can just error out.
    + */
    +
    +GLOBAL(void)
    +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
    +                         long total_bytes_needed)
    +{
    +  ERREXIT(cinfo, JERR_NO_BACKING_STORE);
    +}
    +
    +
    +/*
    + * These routines take care of any system-dependent initialization and
    + * cleanup required.  Here, there isn't any.
    + */
    +
    +GLOBAL(size_t)
    +jpeg_mem_init (j_common_ptr cinfo)
    +{
    +  return 0;                     /* just set max_memory_to_use to 0 */
    +}
    +
    +GLOBAL(void)
    +jpeg_mem_term (j_common_ptr cinfo)
    +{
    +  /* no work */
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemsys.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemsys.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmemsys.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmemsys.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,202 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jmemsys.h
    + *
    + * Copyright (C) 1992-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This include file defines the interface between the system-independent
    + * and system-dependent portions of the JPEG memory manager.  No other
    + * modules need include it.  (The system-independent portion is jmemmgr.c;
    + * there are several different versions of the system-dependent portion.)
    + *
    + * This file works as-is for the system-dependent memory managers supplied
    + * in the IJG distribution.  You may need to modify it if you write a
    + * custom memory manager.  If system-dependent changes are needed in
    + * this file, the best method is to #ifdef them based on a configuration
    + * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
    + * and USE_MAC_MEMMGR.
    + */
    +
    +
    +/* Short forms of external names for systems with brain-damaged linkers. */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_get_small          jGetSmall
    +#define jpeg_free_small         jFreeSmall
    +#define jpeg_get_large          jGetLarge
    +#define jpeg_free_large         jFreeLarge
    +#define jpeg_mem_available      jMemAvail
    +#define jpeg_open_backing_store jOpenBackStore
    +#define jpeg_mem_init           jMemInit
    +#define jpeg_mem_term           jMemTerm
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +
    +/*
    + * These two functions are used to allocate and release small chunks of
    + * memory.  (Typically the total amount requested through jpeg_get_small is
    + * no more than 20K or so; this will be requested in chunks of a few K each.)
    + * Behavior should be the same as for the standard library functions malloc
    + * and free; in particular, jpeg_get_small must return NULL on failure.
    + * On most systems, these ARE malloc and free.  jpeg_free_small is passed the
    + * size of the object being freed, just in case it's needed.
    + * On an 80x86 machine using small-data memory model, these manage near heap.
    + */
    +
    +EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
    +EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
    +                                  size_t sizeofobject));
    +
    +/*
    + * These two functions are used to allocate and release large chunks of
    + * memory (up to the total free space designated by jpeg_mem_available).
    + * The interface is the same as above, except that on an 80x86 machine,
    + * far pointers are used.  On most other machines these are identical to
    + * the jpeg_get/free_small routines; but we keep them separate anyway,
    + * in case a different allocation strategy is desirable for large chunks.
    + */
    +
    +EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
    +                                       size_t sizeofobject));
    +EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
    +                                  size_t sizeofobject));
    +
    +/*
    + * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
    + * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
    + * matter, but that case should never come into play).  This macro is needed
    + * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
    + * On those machines, we expect that jconfig.h will provide a proper value.
    + * On machines with 32-bit flat address spaces, any large constant may be used.
    + *
    + * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
    + * size_t and will be a multiple of sizeof(align_type).
    + */
    +
    +#ifndef MAX_ALLOC_CHUNK         /* may be overridden in jconfig.h */
    +#define MAX_ALLOC_CHUNK  1000000000L
    +#endif
    +
    +/*
    + * This routine computes the total space still available for allocation by
    + * jpeg_get_large.  If more space than this is needed, backing store will be
    + * used.  NOTE: any memory already allocated must not be counted.
    + *
    + * There is a minimum space requirement, corresponding to the minimum
    + * feasible buffer sizes; jmemmgr.c will request that much space even if
    + * jpeg_mem_available returns zero.  The maximum space needed, enough to hold
    + * all working storage in memory, is also passed in case it is useful.
    + * Finally, the total space already allocated is passed.  If no better
    + * method is available, cinfo->mem->max_memory_to_use - already_allocated
    + * is often a suitable calculation.
    + *
    + * It is OK for jpeg_mem_available to underestimate the space available
    + * (that'll just lead to more backing-store access than is really necessary).
    + * However, an overestimate will lead to failure.  Hence it's wise to subtract
    + * a slop factor from the true available space.  5% should be enough.
    + *
    + * On machines with lots of virtual memory, any large constant may be returned.
    + * Conversely, zero may be returned to always use the minimum amount of memory.
    + */
    +
    +EXTERN(size_t) jpeg_mem_available JPP((j_common_ptr cinfo,
    +                                     size_t min_bytes_needed,
    +                                     size_t max_bytes_needed,
    +                                     size_t already_allocated));
    +
    +
    +/*
    + * This structure holds whatever state is needed to access a single
    + * backing-store object.  The read/write/close method pointers are called
    + * by jmemmgr.c to manipulate the backing-store object; all other fields
    + * are private to the system-dependent backing store routines.
    + */
    +
    +#define TEMP_NAME_LENGTH   64   /* max length of a temporary file's name */
    +
    +
    +#ifdef USE_MSDOS_MEMMGR         /* DOS-specific junk */
    +
    +typedef unsigned short XMSH;    /* type of extended-memory handles */
    +typedef unsigned short EMSH;    /* type of expanded-memory handles */
    +
    +typedef union {
    +  short file_handle;            /* DOS file handle if it's a temp file */
    +  XMSH xms_handle;              /* handle if it's a chunk of XMS */
    +  EMSH ems_handle;              /* handle if it's a chunk of EMS */
    +} handle_union;
    +
    +#endif /* USE_MSDOS_MEMMGR */
    +
    +#ifdef USE_MAC_MEMMGR           /* Mac-specific junk */
    +#include 
    +#endif /* USE_MAC_MEMMGR */
    +
    +
    +typedef struct backing_store_struct * backing_store_ptr;
    +
    +typedef struct backing_store_struct {
    +  /* Methods for reading/writing/closing this backing-store object */
    +  JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
    +                                     backing_store_ptr info,
    +                                     void FAR * buffer_address,
    +                                     long file_offset, long byte_count));
    +  JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
    +                                      backing_store_ptr info,
    +                                      void FAR * buffer_address,
    +                                      long file_offset, long byte_count));
    +  JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
    +                                      backing_store_ptr info));
    +
    +  /* Private fields for system-dependent backing-store management */
    +#ifdef USE_MSDOS_MEMMGR
    +  /* For the MS-DOS manager (jmemdos.c), we need: */
    +  handle_union handle;          /* reference to backing-store storage object */
    +  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
    +#else
    +#ifdef USE_MAC_MEMMGR
    +  /* For the Mac manager (jmemmac.c), we need: */
    +  short temp_file;              /* file reference number to temp file */
    +  FSSpec tempSpec;              /* the FSSpec for the temp file */
    +  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
    +#else
    +  /* For a typical implementation with temp files, we need: */
    +  FILE * temp_file;             /* stdio reference to temp file */
    +  char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
    +#endif
    +#endif
    +} backing_store_info;
    +
    +
    +/*
    + * Initial opening of a backing-store object.  This must fill in the
    + * read/write/close pointers in the object.  The read/write routines
    + * may take an error exit if the specified maximum file size is exceeded.
    + * (If jpeg_mem_available always returns a large value, this routine can
    + * just take an error exit.)
    + */
    +
    +EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
    +                                          backing_store_ptr info,
    +                                          long total_bytes_needed));
    +
    +
    +/*
    + * These routines take care of any system-dependent initialization and
    + * cleanup required.  jpeg_mem_init will be called before anything is
    + * allocated (and, therefore, nothing in cinfo is of use except the error
    + * manager pointer).  It should return a suitable default value for
    + * max_memory_to_use; this may subsequently be overridden by the surrounding
    + * application.  (Note that max_memory_to_use is only important if
    + * jpeg_mem_available chooses to consult it ... no one else will.)
    + * jpeg_mem_term may assume that all requested memory has been freed and that
    + * all opened backing-store objects have been closed.
    + */
    +
    +EXTERN(size_t) jpeg_mem_init JPP((j_common_ptr cinfo));
    +EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmorecfg.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmorecfg.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jmorecfg.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jmorecfg.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,378 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jmorecfg.h
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains additional configuration options that customize the
    + * JPEG software for special applications or support machine-dependent
    + * optimizations.  Most users will not need to touch this file.
    + */
    +
    +
    +/*
    + * Define BITS_IN_JSAMPLE as either
    + *   8   for 8-bit sample values (the usual setting)
    + *   12  for 12-bit sample values
    + * Only 8 and 12 are legal data precisions for lossy JPEG according to the
    + * JPEG standard, and the IJG code does not support anything else!
    + * We do not support run-time selection of data precision, sorry.
    + */
    +
    +#define BITS_IN_JSAMPLE  8      /* use 8 or 12 */
    +
    +
    +/*
    + * Maximum number of components (color channels) allowed in JPEG image.
    + * To meet the letter of the JPEG spec, set this to 255.  However, darn
    + * few applications need more than 4 channels (maybe 5 for CMYK + alpha
    + * mask).  We recommend 10 as a reasonable compromise; use 4 if you are
    + * really short on memory.  (Each allowed component costs a hundred or so
    + * bytes of storage, whether actually used in an image or not.)
    + */
    +
    +#define MAX_COMPONENTS  10      /* maximum number of image components */
    +
    +
    +/*
    + * Basic data types.
    + * You may need to change these if you have a machine with unusual data
    + * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
    + * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits,
    + * but it had better be at least 16.
    + */
    +
    +/* Representation of a single sample (pixel element value).
    + * We frequently allocate large arrays of these, so it's important to keep
    + * them small.  But if you have memory to burn and access to char or short
    + * arrays is very slow on your hardware, you might want to change these.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +/* JSAMPLE should be the smallest type that will hold the values 0..255.
    + * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
    + */
    +
    +#ifdef HAVE_UNSIGNED_CHAR
    +
    +typedef unsigned char JSAMPLE;
    +#define GETJSAMPLE(value)  ((int) (value))
    +
    +#else /* not HAVE_UNSIGNED_CHAR */
    +
    +typedef char JSAMPLE;
    +#ifdef CHAR_IS_UNSIGNED
    +#define GETJSAMPLE(value)  ((int) (value))
    +#else
    +#define GETJSAMPLE(value)  ((int) (value) & 0xFF)
    +#endif /* CHAR_IS_UNSIGNED */
    +
    +#endif /* HAVE_UNSIGNED_CHAR */
    +
    +#define MAXJSAMPLE      255
    +#define CENTERJSAMPLE   128
    +
    +#endif /* BITS_IN_JSAMPLE == 8 */
    +
    +
    +#if BITS_IN_JSAMPLE == 12
    +/* JSAMPLE should be the smallest type that will hold the values 0..4095.
    + * On nearly all machines "short" will do nicely.
    + */
    +
    +typedef short JSAMPLE;
    +#define GETJSAMPLE(value)  ((int) (value))
    +
    +#define MAXJSAMPLE      4095
    +#define CENTERJSAMPLE   2048
    +
    +#endif /* BITS_IN_JSAMPLE == 12 */
    +
    +
    +/* Representation of a DCT frequency coefficient.
    + * This should be a signed value of at least 16 bits; "short" is usually OK.
    + * Again, we allocate large arrays of these, but you can change to int
    + * if you have memory to burn and "short" is really slow.
    + */
    +
    +typedef short JCOEF;
    +
    +
    +/* Compressed datastreams are represented as arrays of JOCTET.
    + * These must be EXACTLY 8 bits wide, at least once they are written to
    + * external storage.  Note that when using the stdio data source/destination
    + * managers, this is also the data type passed to fread/fwrite.
    + */
    +
    +#ifdef HAVE_UNSIGNED_CHAR
    +
    +typedef unsigned char JOCTET;
    +#define GETJOCTET(value)  (value)
    +
    +#else /* not HAVE_UNSIGNED_CHAR */
    +
    +typedef char JOCTET;
    +#ifdef CHAR_IS_UNSIGNED
    +#define GETJOCTET(value)  (value)
    +#else
    +#define GETJOCTET(value)  ((value) & 0xFF)
    +#endif /* CHAR_IS_UNSIGNED */
    +
    +#endif /* HAVE_UNSIGNED_CHAR */
    +
    +
    +/* These typedefs are used for various table entries and so forth.
    + * They must be at least as wide as specified; but making them too big
    + * won't cost a huge amount of memory, so we don't provide special
    + * extraction code like we did for JSAMPLE.  (In other words, these
    + * typedefs live at a different point on the speed/space tradeoff curve.)
    + */
    +
    +/* UINT8 must hold at least the values 0..255. */
    +
    +#ifdef HAVE_UNSIGNED_CHAR
    +typedef unsigned char UINT8;
    +#else /* not HAVE_UNSIGNED_CHAR */
    +#ifdef CHAR_IS_UNSIGNED
    +typedef char UINT8;
    +#else /* not CHAR_IS_UNSIGNED */
    +typedef short UINT8;
    +#endif /* CHAR_IS_UNSIGNED */
    +#endif /* HAVE_UNSIGNED_CHAR */
    +
    +/* UINT16 must hold at least the values 0..65535. */
    +
    +#ifdef HAVE_UNSIGNED_SHORT
    +typedef unsigned short UINT16;
    +#else /* not HAVE_UNSIGNED_SHORT */
    +typedef unsigned int UINT16;
    +#endif /* HAVE_UNSIGNED_SHORT */
    +
    +/* INT16 must hold at least the values -32768..32767. */
    +
    +#ifndef XMD_H                   /* X11/xmd.h correctly defines INT16 */
    +typedef short INT16;
    +#endif
    +
    +/* INT32 must hold at least signed 32-bit values. */
    +
    +#ifndef XMD_H                         /* X11/xmd.h correctly defines INT32 */
    +#if defined(_LP64) || defined(_WIN32) /* _WIN32 is on all windows platfroms (x86 and x64) */
    +typedef int INT32;
    +#else
    +typedef long INT32;
    +#endif
    +#endif
    +
    +/* Datatype used for image dimensions.  The JPEG standard only supports
    + * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore
    + * "unsigned int" is sufficient on all machines.  However, if you need to
    + * handle larger images and you don't mind deviating from the spec, you
    + * can change this datatype.
    + */
    +
    +typedef unsigned int JDIMENSION;
    +
    +#ifndef _LP64
    +#define JPEG_MAX_DIMENSION  65500L  /* a tad under 64K to prevent overflows */
    +#else
    +#define JPEG_MAX_DIMENSION  65500  /* a tad under 64K to prevent overflows */
    +#endif
    +
    +
    +/* These macros are used in all function definitions and extern declarations.
    + * You could modify them if you need to change function linkage conventions;
    + * in particular, you'll need to do that to make the library a Windows DLL.
    + * Another application is to make all functions global for use with debuggers
    + * or code profilers that require it.
    + */
    +
    +/* a function called through method pointers: */
    +#define METHODDEF(type)         static type
    +/* a function used only in its module: */
    +#define LOCAL(type)             static type
    +/* a function referenced thru EXTERNs: */
    +#define GLOBAL(type)            type
    +/* a reference to a GLOBAL function: */
    +#define EXTERN(type)            extern type
    +
    +
    +/* This macro is used to declare a "method", that is, a function pointer.
    + * We want to supply prototype parameters if the compiler can cope.
    + * Note that the arglist parameter must be parenthesized!
    + * Again, you can customize this if you need special linkage keywords.
    + */
    +
    +#ifdef HAVE_PROTOTYPES
    +#define JMETHOD(type,methodname,arglist)  type (*methodname) arglist
    +#else
    +#define JMETHOD(type,methodname,arglist)  type (*methodname) ()
    +#endif
    +
    +
    +/* Here is the pseudo-keyword for declaring pointers that must be "far"
    + * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
    + * by just saying "FAR *" where such a pointer is needed.  In a few places
    + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
    + */
    +
    +
    +#ifndef FAR
    +#ifdef NEED_FAR_POINTERS
    +#define FAR  far
    +#else
    +#define FAR
    +#endif
    +#endif
    +
    +
    +/*
    + * On a few systems, type boolean and/or its values FALSE, TRUE may appear
    + * in standard header files.  Or you may have conflicts with application-
    + * specific header files that you want to include together with these files.
    + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
    + */
    +
    +#ifndef HAVE_BOOLEAN
    +typedef int boolean;
    +#endif
    +#ifndef FALSE                   /* in case these macros already exist */
    +#define FALSE   0               /* values of boolean */
    +#endif
    +#ifndef TRUE
    +#define TRUE    1
    +#endif
    +
    +
    +/*
    + * The remaining options affect code selection within the JPEG library,
    + * but they don't need to be visible to most applications using the library.
    + * To minimize application namespace pollution, the symbols won't be
    + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
    + */
    +
    +#ifdef JPEG_INTERNALS
    +#define JPEG_INTERNAL_OPTIONS
    +#endif
    +
    +#ifdef JPEG_INTERNAL_OPTIONS
    +
    +
    +/*
    + * These defines indicate whether to include various optional functions.
    + * Undefining some of these symbols will produce a smaller but less capable
    + * library.  Note that you can leave certain source files out of the
    + * compilation/linking process if you've #undef'd the corresponding symbols.
    + * (You may HAVE to do that if your compiler doesn't like null source files.)
    + */
    +
    +/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
    +
    +/* Capability options common to encoder and decoder: */
    +
    +#define DCT_ISLOW_SUPPORTED     /* slow but accurate integer algorithm */
    +#define DCT_IFAST_SUPPORTED     /* faster, less accurate integer method */
    +#define DCT_FLOAT_SUPPORTED     /* floating-point: accurate, fast on fast HW */
    +
    +/* Encoder capability options: */
    +
    +#undef  C_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
    +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
    +#define C_PROGRESSIVE_SUPPORTED     /* Progressive JPEG? (Requires MULTISCAN)*/
    +#define ENTROPY_OPT_SUPPORTED       /* Optimization of entropy coding parms? */
    +/* Note: if you selected 12-bit data precision, it is dangerous to turn off
    + * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
    + * precision, so jchuff.c normally uses entropy optimization to compute
    + * usable tables for higher precision.  If you don't want to do optimization,
    + * you'll have to supply different default Huffman tables.
    + * The exact same statements apply for progressive JPEG: the default tables
    + * don't work for progressive mode.  (This may get fixed, however.)
    + */
    +#define INPUT_SMOOTHING_SUPPORTED   /* Input image smoothing option? */
    +
    +/* Decoder capability options: */
    +
    +#undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
    +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
    +#define D_PROGRESSIVE_SUPPORTED     /* Progressive JPEG? (Requires MULTISCAN)*/
    +#define SAVE_MARKERS_SUPPORTED      /* jpeg_save_markers() needed? */
    +#define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
    +#define IDCT_SCALING_SUPPORTED      /* Output rescaling via IDCT? */
    +#undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
    +#define UPSAMPLE_MERGING_SUPPORTED  /* Fast path for sloppy upsampling? */
    +#define QUANT_1PASS_SUPPORTED       /* 1-pass color quantization? */
    +#define QUANT_2PASS_SUPPORTED       /* 2-pass color quantization? */
    +
    +/* more capability options later, no doubt */
    +
    +
    +/*
    + * Ordering of RGB data in scanlines passed to or from the application.
    + * If your application wants to deal with data in the order B,G,R, just
    + * change these macros.  You can also deal with formats such as R,G,B,X
    + * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing
    + * the offsets will also change the order in which colormap data is organized.
    + * RESTRICTIONS:
    + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
    + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
    + *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
    + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
    + *    is not 3 (they don't understand about dummy color components!).  So you
    + *    can't use color quantization if you change that value.
    + */
    +
    +#define RGB_RED         0       /* Offset of Red in an RGB scanline element */
    +#define RGB_GREEN       1       /* Offset of Green */
    +#define RGB_BLUE        2       /* Offset of Blue */
    +#define RGB_PIXELSIZE   3       /* JSAMPLEs per RGB scanline element */
    +
    +
    +/* Definitions for speed-related optimizations. */
    +
    +
    +/* If your compiler supports inline functions, define INLINE
    + * as the inline keyword; otherwise define it as empty.
    + */
    +
    +#ifndef INLINE
    +#ifdef __GNUC__                 /* for instance, GNU C knows about inline */
    +#define INLINE __inline__
    +#endif
    +#ifndef INLINE
    +#define INLINE                  /* default is to define it as empty */
    +#endif
    +#endif
    +
    +
    +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
    + * two 16-bit shorts is faster than multiplying two ints.  Define MULTIPLIER
    + * as short on such a machine.  MULTIPLIER must be at least 16 bits wide.
    + */
    +
    +#ifndef MULTIPLIER
    +#define MULTIPLIER  int         /* type for fastest integer multiply */
    +#endif
    +
    +
    +/* FAST_FLOAT should be either float or double, whichever is done faster
    + * by your compiler.  (Note that this type is only used in the floating point
    + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
    + * Typically, float is faster in ANSI C compilers, while double is faster in
    + * pre-ANSI compilers (because they insist on converting to double anyway).
    + * The code below therefore chooses float if we have ANSI-style prototypes.
    + */
    +
    +#ifndef FAST_FLOAT
    +#ifdef HAVE_PROTOTYPES
    +#define FAST_FLOAT  float
    +#else
    +#define FAST_FLOAT  double
    +#endif
    +#endif
    +
    +#endif /* JPEG_INTERNAL_OPTIONS */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jpegint.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jpegint.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jpegint.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jpegint.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,396 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jpegint.h
    + *
    + * Copyright (C) 1991-1997, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file provides common declarations for the various JPEG modules.
    + * These declarations are considered internal to the JPEG library; most
    + * applications using the library shouldn't need to include this file.
    + */
    +
    +
    +/* Declarations for both compression & decompression */
    +
    +typedef enum {                  /* Operating modes for buffer controllers */
    +        JBUF_PASS_THRU,         /* Plain stripwise operation */
    +        /* Remaining modes require a full-image buffer to have been created */
    +        JBUF_SAVE_SOURCE,       /* Run source subobject only, save output */
    +        JBUF_CRANK_DEST,        /* Run dest subobject only, using saved data */
    +        JBUF_SAVE_AND_PASS      /* Run both subobjects, save output */
    +} J_BUF_MODE;
    +
    +/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
    +#define CSTATE_START    100     /* after create_compress */
    +#define CSTATE_SCANNING 101     /* start_compress done, write_scanlines OK */
    +#define CSTATE_RAW_OK   102     /* start_compress done, write_raw_data OK */
    +#define CSTATE_WRCOEFS  103     /* jpeg_write_coefficients done */
    +#define DSTATE_START    200     /* after create_decompress */
    +#define DSTATE_INHEADER 201     /* reading header markers, no SOS yet */
    +#define DSTATE_READY    202     /* found SOS, ready for start_decompress */
    +#define DSTATE_PRELOAD  203     /* reading multiscan file in start_decompress*/
    +#define DSTATE_PRESCAN  204     /* performing dummy pass for 2-pass quant */
    +#define DSTATE_SCANNING 205     /* start_decompress done, read_scanlines OK */
    +#define DSTATE_RAW_OK   206     /* start_decompress done, read_raw_data OK */
    +#define DSTATE_BUFIMAGE 207     /* expecting jpeg_start_output */
    +#define DSTATE_BUFPOST  208     /* looking for SOS/EOI in jpeg_finish_output */
    +#define DSTATE_RDCOEFS  209     /* reading file in jpeg_read_coefficients */
    +#define DSTATE_STOPPING 210     /* looking for EOI in jpeg_finish_decompress */
    +
    +
    +/* Declarations for compression modules */
    +
    +/* Master control module */
    +struct jpeg_comp_master {
    +  JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
    +  JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
    +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
    +
    +  /* State variables made visible to other modules */
    +  boolean call_pass_startup;    /* True if pass_startup must be called */
    +  boolean is_last_pass;         /* True during last pass */
    +};
    +
    +/* Main buffer control (downsampled-data buffer) */
    +struct jpeg_c_main_controller {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
    +  JMETHOD(void, process_data, (j_compress_ptr cinfo,
    +                               JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
    +                               JDIMENSION in_rows_avail));
    +};
    +
    +/* Compression preprocessing (downsampling input buffer control) */
    +struct jpeg_c_prep_controller {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
    +  JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
    +                                   JSAMPARRAY input_buf,
    +                                   JDIMENSION *in_row_ctr,
    +                                   JDIMENSION in_rows_avail,
    +                                   JSAMPIMAGE output_buf,
    +                                   JDIMENSION *out_row_group_ctr,
    +                                   JDIMENSION out_row_groups_avail));
    +};
    +
    +/* Coefficient buffer control */
    +struct jpeg_c_coef_controller {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
    +  JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
    +                                   JSAMPIMAGE input_buf));
    +};
    +
    +/* Colorspace conversion */
    +struct jpeg_color_converter {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
    +  JMETHOD(void, color_convert, (j_compress_ptr cinfo,
    +                                JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
    +                                JDIMENSION output_row, int num_rows));
    +};
    +
    +/* Downsampling */
    +struct jpeg_downsampler {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
    +  JMETHOD(void, downsample, (j_compress_ptr cinfo,
    +                             JSAMPIMAGE input_buf, JDIMENSION in_row_index,
    +                             JSAMPIMAGE output_buf,
    +                             JDIMENSION out_row_group_index));
    +
    +  boolean need_context_rows;    /* TRUE if need rows above & below */
    +};
    +
    +/* Forward DCT (also controls coefficient quantization) */
    +struct jpeg_forward_dct {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo));
    +  /* perhaps this should be an array??? */
    +  JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
    +                              jpeg_component_info * compptr,
    +                              JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
    +                              JDIMENSION start_row, JDIMENSION start_col,
    +                              JDIMENSION num_blocks));
    +};
    +
    +/* Entropy encoding */
    +struct jpeg_entropy_encoder {
    +  JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
    +  JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
    +  JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
    +};
    +
    +/* Marker writing */
    +struct jpeg_marker_writer {
    +  JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
    +  JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
    +  JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
    +  JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
    +  JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
    +  /* These routines are exported to allow insertion of extra markers */
    +  /* Probably only COM and APPn markers should be written this way */
    +  JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
    +                                      unsigned int datalen));
    +  JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
    +};
    +
    +
    +/* Declarations for decompression modules */
    +
    +/* Master control module */
    +struct jpeg_decomp_master {
    +  JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
    +
    +  /* State variables made visible to other modules */
    +  boolean is_dummy_pass;        /* True during 1st pass for 2-pass quant */
    +};
    +
    +/* Input control module */
    +struct jpeg_input_controller {
    +  JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
    +  JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
    +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
    +
    +  /* State variables made visible to other modules */
    +  boolean has_multiple_scans;   /* True if file has multiple scans */
    +  boolean eoi_reached;          /* True when EOI has been consumed */
    +};
    +
    +/* Main buffer control (downsampled-data buffer) */
    +struct jpeg_d_main_controller {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
    +  JMETHOD(void, process_data, (j_decompress_ptr cinfo,
    +                               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    +                               JDIMENSION out_rows_avail));
    +};
    +
    +/* Coefficient buffer control */
    +struct jpeg_d_coef_controller {
    +  JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
    +  JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
    +                                 JSAMPIMAGE output_buf));
    +  /* Pointer to array of coefficient virtual arrays, or NULL if none */
    +  jvirt_barray_ptr *coef_arrays;
    +};
    +
    +/* Decompression postprocessing (color quantization buffer control) */
    +struct jpeg_d_post_controller {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
    +  JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
    +                                    JSAMPIMAGE input_buf,
    +                                    JDIMENSION *in_row_group_ctr,
    +                                    JDIMENSION in_row_groups_avail,
    +                                    JSAMPARRAY output_buf,
    +                                    JDIMENSION *out_row_ctr,
    +                                    JDIMENSION out_rows_avail));
    +};
    +
    +/* Marker reading & parsing */
    +struct jpeg_marker_reader {
    +  JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
    +  /* Read markers until SOS or EOI.
    +   * Returns same codes as are defined for jpeg_consume_input:
    +   * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
    +   */
    +  JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
    +  /* Read a restart marker --- exported for use by entropy decoder only */
    +  jpeg_marker_parser_method read_restart_marker;
    +
    +  /* State of marker reader --- nominally internal, but applications
    +   * supplying COM or APPn handlers might like to know the state.
    +   */
    +  boolean saw_SOI;              /* found SOI? */
    +  boolean saw_SOF;              /* found SOF? */
    +  int next_restart_num;         /* next restart number expected (0-7) */
    +  unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
    +};
    +
    +/* Entropy decoding */
    +struct jpeg_entropy_decoder {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
    +                                JBLOCKROW *MCU_data));
    +
    +  /* This is here to share code between baseline and progressive decoders; */
    +  /* other modules probably should not use it */
    +  boolean insufficient_data;    /* set TRUE after emitting warning */
    +};
    +
    +/* Inverse DCT (also performs dequantization) */
    +typedef JMETHOD(void, inverse_DCT_method_ptr,
    +                (j_decompress_ptr cinfo, jpeg_component_info * compptr,
    +                 JCOEFPTR coef_block,
    +                 JSAMPARRAY output_buf, JDIMENSION output_col));
    +
    +struct jpeg_inverse_dct {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
    +  /* It is useful to allow each component to have a separate IDCT method. */
    +  inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
    +};
    +
    +/* Upsampling (note that upsampler must also call color converter) */
    +struct jpeg_upsampler {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(void, upsample, (j_decompress_ptr cinfo,
    +                           JSAMPIMAGE input_buf,
    +                           JDIMENSION *in_row_group_ctr,
    +                           JDIMENSION in_row_groups_avail,
    +                           JSAMPARRAY output_buf,
    +                           JDIMENSION *out_row_ctr,
    +                           JDIMENSION out_rows_avail));
    +
    +  boolean need_context_rows;    /* TRUE if need rows above & below */
    +};
    +
    +/* Colorspace conversion */
    +struct jpeg_color_deconverter {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
    +                                JSAMPIMAGE input_buf, JDIMENSION input_row,
    +                                JSAMPARRAY output_buf, int num_rows));
    +};
    +
    +/* Color quantization or color precision reduction */
    +struct jpeg_color_quantizer {
    +  JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
    +  JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
    +                                 JSAMPARRAY input_buf, JSAMPARRAY output_buf,
    +                                 int num_rows));
    +  JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
    +  JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
    +};
    +
    +
    +/* Miscellaneous useful macros */
    +
    +#undef MAX
    +#define MAX(a,b)        ((a) > (b) ? (a) : (b))
    +#undef MIN
    +#define MIN(a,b)        ((a) < (b) ? (a) : (b))
    +
    +
    +/* We assume that right shift corresponds to signed division by 2 with
    + * rounding towards minus infinity.  This is correct for typical "arithmetic
    + * shift" instructions that shift in copies of the sign bit.  But some
    + * C compilers implement >> with an unsigned shift.  For these machines you
    + * must define RIGHT_SHIFT_IS_UNSIGNED.
    + * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
    + * It is only applied with constant shift counts.  SHIFT_TEMPS must be
    + * included in the variables of any routine using RIGHT_SHIFT.
    + */
    +
    +#ifdef RIGHT_SHIFT_IS_UNSIGNED
    +#define SHIFT_TEMPS     INT32 shift_temp;
    +#define RIGHT_SHIFT(x,shft)  \
    +        ((shift_temp = (x)) < 0 ? \
    +         (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
    +         (shift_temp >> (shft)))
    +#else
    +#define SHIFT_TEMPS
    +#define RIGHT_SHIFT(x,shft)     ((x) >> (shft))
    +#endif
    +
    +
    +/* Short forms of external names for systems with brain-damaged linkers. */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jinit_compress_master   jICompress
    +#define jinit_c_master_control  jICMaster
    +#define jinit_c_main_controller jICMainC
    +#define jinit_c_prep_controller jICPrepC
    +#define jinit_c_coef_controller jICCoefC
    +#define jinit_color_converter   jICColor
    +#define jinit_downsampler       jIDownsampler
    +#define jinit_forward_dct       jIFDCT
    +#define jinit_huff_encoder      jIHEncoder
    +#define jinit_phuff_encoder     jIPHEncoder
    +#define jinit_marker_writer     jIMWriter
    +#define jinit_master_decompress jIDMaster
    +#define jinit_d_main_controller jIDMainC
    +#define jinit_d_coef_controller jIDCoefC
    +#define jinit_d_post_controller jIDPostC
    +#define jinit_input_controller  jIInCtlr
    +#define jinit_marker_reader     jIMReader
    +#define jinit_huff_decoder      jIHDecoder
    +#define jinit_phuff_decoder     jIPHDecoder
    +#define jinit_inverse_dct       jIIDCT
    +#define jinit_upsampler         jIUpsampler
    +#define jinit_color_deconverter jIDColor
    +#define jinit_1pass_quantizer   jI1Quant
    +#define jinit_2pass_quantizer   jI2Quant
    +#define jinit_merged_upsampler  jIMUpsampler
    +#define jinit_memory_mgr        jIMemMgr
    +#define jdiv_round_up           jDivRound
    +#define jround_up               jRound
    +#define jcopy_sample_rows       jCopySamples
    +#define jcopy_block_row         jCopyBlocks
    +#define jzero_far               jZeroFar
    +#define jpeg_zigzag_order       jZIGTable
    +#define jpeg_natural_order      jZAGTable
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +
    +/* Compression module initialization routines */
    +EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
    +                                         boolean transcode_only));
    +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
    +EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
    +/* Decompression module initialization routines */
    +EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
    +                                          boolean need_full_buffer));
    +EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
    +/* Memory manager initialization */
    +EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
    +
    +/* Utility routines in jutils.c */
    +EXTERN(long) jdiv_round_up JPP((long a, long b));
    +EXTERN(long) jround_up JPP((long a, long b));
    +EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
    +                                    JSAMPARRAY output_array, int dest_row,
    +                                    int num_rows, JDIMENSION num_cols));
    +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
    +                                  JDIMENSION num_blocks));
    +EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
    +/* Constant tables in jutils.c */
    +#if 0                           /* This table is not actually needed in v6a */
    +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
    +#endif
    +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
    +
    +/* Suppress undefined-structure complaints if necessary. */
    +
    +#ifdef INCOMPLETE_TYPES_BROKEN
    +#ifndef AM_MEMORY_MANAGER       /* only jmemmgr.c defines these */
    +struct jvirt_sarray_control { long dummy; };
    +struct jvirt_barray_control { long dummy; };
    +#endif
    +#endif /* INCOMPLETE_TYPES_BROKEN */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jpeglib.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jpeglib.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jpeglib.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jpeglib.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1100 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jpeglib.h
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file defines the application interface for the JPEG library.
    + * Most applications using the library need only include this file,
    + * and perhaps jerror.h if they want to know the exact error codes.
    + */
    +
    +#ifndef JPEGLIB_H
    +#define JPEGLIB_H
    +
    +/*
    + * First we include the configuration files that record how this
    + * installation of the JPEG library is set up.  jconfig.h can be
    + * generated automatically for many systems.  jmorecfg.h contains
    + * manual configuration options that most people need not worry about.
    + */
    +
    +#ifndef JCONFIG_INCLUDED        /* in case jinclude.h already did */
    +#include "jconfig.h"            /* widely used configuration options */
    +#endif
    +#include "jmorecfg.h"           /* seldom changed options */
    +
    +
    +/* Version ID for the JPEG library.
    + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
    + */
    +
    +#define JPEG_LIB_VERSION  62    /* Version 6b */
    +
    +
    +/* Various constants determining the sizes of things.
    + * All of these are specified by the JPEG standard, so don't change them
    + * if you want to be compatible.
    + */
    +
    +#define DCTSIZE             8   /* The basic DCT block is 8x8 samples */
    +#define DCTSIZE2            64  /* DCTSIZE squared; # of elements in a block */
    +#define NUM_QUANT_TBLS      4   /* Quantization tables are numbered 0..3 */
    +#define NUM_HUFF_TBLS       4   /* Huffman tables are numbered 0..3 */
    +#define NUM_ARITH_TBLS      16  /* Arith-coding tables are numbered 0..15 */
    +#define MAX_COMPS_IN_SCAN   4   /* JPEG limit on # of components in one scan */
    +#define MAX_SAMP_FACTOR     4   /* JPEG limit on sampling factors */
    +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
    + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
    + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
    + * to handle it.  We even let you do this from the jconfig.h file.  However,
    + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
    + * sometimes emits noncompliant files doesn't mean you should too.
    + */
    +#define C_MAX_BLOCKS_IN_MCU   10 /* compressor's limit on blocks per MCU */
    +#ifndef D_MAX_BLOCKS_IN_MCU
    +#define D_MAX_BLOCKS_IN_MCU   10 /* decompressor's limit on blocks per MCU */
    +#endif
    +
    +
    +/* Data structures for images (arrays of samples and of DCT coefficients).
    + * On 80x86 machines, the image arrays are too big for near pointers,
    + * but the pointer arrays can fit in near memory.
    + */
    +
    +typedef JSAMPLE FAR *JSAMPROW;  /* ptr to one image row of pixel samples. */
    +typedef JSAMPROW *JSAMPARRAY;   /* ptr to some rows (a 2-D sample array) */
    +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
    +
    +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
    +typedef JBLOCK FAR *JBLOCKROW;  /* pointer to one row of coefficient blocks */
    +typedef JBLOCKROW *JBLOCKARRAY;         /* a 2-D array of coefficient blocks */
    +typedef JBLOCKARRAY *JBLOCKIMAGE;       /* a 3-D array of coefficient blocks */
    +
    +typedef JCOEF FAR *JCOEFPTR;    /* useful in a couple of places */
    +
    +
    +/* Types for JPEG compression parameters and working tables. */
    +
    +
    +/* DCT coefficient quantization tables. */
    +
    +typedef struct {
    +  /* This array gives the coefficient quantizers in natural array order
    +   * (not the zigzag order in which they are stored in a JPEG DQT marker).
    +   * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
    +   */
    +  UINT16 quantval[DCTSIZE2];    /* quantization step for each coefficient */
    +  /* This field is used only during compression.  It's initialized FALSE when
    +   * the table is created, and set TRUE when it's been output to the file.
    +   * You could suppress output of a table by setting this to TRUE.
    +   * (See jpeg_suppress_tables for an example.)
    +   */
    +  boolean sent_table;           /* TRUE when table has been output */
    +} JQUANT_TBL;
    +
    +
    +/* Huffman coding tables. */
    +
    +typedef struct {
    +  /* These two fields directly represent the contents of a JPEG DHT marker */
    +  UINT8 bits[17];               /* bits[k] = # of symbols with codes of */
    +                                /* length k bits; bits[0] is unused */
    +  UINT8 huffval[256];           /* The symbols, in order of incr code length */
    +  /* This field is used only during compression.  It's initialized FALSE when
    +   * the table is created, and set TRUE when it's been output to the file.
    +   * You could suppress output of a table by setting this to TRUE.
    +   * (See jpeg_suppress_tables for an example.)
    +   */
    +  boolean sent_table;           /* TRUE when table has been output */
    +} JHUFF_TBL;
    +
    +
    +/* Basic info about one component (color channel). */
    +
    +typedef struct {
    +  /* These values are fixed over the whole image. */
    +  /* For compression, they must be supplied by parameter setup; */
    +  /* for decompression, they are read from the SOF marker. */
    +  int component_id;             /* identifier for this component (0..255) */
    +  int component_index;          /* its index in SOF or cinfo->comp_info[] */
    +  int h_samp_factor;            /* horizontal sampling factor (1..4) */
    +  int v_samp_factor;            /* vertical sampling factor (1..4) */
    +  int quant_tbl_no;             /* quantization table selector (0..3) */
    +  /* These values may vary between scans. */
    +  /* For compression, they must be supplied by parameter setup; */
    +  /* for decompression, they are read from the SOS marker. */
    +  /* The decompressor output side may not use these variables. */
    +  int dc_tbl_no;                /* DC entropy table selector (0..3) */
    +  int ac_tbl_no;                /* AC entropy table selector (0..3) */
    +
    +  /* Remaining fields should be treated as private by applications. */
    +
    +  /* These values are computed during compression or decompression startup: */
    +  /* Component's size in DCT blocks.
    +   * Any dummy blocks added to complete an MCU are not counted; therefore
    +   * these values do not depend on whether a scan is interleaved or not.
    +   */
    +  JDIMENSION width_in_blocks;
    +  JDIMENSION height_in_blocks;
    +  /* Size of a DCT block in samples.  Always DCTSIZE for compression.
    +   * For decompression this is the size of the output from one DCT block,
    +   * reflecting any scaling we choose to apply during the IDCT step.
    +   * Values of 1,2,4,8 are likely to be supported.  Note that different
    +   * components may receive different IDCT scalings.
    +   */
    +  int DCT_scaled_size;
    +  /* The downsampled dimensions are the component's actual, unpadded number
    +   * of samples at the main buffer (preprocessing/compression interface), thus
    +   * downsampled_width = ceil(image_width * Hi/Hmax)
    +   * and similarly for height.  For decompression, IDCT scaling is included, so
    +   * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
    +   */
    +  JDIMENSION downsampled_width;  /* actual width in samples */
    +  JDIMENSION downsampled_height; /* actual height in samples */
    +  /* This flag is used only for decompression.  In cases where some of the
    +   * components will be ignored (eg grayscale output from YCbCr image),
    +   * we can skip most computations for the unused components.
    +   */
    +  boolean component_needed;     /* do we need the value of this component? */
    +
    +  /* These values are computed before starting a scan of the component. */
    +  /* The decompressor output side may not use these variables. */
    +  int MCU_width;                /* number of blocks per MCU, horizontally */
    +  int MCU_height;               /* number of blocks per MCU, vertically */
    +  int MCU_blocks;               /* MCU_width * MCU_height */
    +  int MCU_sample_width;         /* MCU width in samples, MCU_width*DCT_scaled_size */
    +  int last_col_width;           /* # of non-dummy blocks across in last MCU */
    +  int last_row_height;          /* # of non-dummy blocks down in last MCU */
    +
    +  /* Saved quantization table for component; NULL if none yet saved.
    +   * See jdinput.c comments about the need for this information.
    +   * This field is currently used only for decompression.
    +   */
    +  JQUANT_TBL * quant_table;
    +
    +  /* Private per-component storage for DCT or IDCT subsystem. */
    +  void * dct_table;
    +} jpeg_component_info;
    +
    +
    +/* The script for encoding a multiple-scan file is an array of these: */
    +
    +typedef struct {
    +  int comps_in_scan;            /* number of components encoded in this scan */
    +  int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
    +  int Ss, Se;                   /* progressive JPEG spectral selection parms */
    +  int Ah, Al;                   /* progressive JPEG successive approx. parms */
    +} jpeg_scan_info;
    +
    +/* The decompressor can save APPn and COM markers in a list of these: */
    +
    +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
    +
    +struct jpeg_marker_struct {
    +  jpeg_saved_marker_ptr next;   /* next in list, or NULL */
    +  UINT8 marker;                 /* marker code: JPEG_COM, or JPEG_APP0+n */
    +  unsigned int original_length; /* # bytes of data in the file */
    +  unsigned int data_length;     /* # bytes of data saved at data[] */
    +  JOCTET FAR * data;            /* the data contained in the marker */
    +  /* the marker length word is not counted in data_length or original_length */
    +};
    +
    +/* Known color spaces. */
    +
    +typedef enum {
    +        JCS_UNKNOWN,            /* error/unspecified */
    +        JCS_GRAYSCALE,          /* monochrome */
    +        JCS_RGB,                /* red/green/blue */
    +        JCS_YCbCr,              /* Y/Cb/Cr (also known as YUV) */
    +        JCS_CMYK,               /* C/M/Y/K */
    +        JCS_YCCK                /* Y/Cb/Cr/K */
    +} J_COLOR_SPACE;
    +
    +/* DCT/IDCT algorithm options. */
    +
    +typedef enum {
    +        JDCT_ISLOW,             /* slow but accurate integer algorithm */
    +        JDCT_IFAST,             /* faster, less accurate integer method */
    +        JDCT_FLOAT              /* floating-point: accurate, fast on fast HW */
    +} J_DCT_METHOD;
    +
    +#ifndef JDCT_DEFAULT            /* may be overridden in jconfig.h */
    +#define JDCT_DEFAULT  JDCT_ISLOW
    +#endif
    +#ifndef JDCT_FASTEST            /* may be overridden in jconfig.h */
    +#define JDCT_FASTEST  JDCT_IFAST
    +#endif
    +
    +/* Dithering options for decompression. */
    +
    +typedef enum {
    +        JDITHER_NONE,           /* no dithering */
    +        JDITHER_ORDERED,        /* simple ordered dither */
    +        JDITHER_FS              /* Floyd-Steinberg error diffusion dither */
    +} J_DITHER_MODE;
    +
    +
    +/* Common fields between JPEG compression and decompression master structs. */
    +
    +#define jpeg_common_fields \
    +  struct jpeg_error_mgr * err;  /* Error handler module */\
    +  struct jpeg_memory_mgr * mem; /* Memory manager module */\
    +  struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
    +  void * client_data;           /* Available for use by application */\
    +  boolean is_decompressor;      /* So common code can tell which is which */\
    +  int global_state              /* For checking call sequence validity */
    +
    +/* Routines that are to be used by both halves of the library are declared
    + * to receive a pointer to this structure.  There are no actual instances of
    + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
    + */
    +struct jpeg_common_struct {
    +  jpeg_common_fields;           /* Fields common to both master struct types */
    +  /* Additional fields follow in an actual jpeg_compress_struct or
    +   * jpeg_decompress_struct.  All three structs must agree on these
    +   * initial fields!  (This would be a lot cleaner in C++.)
    +   */
    +};
    +
    +typedef struct jpeg_common_struct * j_common_ptr;
    +typedef struct jpeg_compress_struct * j_compress_ptr;
    +typedef struct jpeg_decompress_struct * j_decompress_ptr;
    +
    +
    +/* Master record for a compression instance */
    +
    +struct jpeg_compress_struct {
    +  jpeg_common_fields;           /* Fields shared with jpeg_decompress_struct */
    +
    +  /* Destination for compressed data */
    +  struct jpeg_destination_mgr * dest;
    +
    +  /* Description of source image --- these fields must be filled in by
    +   * outer application before starting compression.  in_color_space must
    +   * be correct before you can even call jpeg_set_defaults().
    +   */
    +
    +  JDIMENSION image_width;       /* input image width */
    +  JDIMENSION image_height;      /* input image height */
    +  int input_components;         /* # of color components in input image */
    +  J_COLOR_SPACE in_color_space; /* colorspace of input image */
    +
    +  double input_gamma;           /* image gamma of input image */
    +
    +  /* Compression parameters --- these fields must be set before calling
    +   * jpeg_start_compress().  We recommend calling jpeg_set_defaults() to
    +   * initialize everything to reasonable defaults, then changing anything
    +   * the application specifically wants to change.  That way you won't get
    +   * burnt when new parameters are added.  Also note that there are several
    +   * helper routines to simplify changing parameters.
    +   */
    +
    +  int data_precision;           /* bits of precision in image data */
    +
    +  int num_components;           /* # of color components in JPEG image */
    +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
    +
    +  jpeg_component_info * comp_info;
    +  /* comp_info[i] describes component that appears i'th in SOF */
    +
    +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
    +  /* ptrs to coefficient quantization tables, or NULL if not defined */
    +
    +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
    +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
    +  /* ptrs to Huffman coding tables, or NULL if not defined */
    +
    +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
    +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
    +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
    +
    +  int num_scans;                /* # of entries in scan_info array */
    +  const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
    +  /* The default value of scan_info is NULL, which causes a single-scan
    +   * sequential JPEG file to be emitted.  To create a multi-scan file,
    +   * set num_scans and scan_info to point to an array of scan definitions.
    +   */
    +
    +  boolean raw_data_in;          /* TRUE=caller supplies downsampled data */
    +  boolean arith_code;           /* TRUE=arithmetic coding, FALSE=Huffman */
    +  boolean optimize_coding;      /* TRUE=optimize entropy encoding parms */
    +  boolean CCIR601_sampling;     /* TRUE=first samples are cosited */
    +  int smoothing_factor;         /* 1..100, or 0 for no input smoothing */
    +  J_DCT_METHOD dct_method;      /* DCT algorithm selector */
    +
    +  /* The restart interval can be specified in absolute MCUs by setting
    +   * restart_interval, or in MCU rows by setting restart_in_rows
    +   * (in which case the correct restart_interval will be figured
    +   * for each scan).
    +   */
    +  unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
    +  int restart_in_rows;          /* if > 0, MCU rows per restart interval */
    +
    +  /* Parameters controlling emission of special markers. */
    +
    +  boolean write_JFIF_header;    /* should a JFIF marker be written? */
    +  UINT8 JFIF_major_version;     /* What to write for the JFIF version number */
    +  UINT8 JFIF_minor_version;
    +  /* These three values are not used by the JPEG code, merely copied */
    +  /* into the JFIF APP0 marker.  density_unit can be 0 for unknown, */
    +  /* 1 for dots/inch, or 2 for dots/cm.  Note that the pixel aspect */
    +  /* ratio is defined by X_density/Y_density even when density_unit=0. */
    +  UINT8 density_unit;           /* JFIF code for pixel size units */
    +  UINT16 X_density;             /* Horizontal pixel density */
    +  UINT16 Y_density;             /* Vertical pixel density */
    +  boolean write_Adobe_marker;   /* should an Adobe marker be written? */
    +
    +  /* State variable: index of next scanline to be written to
    +   * jpeg_write_scanlines().  Application may use this to control its
    +   * processing loop, e.g., "while (next_scanline < image_height)".
    +   */
    +
    +  JDIMENSION next_scanline;     /* 0 .. image_height-1  */
    +
    +  /* Remaining fields are known throughout compressor, but generally
    +   * should not be touched by a surrounding application.
    +   */
    +
    +  /*
    +   * These fields are computed during compression startup
    +   */
    +  boolean progressive_mode;     /* TRUE if scan script uses progressive mode */
    +  int max_h_samp_factor;        /* largest h_samp_factor */
    +  int max_v_samp_factor;        /* largest v_samp_factor */
    +
    +  JDIMENSION total_iMCU_rows;   /* # of iMCU rows to be input to coef ctlr */
    +  /* The coefficient controller receives data in units of MCU rows as defined
    +   * for fully interleaved scans (whether the JPEG file is interleaved or not).
    +   * There are v_samp_factor * DCTSIZE sample rows of each component in an
    +   * "iMCU" (interleaved MCU) row.
    +   */
    +
    +  /*
    +   * These fields are valid during any one scan.
    +   * They describe the components and MCUs actually appearing in the scan.
    +   */
    +  int comps_in_scan;            /* # of JPEG components in this scan */
    +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
    +  /* *cur_comp_info[i] describes component that appears i'th in SOS */
    +
    +  JDIMENSION MCUs_per_row;      /* # of MCUs across the image */
    +  JDIMENSION MCU_rows_in_scan;  /* # of MCU rows in the image */
    +
    +  int blocks_in_MCU;            /* # of DCT blocks per MCU */
    +  int MCU_membership[C_MAX_BLOCKS_IN_MCU];
    +  /* MCU_membership[i] is index in cur_comp_info of component owning */
    +  /* i'th block in an MCU */
    +
    +  int Ss, Se, Ah, Al;           /* progressive JPEG parameters for scan */
    +
    +  /*
    +   * Links to compression subobjects (methods and private variables of modules)
    +   */
    +  struct jpeg_comp_master * master;
    +  struct jpeg_c_main_controller * main;
    +  struct jpeg_c_prep_controller * prep;
    +  struct jpeg_c_coef_controller * coef;
    +  struct jpeg_marker_writer * marker;
    +  struct jpeg_color_converter * cconvert;
    +  struct jpeg_downsampler * downsample;
    +  struct jpeg_forward_dct * fdct;
    +  struct jpeg_entropy_encoder * entropy;
    +  jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
    +  int script_space_size;
    +};
    +
    +
    +/* Master record for a decompression instance */
    +
    +struct jpeg_decompress_struct {
    +  jpeg_common_fields;           /* Fields shared with jpeg_compress_struct */
    +
    +  /* Source of compressed data */
    +  struct jpeg_source_mgr * src;
    +
    +  /* Basic description of image --- filled in by jpeg_read_header(). */
    +  /* Application may inspect these values to decide how to process image. */
    +
    +  JDIMENSION image_width;       /* nominal image width (from SOF marker) */
    +  JDIMENSION image_height;      /* nominal image height */
    +  int num_components;           /* # of color components in JPEG image */
    +  J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
    +
    +  /* Decompression processing parameters --- these fields must be set before
    +   * calling jpeg_start_decompress().  Note that jpeg_read_header() initializes
    +   * them to default values.
    +   */
    +
    +  J_COLOR_SPACE out_color_space; /* colorspace for output */
    +
    +  unsigned int scale_num, scale_denom; /* fraction by which to scale image */
    +
    +  double output_gamma;          /* image gamma wanted in output */
    +
    +  boolean buffered_image;       /* TRUE=multiple output passes */
    +  boolean raw_data_out;         /* TRUE=downsampled data wanted */
    +
    +  J_DCT_METHOD dct_method;      /* IDCT algorithm selector */
    +  boolean do_fancy_upsampling;  /* TRUE=apply fancy upsampling */
    +  boolean do_block_smoothing;   /* TRUE=apply interblock smoothing */
    +
    +  boolean quantize_colors;      /* TRUE=colormapped output wanted */
    +  /* the following are ignored if not quantize_colors: */
    +  J_DITHER_MODE dither_mode;    /* type of color dithering to use */
    +  boolean two_pass_quantize;    /* TRUE=use two-pass color quantization */
    +  int desired_number_of_colors; /* max # colors to use in created colormap */
    +  /* these are significant only in buffered-image mode: */
    +  boolean enable_1pass_quant;   /* enable future use of 1-pass quantizer */
    +  boolean enable_external_quant;/* enable future use of external colormap */
    +  boolean enable_2pass_quant;   /* enable future use of 2-pass quantizer */
    +
    +  /* Description of actual output image that will be returned to application.
    +   * These fields are computed by jpeg_start_decompress().
    +   * You can also use jpeg_calc_output_dimensions() to determine these values
    +   * in advance of calling jpeg_start_decompress().
    +   */
    +
    +  JDIMENSION output_width;      /* scaled image width */
    +  JDIMENSION output_height;     /* scaled image height */
    +  int out_color_components;     /* # of color components in out_color_space */
    +  int output_components;        /* # of color components returned */
    +  /* output_components is 1 (a colormap index) when quantizing colors;
    +   * otherwise it equals out_color_components.
    +   */
    +  int rec_outbuf_height;        /* min recommended height of scanline buffer */
    +  /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
    +   * high, space and time will be wasted due to unnecessary data copying.
    +   * Usually rec_outbuf_height will be 1 or 2, at most 4.
    +   */
    +
    +  /* When quantizing colors, the output colormap is described by these fields.
    +   * The application can supply a colormap by setting colormap non-NULL before
    +   * calling jpeg_start_decompress; otherwise a colormap is created during
    +   * jpeg_start_decompress or jpeg_start_output.
    +   * The map has out_color_components rows and actual_number_of_colors columns.
    +   */
    +  int actual_number_of_colors;  /* number of entries in use */
    +  JSAMPARRAY colormap;          /* The color map as a 2-D pixel array */
    +
    +  /* State variables: these variables indicate the progress of decompression.
    +   * The application may examine these but must not modify them.
    +   */
    +
    +  /* Row index of next scanline to be read from jpeg_read_scanlines().
    +   * Application may use this to control its processing loop, e.g.,
    +   * "while (output_scanline < output_height)".
    +   */
    +  JDIMENSION output_scanline;   /* 0 .. output_height-1  */
    +
    +  /* Current input scan number and number of iMCU rows completed in scan.
    +   * These indicate the progress of the decompressor input side.
    +   */
    +  int input_scan_number;        /* Number of SOS markers seen so far */
    +  JDIMENSION input_iMCU_row;    /* Number of iMCU rows completed */
    +
    +  /* The "output scan number" is the notional scan being displayed by the
    +   * output side.  The decompressor will not allow output scan/row number
    +   * to get ahead of input scan/row, but it can fall arbitrarily far behind.
    +   */
    +  int output_scan_number;       /* Nominal scan number being displayed */
    +  JDIMENSION output_iMCU_row;   /* Number of iMCU rows read */
    +
    +  /* Current progression status.  coef_bits[c][i] indicates the precision
    +   * with which component c's DCT coefficient i (in zigzag order) is known.
    +   * It is -1 when no data has yet been received, otherwise it is the point
    +   * transform (shift) value for the most recent scan of the coefficient
    +   * (thus, 0 at completion of the progression).
    +   * This pointer is NULL when reading a non-progressive file.
    +   */
    +  int (*coef_bits)[DCTSIZE2];   /* -1 or current Al value for each coef */
    +
    +  /* Internal JPEG parameters --- the application usually need not look at
    +   * these fields.  Note that the decompressor output side may not use
    +   * any parameters that can change between scans.
    +   */
    +
    +  /* Quantization and Huffman tables are carried forward across input
    +   * datastreams when processing abbreviated JPEG datastreams.
    +   */
    +
    +  JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
    +  /* ptrs to coefficient quantization tables, or NULL if not defined */
    +
    +  JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
    +  JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
    +  /* ptrs to Huffman coding tables, or NULL if not defined */
    +
    +  /* These parameters are never carried across datastreams, since they
    +   * are given in SOF/SOS markers or defined to be reset by SOI.
    +   */
    +
    +  int data_precision;           /* bits of precision in image data */
    +
    +  jpeg_component_info * comp_info;
    +  /* comp_info[i] describes component that appears i'th in SOF */
    +
    +  boolean progressive_mode;     /* TRUE if SOFn specifies progressive mode */
    +  boolean arith_code;           /* TRUE=arithmetic coding, FALSE=Huffman */
    +
    +  UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
    +  UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
    +  UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
    +
    +  unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
    +
    +  /* These fields record data obtained from optional markers recognized by
    +   * the JPEG library.
    +   */
    +  boolean saw_JFIF_marker;      /* TRUE iff a JFIF APP0 marker was found */
    +  /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
    +  UINT8 JFIF_major_version;     /* JFIF version number */
    +  UINT8 JFIF_minor_version;
    +  UINT8 density_unit;           /* JFIF code for pixel size units */
    +  UINT16 X_density;             /* Horizontal pixel density */
    +  UINT16 Y_density;             /* Vertical pixel density */
    +  boolean saw_Adobe_marker;     /* TRUE iff an Adobe APP14 marker was found */
    +  UINT8 Adobe_transform;        /* Color transform code from Adobe marker */
    +
    +  boolean CCIR601_sampling;     /* TRUE=first samples are cosited */
    +
    +  /* Aside from the specific data retained from APPn markers known to the
    +   * library, the uninterpreted contents of any or all APPn and COM markers
    +   * can be saved in a list for examination by the application.
    +   */
    +  jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
    +
    +  /* Remaining fields are known throughout decompressor, but generally
    +   * should not be touched by a surrounding application.
    +   */
    +
    +  /*
    +   * These fields are computed during decompression startup
    +   */
    +  int max_h_samp_factor;        /* largest h_samp_factor */
    +  int max_v_samp_factor;        /* largest v_samp_factor */
    +
    +  int min_DCT_scaled_size;      /* smallest DCT_scaled_size of any component */
    +
    +  JDIMENSION total_iMCU_rows;   /* # of iMCU rows in image */
    +  /* The coefficient controller's input and output progress is measured in
    +   * units of "iMCU" (interleaved MCU) rows.  These are the same as MCU rows
    +   * in fully interleaved JPEG scans, but are used whether the scan is
    +   * interleaved or not.  We define an iMCU row as v_samp_factor DCT block
    +   * rows of each component.  Therefore, the IDCT output contains
    +   * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
    +   */
    +
    +  JSAMPLE * sample_range_limit; /* table for fast range-limiting */
    +
    +  /*
    +   * These fields are valid during any one scan.
    +   * They describe the components and MCUs actually appearing in the scan.
    +   * Note that the decompressor output side must not use these fields.
    +   */
    +  int comps_in_scan;            /* # of JPEG components in this scan */
    +  jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
    +  /* *cur_comp_info[i] describes component that appears i'th in SOS */
    +
    +  JDIMENSION MCUs_per_row;      /* # of MCUs across the image */
    +  JDIMENSION MCU_rows_in_scan;  /* # of MCU rows in the image */
    +
    +  int blocks_in_MCU;            /* # of DCT blocks per MCU */
    +  int MCU_membership[D_MAX_BLOCKS_IN_MCU];
    +  /* MCU_membership[i] is index in cur_comp_info of component owning */
    +  /* i'th block in an MCU */
    +
    +  int Ss, Se, Ah, Al;           /* progressive JPEG parameters for scan */
    +
    +  /* This field is shared between entropy decoder and marker parser.
    +   * It is either zero or the code of a JPEG marker that has been
    +   * read from the data source, but has not yet been processed.
    +   */
    +  int unread_marker;
    +
    +  /*
    +   * Links to decompression subobjects (methods, private variables of modules)
    +   */
    +  struct jpeg_decomp_master * master;
    +  struct jpeg_d_main_controller * main;
    +  struct jpeg_d_coef_controller * coef;
    +  struct jpeg_d_post_controller * post;
    +  struct jpeg_input_controller * inputctl;
    +  struct jpeg_marker_reader * marker;
    +  struct jpeg_entropy_decoder * entropy;
    +  struct jpeg_inverse_dct * idct;
    +  struct jpeg_upsampler * upsample;
    +  struct jpeg_color_deconverter * cconvert;
    +  struct jpeg_color_quantizer * cquantize;
    +};
    +
    +
    +/* "Object" declarations for JPEG modules that may be supplied or called
    + * directly by the surrounding application.
    + * As with all objects in the JPEG library, these structs only define the
    + * publicly visible methods and state variables of a module.  Additional
    + * private fields may exist after the public ones.
    + */
    +
    +
    +/* Error handler object */
    +
    +struct jpeg_error_mgr {
    +  /* Error exit handler: does not return to caller */
    +  JMETHOD(void, error_exit, (j_common_ptr cinfo));
    +  /* Conditionally emit a trace or warning message */
    +  JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
    +  /* Routine that actually outputs a trace or error message */
    +  JMETHOD(void, output_message, (j_common_ptr cinfo));
    +  /* Format a message string for the most recent JPEG error or message */
    +  JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
    +#define JMSG_LENGTH_MAX  200    /* recommended size of format_message buffer */
    +  /* Reset error state variables at start of a new image */
    +  JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
    +
    +  /* The message ID code and any parameters are saved here.
    +   * A message can have one string parameter or up to 8 int parameters.
    +   */
    +  int msg_code;
    +#define JMSG_STR_PARM_MAX  80
    +  union {
    +    int i[8];
    +    char s[JMSG_STR_PARM_MAX];
    +  } msg_parm;
    +
    +  /* Standard state variables for error facility */
    +
    +  int trace_level;              /* max msg_level that will be displayed */
    +
    +  /* For recoverable corrupt-data errors, we emit a warning message,
    +   * but keep going unless emit_message chooses to abort.  emit_message
    +   * should count warnings in num_warnings.  The surrounding application
    +   * can check for bad data by seeing if num_warnings is nonzero at the
    +   * end of processing.
    +   */
    +  long num_warnings;            /* number of corrupt-data warnings */
    +
    +  /* These fields point to the table(s) of error message strings.
    +   * An application can change the table pointer to switch to a different
    +   * message list (typically, to change the language in which errors are
    +   * reported).  Some applications may wish to add additional error codes
    +   * that will be handled by the JPEG library error mechanism; the second
    +   * table pointer is used for this purpose.
    +   *
    +   * First table includes all errors generated by JPEG library itself.
    +   * Error code 0 is reserved for a "no such error string" message.
    +   */
    +  const char * const * jpeg_message_table; /* Library errors */
    +  int last_jpeg_message;    /* Table contains strings 0..last_jpeg_message */
    +  /* Second table can be added by application (see cjpeg/djpeg for example).
    +   * It contains strings numbered first_addon_message..last_addon_message.
    +   */
    +  const char * const * addon_message_table; /* Non-library errors */
    +  int first_addon_message;      /* code for first string in addon table */
    +  int last_addon_message;       /* code for last string in addon table */
    +};
    +
    +
    +/* Progress monitor object */
    +
    +struct jpeg_progress_mgr {
    +  JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
    +
    +  long pass_counter;            /* work units completed in this pass */
    +  long pass_limit;              /* total number of work units in this pass */
    +  int completed_passes;         /* passes completed so far */
    +  int total_passes;             /* total number of passes expected */
    +};
    +
    +
    +/* Data destination object for compression */
    +
    +struct jpeg_destination_mgr {
    +  JOCTET * next_output_byte;    /* => next byte to write in buffer */
    +  size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
    +
    +  JMETHOD(void, init_destination, (j_compress_ptr cinfo));
    +  JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
    +  JMETHOD(void, term_destination, (j_compress_ptr cinfo));
    +};
    +
    +
    +/* Data source object for decompression */
    +
    +struct jpeg_source_mgr {
    +  const JOCTET * next_input_byte; /* => next byte to read from buffer */
    +  size_t bytes_in_buffer;       /* # of bytes remaining in buffer */
    +
    +  JMETHOD(void, init_source, (j_decompress_ptr cinfo));
    +  JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
    +  JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
    +  JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
    +  JMETHOD(void, term_source, (j_decompress_ptr cinfo));
    +};
    +
    +
    +/* Memory manager object.
    + * Allocates "small" objects (a few K total), "large" objects (tens of K),
    + * and "really big" objects (virtual arrays with backing store if needed).
    + * The memory manager does not allow individual objects to be freed; rather,
    + * each created object is assigned to a pool, and whole pools can be freed
    + * at once.  This is faster and more convenient than remembering exactly what
    + * to free, especially where malloc()/free() are not too speedy.
    + * NB: alloc routines never return NULL.  They exit to error_exit if not
    + * successful.
    + */
    +
    +#define JPOOL_PERMANENT 0       /* lasts until master record is destroyed */
    +#define JPOOL_IMAGE     1       /* lasts until done with image/datastream */
    +#define JPOOL_NUMPOOLS  2
    +
    +typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
    +typedef struct jvirt_barray_control * jvirt_barray_ptr;
    +
    +
    +struct jpeg_memory_mgr {
    +  /* Method pointers */
    +  JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
    +                                size_t sizeofobject));
    +  JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
    +                                     size_t sizeofobject));
    +  JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
    +                                     JDIMENSION samplesperrow,
    +                                     JDIMENSION numrows));
    +  JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
    +                                      JDIMENSION blocksperrow,
    +                                      JDIMENSION numrows));
    +  JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
    +                                                  int pool_id,
    +                                                  boolean pre_zero,
    +                                                  JDIMENSION samplesperrow,
    +                                                  JDIMENSION numrows,
    +                                                  JDIMENSION maxaccess));
    +  JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
    +                                                  int pool_id,
    +                                                  boolean pre_zero,
    +                                                  JDIMENSION blocksperrow,
    +                                                  JDIMENSION numrows,
    +                                                  JDIMENSION maxaccess));
    +  JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
    +  JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
    +                                           jvirt_sarray_ptr ptr,
    +                                           JDIMENSION start_row,
    +                                           JDIMENSION num_rows,
    +                                           boolean writable));
    +  JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
    +                                            jvirt_barray_ptr ptr,
    +                                            JDIMENSION start_row,
    +                                            JDIMENSION num_rows,
    +                                            boolean writable));
    +  JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
    +  JMETHOD(void, self_destruct, (j_common_ptr cinfo));
    +
    +  /* Limit on memory allocation for this JPEG object.  (Note that this is
    +   * merely advisory, not a guaranteed maximum; it only affects the space
    +   * used for virtual-array buffers.)  May be changed by outer application
    +   * after creating the JPEG object.
    +   */
    +  size_t max_memory_to_use;
    +
    +  /* Maximum allocation request accepted by alloc_large. */
    +  size_t max_alloc_chunk;
    +};
    +
    +
    +/* Routine signature for application-supplied marker processing methods.
    + * Need not pass marker code since it is stored in cinfo->unread_marker.
    + */
    +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
    +
    +
    +/* Declarations for routines called by application.
    + * The JPP macro hides prototype parameters from compilers that can't cope.
    + * Note JPP requires double parentheses.
    + */
    +
    +#ifdef HAVE_PROTOTYPES
    +#define JPP(arglist)    arglist
    +#else
    +#define JPP(arglist)    ()
    +#endif
    +
    +
    +/* Short forms of external names for systems with brain-damaged linkers.
    + * We shorten external names to be unique in the first six letters, which
    + * is good enough for all known systems.
    + * (If your compiler itself needs names to be unique in less than 15
    + * characters, you are out of luck.  Get a better compiler.)
    + */
    +
    +#ifdef NEED_SHORT_EXTERNAL_NAMES
    +#define jpeg_std_error          jStdError
    +#define jpeg_CreateCompress     jCreaCompress
    +#define jpeg_CreateDecompress   jCreaDecompress
    +#define jpeg_destroy_compress   jDestCompress
    +#define jpeg_destroy_decompress jDestDecompress
    +#define jpeg_stdio_dest         jStdDest
    +#define jpeg_stdio_src          jStdSrc
    +#define jpeg_set_defaults       jSetDefaults
    +#define jpeg_set_colorspace     jSetColorspace
    +#define jpeg_default_colorspace jDefColorspace
    +#define jpeg_set_quality        jSetQuality
    +#define jpeg_set_linear_quality jSetLQuality
    +#define jpeg_add_quant_table    jAddQuantTable
    +#define jpeg_quality_scaling    jQualityScaling
    +#define jpeg_simple_progression jSimProgress
    +#define jpeg_suppress_tables    jSuppressTables
    +#define jpeg_alloc_quant_table  jAlcQTable
    +#define jpeg_alloc_huff_table   jAlcHTable
    +#define jpeg_start_compress     jStrtCompress
    +#define jpeg_write_scanlines    jWrtScanlines
    +#define jpeg_finish_compress    jFinCompress
    +#define jpeg_write_raw_data     jWrtRawData
    +#define jpeg_write_marker       jWrtMarker
    +#define jpeg_write_m_header     jWrtMHeader
    +#define jpeg_write_m_byte       jWrtMByte
    +#define jpeg_write_tables       jWrtTables
    +#define jpeg_read_header        jReadHeader
    +#define jpeg_start_decompress   jStrtDecompress
    +#define jpeg_read_scanlines     jReadScanlines
    +#define jpeg_finish_decompress  jFinDecompress
    +#define jpeg_read_raw_data      jReadRawData
    +#define jpeg_has_multiple_scans jHasMultScn
    +#define jpeg_start_output       jStrtOutput
    +#define jpeg_finish_output      jFinOutput
    +#define jpeg_input_complete     jInComplete
    +#define jpeg_new_colormap       jNewCMap
    +#define jpeg_consume_input      jConsumeInput
    +#define jpeg_calc_output_dimensions     jCalcDimensions
    +#define jpeg_save_markers       jSaveMarkers
    +#define jpeg_set_marker_processor       jSetMarker
    +#define jpeg_read_coefficients  jReadCoefs
    +#define jpeg_write_coefficients jWrtCoefs
    +#define jpeg_copy_critical_parameters   jCopyCrit
    +#define jpeg_abort_compress     jAbrtCompress
    +#define jpeg_abort_decompress   jAbrtDecompress
    +#define jpeg_abort              jAbort
    +#define jpeg_destroy            jDestroy
    +#define jpeg_resync_to_restart  jResyncRestart
    +#endif /* NEED_SHORT_EXTERNAL_NAMES */
    +
    +
    +/* Default error-management setup */
    +EXTERN(struct jpeg_error_mgr *) jpeg_std_error
    +        JPP((struct jpeg_error_mgr * err));
    +
    +/* Initialization of JPEG compression objects.
    + * jpeg_create_compress() and jpeg_create_decompress() are the exported
    + * names that applications should call.  These expand to calls on
    + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
    + * passed for version mismatch checking.
    + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
    + */
    +#define jpeg_create_compress(cinfo) \
    +    jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
    +                        (size_t) sizeof(struct jpeg_compress_struct))
    +#define jpeg_create_decompress(cinfo) \
    +    jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
    +                          (size_t) sizeof(struct jpeg_decompress_struct))
    +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
    +                                      int version, size_t structsize));
    +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
    +                                        int version, size_t structsize));
    +/* Destruction of JPEG compression objects */
    +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
    +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
    +
    +/* Standard data source and destination managers: stdio streams. */
    +/* Caller is responsible for opening the file before and closing after. */
    +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
    +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
    +
    +/* Default parameter setup for compression */
    +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
    +/* Compression parameter setup aids */
    +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
    +                                      J_COLOR_SPACE colorspace));
    +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
    +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
    +                                   boolean force_baseline));
    +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
    +                                          int scale_factor,
    +                                          boolean force_baseline));
    +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
    +                                       const unsigned int *basic_table,
    +                                       int scale_factor,
    +                                       boolean force_baseline));
    +EXTERN(int) jpeg_quality_scaling JPP((int quality));
    +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
    +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
    +                                       boolean suppress));
    +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
    +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
    +
    +/* Main entry points for compression */
    +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
    +                                      boolean write_all_tables));
    +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
    +                                             JSAMPARRAY scanlines,
    +                                             JDIMENSION num_lines));
    +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
    +
    +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
    +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
    +                                            JSAMPIMAGE data,
    +                                            JDIMENSION num_lines));
    +
    +/* Write a special marker.  See libjpeg.doc concerning safe usage. */
    +EXTERN(void) jpeg_write_marker
    +        JPP((j_compress_ptr cinfo, int marker,
    +             const JOCTET * dataptr, unsigned int datalen));
    +/* Same, but piecemeal. */
    +EXTERN(void) jpeg_write_m_header
    +        JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
    +EXTERN(void) jpeg_write_m_byte
    +        JPP((j_compress_ptr cinfo, int val));
    +
    +/* Alternate compression function: just write an abbreviated table file */
    +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
    +
    +/* Decompression startup: read start of JPEG datastream to see what's there */
    +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
    +                                  boolean require_image));
    +/* Return value is one of: */
    +#define JPEG_SUSPENDED          0 /* Suspended due to lack of input data */
    +#define JPEG_HEADER_OK          1 /* Found valid image datastream */
    +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
    +/* If you pass require_image = TRUE (normal case), you need not check for
    + * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
    + * JPEG_SUSPENDED is only possible if you use a data source module that can
    + * give a suspension return (the stdio source module doesn't).
    + */
    +
    +/* Main entry points for decompression */
    +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
    +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
    +                                            JSAMPARRAY scanlines,
    +                                            JDIMENSION max_lines));
    +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
    +
    +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
    +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
    +                                           JSAMPIMAGE data,
    +                                           JDIMENSION max_lines));
    +
    +/* Additional entry points for buffered-image mode. */
    +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
    +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
    +                                       int scan_number));
    +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
    +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
    +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
    +/* Return value is one of: */
    +/* #define JPEG_SUSPENDED       0    Suspended due to lack of input data */
    +#define JPEG_REACHED_SOS        1 /* Reached start of new scan */
    +#define JPEG_REACHED_EOI        2 /* Reached end of image */
    +#define JPEG_ROW_COMPLETED      3 /* Completed one iMCU row */
    +#define JPEG_SCAN_COMPLETED     4 /* Completed last iMCU row of a scan */
    +
    +/* Precalculate output dimensions for current decompression parameters. */
    +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
    +
    +/* Control saving of COM and APPn markers into marker_list. */
    +EXTERN(void) jpeg_save_markers
    +        JPP((j_decompress_ptr cinfo, int marker_code,
    +             unsigned int length_limit));
    +
    +/* Install a special processing method for COM or APPn markers. */
    +EXTERN(void) jpeg_set_marker_processor
    +        JPP((j_decompress_ptr cinfo, int marker_code,
    +             jpeg_marker_parser_method routine));
    +
    +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
    +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
    +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
    +                                          jvirt_barray_ptr * coef_arrays));
    +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
    +                                                j_compress_ptr dstinfo));
    +
    +/* If you choose to abort compression or decompression before completing
    + * jpeg_finish_(de)compress, then you need to clean up to release memory,
    + * temporary files, etc.  You can just call jpeg_destroy_(de)compress
    + * if you're done with the JPEG object, but if you want to clean it up and
    + * reuse it, call this:
    + */
    +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
    +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
    +
    +/* Generic versions of jpeg_abort and jpeg_destroy that work on either
    + * flavor of JPEG object.  These may be more convenient in some places.
    + */
    +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
    +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
    +
    +/* Default restart-marker-resync procedure for use by data source modules */
    +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
    +                                            int desired));
    +
    +
    +/* These marker codes are exported since applications and data source modules
    + * are likely to want to use them.
    + */
    +
    +#define JPEG_RST0       0xD0    /* RST0 marker code */
    +#define JPEG_EOI        0xD9    /* EOI marker code */
    +#define JPEG_APP0       0xE0    /* APP0 marker code */
    +#define JPEG_COM        0xFE    /* COM marker code */
    +
    +
    +/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
    + * for structure definitions that are never filled in, keep it quiet by
    + * supplying dummy definitions for the various substructures.
    + */
    +
    +#ifdef INCOMPLETE_TYPES_BROKEN
    +#ifndef JPEG_INTERNALS          /* will be defined in jpegint.h */
    +struct jvirt_sarray_control { long dummy; };
    +struct jvirt_barray_control { long dummy; };
    +struct jpeg_comp_master { long dummy; };
    +struct jpeg_c_main_controller { long dummy; };
    +struct jpeg_c_prep_controller { long dummy; };
    +struct jpeg_c_coef_controller { long dummy; };
    +struct jpeg_marker_writer { long dummy; };
    +struct jpeg_color_converter { long dummy; };
    +struct jpeg_downsampler { long dummy; };
    +struct jpeg_forward_dct { long dummy; };
    +struct jpeg_entropy_encoder { long dummy; };
    +struct jpeg_decomp_master { long dummy; };
    +struct jpeg_d_main_controller { long dummy; };
    +struct jpeg_d_coef_controller { long dummy; };
    +struct jpeg_d_post_controller { long dummy; };
    +struct jpeg_input_controller { long dummy; };
    +struct jpeg_marker_reader { long dummy; };
    +struct jpeg_entropy_decoder { long dummy; };
    +struct jpeg_inverse_dct { long dummy; };
    +struct jpeg_upsampler { long dummy; };
    +struct jpeg_color_deconverter { long dummy; };
    +struct jpeg_color_quantizer { long dummy; };
    +#endif /* JPEG_INTERNALS */
    +#endif /* INCOMPLETE_TYPES_BROKEN */
    +
    +
    +/*
    + * The JPEG library modules define JPEG_INTERNALS before including this file.
    + * The internal structure declarations are read only when that is true.
    + * Applications using the library should not include jpegint.h, but may wish
    + * to include jerror.h.
    + */
    +
    +#ifdef JPEG_INTERNALS
    +#include "jpegint.h"            /* fetch private declarations */
    +#include "jerror.h"             /* fetch error codes too */
    +#endif
    +
    +#endif /* JPEGLIB_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jquant1.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jquant1.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jquant1.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jquant1.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,860 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jquant1.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains 1-pass color quantization (color mapping) routines.
    + * These routines provide mapping to a fixed color map using equally spaced
    + * color values.  Optional Floyd-Steinberg or ordered dithering is available.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +#ifdef QUANT_1PASS_SUPPORTED
    +
    +
    +/*
    + * The main purpose of 1-pass quantization is to provide a fast, if not very
    + * high quality, colormapped output capability.  A 2-pass quantizer usually
    + * gives better visual quality; however, for quantized grayscale output this
    + * quantizer is perfectly adequate.  Dithering is highly recommended with this
    + * quantizer, though you can turn it off if you really want to.
    + *
    + * In 1-pass quantization the colormap must be chosen in advance of seeing the
    + * image.  We use a map consisting of all combinations of Ncolors[i] color
    + * values for the i'th component.  The Ncolors[] values are chosen so that
    + * their product, the total number of colors, is no more than that requested.
    + * (In most cases, the product will be somewhat less.)
    + *
    + * Since the colormap is orthogonal, the representative value for each color
    + * component can be determined without considering the other components;
    + * then these indexes can be combined into a colormap index by a standard
    + * N-dimensional-array-subscript calculation.  Most of the arithmetic involved
    + * can be precalculated and stored in the lookup table colorindex[].
    + * colorindex[i][j] maps pixel value j in component i to the nearest
    + * representative value (grid plane) for that component; this index is
    + * multiplied by the array stride for component i, so that the
    + * index of the colormap entry closest to a given pixel value is just
    + *    sum( colorindex[component-number][pixel-component-value] )
    + * Aside from being fast, this scheme allows for variable spacing between
    + * representative values with no additional lookup cost.
    + *
    + * If gamma correction has been applied in color conversion, it might be wise
    + * to adjust the color grid spacing so that the representative colors are
    + * equidistant in linear space.  At this writing, gamma correction is not
    + * implemented by jdcolor, so nothing is done here.
    + */
    +
    +
    +/* Declarations for ordered dithering.
    + *
    + * We use a standard 16x16 ordered dither array.  The basic concept of ordered
    + * dithering is described in many references, for instance Dale Schumacher's
    + * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
    + * In place of Schumacher's comparisons against a "threshold" value, we add a
    + * "dither" value to the input pixel and then round the result to the nearest
    + * output value.  The dither value is equivalent to (0.5 - threshold) times
    + * the distance between output values.  For ordered dithering, we assume that
    + * the output colors are equally spaced; if not, results will probably be
    + * worse, since the dither may be too much or too little at a given point.
    + *
    + * The normal calculation would be to form pixel value + dither, range-limit
    + * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
    + * We can skip the separate range-limiting step by extending the colorindex
    + * table in both directions.
    + */
    +
    +#define ODITHER_SIZE  16        /* dimension of dither matrix */
    +/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
    +#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE)       /* # cells in matrix */
    +#define ODITHER_MASK  (ODITHER_SIZE-1) /* mask for wrapping around counters */
    +
    +typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
    +typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
    +
    +static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
    +  /* Bayer's order-4 dither array.  Generated by the code given in
    +   * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
    +   * The values in this array must range from 0 to ODITHER_CELLS-1.
    +   */
    +  {   0,192, 48,240, 12,204, 60,252,  3,195, 51,243, 15,207, 63,255 },
    +  { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
    +  {  32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
    +  { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
    +  {   8,200, 56,248,  4,196, 52,244, 11,203, 59,251,  7,199, 55,247 },
    +  { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
    +  {  40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
    +  { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
    +  {   2,194, 50,242, 14,206, 62,254,  1,193, 49,241, 13,205, 61,253 },
    +  { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
    +  {  34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
    +  { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
    +  {  10,202, 58,250,  6,198, 54,246,  9,201, 57,249,  5,197, 53,245 },
    +  { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
    +  {  42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
    +  { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
    +};
    +
    +
    +/* Declarations for Floyd-Steinberg dithering.
    + *
    + * Errors are accumulated into the array fserrors[], at a resolution of
    + * 1/16th of a pixel count.  The error at a given pixel is propagated
    + * to its not-yet-processed neighbors using the standard F-S fractions,
    + *              ...     (here)  7/16
    + *              3/16    5/16    1/16
    + * We work left-to-right on even rows, right-to-left on odd rows.
    + *
    + * We can get away with a single array (holding one row's worth of errors)
    + * by using it to store the current row's errors at pixel columns not yet
    + * processed, but the next row's errors at columns already processed.  We
    + * need only a few extra variables to hold the errors immediately around the
    + * current column.  (If we are lucky, those variables are in registers, but
    + * even if not, they're probably cheaper to access than array elements are.)
    + *
    + * The fserrors[] array is indexed [component#][position].
    + * We provide (#columns + 2) entries per component; the extra entry at each
    + * end saves us from special-casing the first and last pixels.
    + *
    + * Note: on a wide image, we might not have enough room in a PC's near data
    + * segment to hold the error array; so it is allocated with alloc_large.
    + */
    +
    +#if BITS_IN_JSAMPLE == 8
    +typedef INT16 FSERROR;          /* 16 bits should be enough */
    +typedef int LOCFSERROR;         /* use 'int' for calculation temps */
    +#else
    +typedef INT32 FSERROR;          /* may need more than 16 bits */
    +typedef INT32 LOCFSERROR;       /* be sure calculation temps are big enough */
    +#endif
    +
    +typedef FSERROR FAR *FSERRPTR;  /* pointer to error array (in FAR storage!) */
    +
    +
    +/* Private subobject */
    +
    +#define MAX_Q_COMPS 4           /* max components I can handle */
    +
    +typedef struct {
    +  struct jpeg_color_quantizer pub; /* public fields */
    +
    +  /* Initially allocated colormap is saved here */
    +  JSAMPARRAY sv_colormap;       /* The color map as a 2-D pixel array */
    +  int sv_actual;                /* number of entries in use */
    +
    +  JSAMPARRAY colorindex;        /* Precomputed mapping for speed */
    +  /* colorindex[i][j] = index of color closest to pixel value j in component i,
    +   * premultiplied as described above.  Since colormap indexes must fit into
    +   * JSAMPLEs, the entries of this array will too.
    +   */
    +  boolean is_padded;            /* is the colorindex padded for odither? */
    +
    +  int Ncolors[MAX_Q_COMPS];     /* # of values alloced to each component */
    +
    +  /* Variables for ordered dithering */
    +  int row_index;                /* cur row's vertical index in dither matrix */
    +  ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
    +
    +  /* Variables for Floyd-Steinberg dithering */
    +  FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
    +  boolean on_odd_row;           /* flag to remember which row we are on */
    +} my_cquantizer;
    +
    +typedef my_cquantizer * my_cquantize_ptr;
    +
    +
    +/*
    + * Policy-making subroutines for create_colormap and create_colorindex.
    + * These routines determine the colormap to be used.  The rest of the module
    + * only assumes that the colormap is orthogonal.
    + *
    + *  * select_ncolors decides how to divvy up the available colors
    + *    among the components.
    + *  * output_value defines the set of representative values for a component.
    + *  * largest_input_value defines the mapping from input values to
    + *    representative values for a component.
    + * Note that the latter two routines may impose different policies for
    + * different components, though this is not currently done.
    + */
    +
    +
    +LOCAL(int)
    +select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
    +/* Determine allocation of desired colors to components, */
    +/* and fill in Ncolors[] array to indicate choice. */
    +/* Return value is total number of colors (product of Ncolors[] values). */
    +{
    +  int nc = cinfo->out_color_components; /* number of color components */
    +  int max_colors = cinfo->desired_number_of_colors;
    +  int total_colors, iroot, i, j;
    +  boolean changed;
    +  long temp;
    +  static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
    +
    +  /* We can allocate at least the nc'th root of max_colors per component. */
    +  /* Compute floor(nc'th root of max_colors). */
    +  iroot = 1;
    +  do {
    +    iroot++;
    +    temp = iroot;               /* set temp = iroot ** nc */
    +    for (i = 1; i < nc; i++)
    +      temp *= iroot;
    +  } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
    +  iroot--;                      /* now iroot = floor(root) */
    +
    +  /* Must have at least 2 color values per component */
    +  if (iroot < 2)
    +    ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
    +
    +  /* Initialize to iroot color values for each component */
    +  total_colors = 1;
    +  for (i = 0; i < nc; i++) {
    +    Ncolors[i] = iroot;
    +    total_colors *= iroot;
    +  }
    +  /* We may be able to increment the count for one or more components without
    +   * exceeding max_colors, though we know not all can be incremented.
    +   * Sometimes, the first component can be incremented more than once!
    +   * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
    +   * In RGB colorspace, try to increment G first, then R, then B.
    +   */
    +  do {
    +    changed = FALSE;
    +    for (i = 0; i < nc; i++) {
    +      j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
    +      /* calculate new total_colors if Ncolors[j] is incremented */
    +      temp = total_colors / Ncolors[j];
    +      temp *= Ncolors[j]+1;     /* done in long arith to avoid oflo */
    +      if (temp > (long) max_colors)
    +        break;                  /* won't fit, done with this pass */
    +      Ncolors[j]++;             /* OK, apply the increment */
    +      total_colors = (int) temp;
    +      changed = TRUE;
    +    }
    +  } while (changed);
    +
    +  return total_colors;
    +}
    +
    +
    +LOCAL(int)
    +output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
    +/* Return j'th output value, where j will range from 0 to maxj */
    +/* The output values must fall in 0..MAXJSAMPLE in increasing order */
    +{
    +  /* We always provide values 0 and MAXJSAMPLE for each component;
    +   * any additional values are equally spaced between these limits.
    +   * (Forcing the upper and lower values to the limits ensures that
    +   * dithering can't produce a color outside the selected gamut.)
    +   */
    +  return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
    +}
    +
    +
    +LOCAL(int)
    +largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
    +/* Return largest input value that should map to j'th output value */
    +/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
    +{
    +  /* Breakpoints are halfway between values returned by output_value */
    +  return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
    +}
    +
    +
    +/*
    + * Create the colormap.
    + */
    +
    +LOCAL(void)
    +create_colormap (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  JSAMPARRAY colormap;          /* Created colormap */
    +  int total_colors;             /* Number of distinct output colors */
    +  int i,j,k, nci, blksize, blkdist, ptr, val;
    +
    +  /* Select number of colors for each component */
    +  total_colors = select_ncolors(cinfo, cquantize->Ncolors);
    +
    +  /* Report selected color counts */
    +  if (cinfo->out_color_components == 3)
    +    TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
    +             total_colors, cquantize->Ncolors[0],
    +             cquantize->Ncolors[1], cquantize->Ncolors[2]);
    +  else
    +    TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
    +
    +  /* Allocate and fill in the colormap. */
    +  /* The colors are ordered in the map in standard row-major order, */
    +  /* i.e. rightmost (highest-indexed) color changes most rapidly. */
    +
    +  colormap = (*cinfo->mem->alloc_sarray)
    +    ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +     (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
    +
    +  /* blksize is number of adjacent repeated entries for a component */
    +  /* blkdist is distance between groups of identical entries for a component */
    +  blkdist = total_colors;
    +
    +  for (i = 0; i < cinfo->out_color_components; i++) {
    +    /* fill in colormap entries for i'th color component */
    +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
    +    blksize = blkdist / nci;
    +    for (j = 0; j < nci; j++) {
    +      /* Compute j'th output value (out of nci) for component */
    +      val = output_value(cinfo, i, j, nci-1);
    +      /* Fill in all colormap entries that have this value of this component */
    +      for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
    +        /* fill in blksize entries beginning at ptr */
    +        for (k = 0; k < blksize; k++)
    +          colormap[i][ptr+k] = (JSAMPLE) val;
    +      }
    +    }
    +    blkdist = blksize;          /* blksize of this color is blkdist of next */
    +  }
    +
    +  /* Save the colormap in private storage,
    +   * where it will survive color quantization mode changes.
    +   */
    +  cquantize->sv_colormap = colormap;
    +  cquantize->sv_actual = total_colors;
    +}
    +
    +
    +/*
    + * Create the color index table.
    + */
    +
    +LOCAL(void)
    +create_colorindex (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  JSAMPROW indexptr;
    +  int i,j,k, nci, blksize, val, pad;
    +
    +  /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
    +   * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
    +   * This is not necessary in the other dithering modes.  However, we
    +   * flag whether it was done in case user changes dithering mode.
    +   */
    +  if (cinfo->dither_mode == JDITHER_ORDERED) {
    +    pad = MAXJSAMPLE*2;
    +    cquantize->is_padded = TRUE;
    +  } else {
    +    pad = 0;
    +    cquantize->is_padded = FALSE;
    +  }
    +
    +  cquantize->colorindex = (*cinfo->mem->alloc_sarray)
    +    ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +     (JDIMENSION) (MAXJSAMPLE+1 + pad),
    +     (JDIMENSION) cinfo->out_color_components);
    +
    +  /* blksize is number of adjacent repeated entries for a component */
    +  blksize = cquantize->sv_actual;
    +
    +  for (i = 0; i < cinfo->out_color_components; i++) {
    +    /* fill in colorindex entries for i'th color component */
    +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
    +    blksize = blksize / nci;
    +
    +    /* adjust colorindex pointers to provide padding at negative indexes. */
    +    if (pad)
    +      cquantize->colorindex[i] += MAXJSAMPLE;
    +
    +    /* in loop, val = index of current output value, */
    +    /* and k = largest j that maps to current val */
    +    indexptr = cquantize->colorindex[i];
    +    val = 0;
    +    k = largest_input_value(cinfo, i, 0, nci-1);
    +    for (j = 0; j <= MAXJSAMPLE; j++) {
    +      while (j > k)             /* advance val if past boundary */
    +        k = largest_input_value(cinfo, i, ++val, nci-1);
    +      /* premultiply so that no multiplication needed in main processing */
    +      indexptr[j] = (JSAMPLE) (val * blksize);
    +    }
    +    /* Pad at both ends if necessary */
    +    if (pad)
    +      for (j = 1; j <= MAXJSAMPLE; j++) {
    +        indexptr[-j] = indexptr[0];
    +        indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
    +      }
    +  }
    +}
    +
    +
    +/*
    + * Create an ordered-dither array for a component having ncolors
    + * distinct output values.
    + */
    +
    +LOCAL(ODITHER_MATRIX_PTR)
    +make_odither_array (j_decompress_ptr cinfo, int ncolors)
    +{
    +  ODITHER_MATRIX_PTR odither;
    +  int j,k;
    +  INT32 num,den;
    +
    +  odither = (ODITHER_MATRIX_PTR)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(ODITHER_MATRIX));
    +  /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
    +   * Hence the dither value for the matrix cell with fill order f
    +   * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
    +   * On 16-bit-int machine, be careful to avoid overflow.
    +   */
    +  den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
    +  for (j = 0; j < ODITHER_SIZE; j++) {
    +    for (k = 0; k < ODITHER_SIZE; k++) {
    +      num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
    +            * MAXJSAMPLE;
    +      /* Ensure round towards zero despite C's lack of consistency
    +       * about rounding negative values in integer division...
    +       */
    +      odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
    +    }
    +  }
    +  return odither;
    +}
    +
    +
    +/*
    + * Create the ordered-dither tables.
    + * Components having the same number of representative colors may
    + * share a dither table.
    + */
    +
    +LOCAL(void)
    +create_odither_tables (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  ODITHER_MATRIX_PTR odither;
    +  int i, j, nci;
    +
    +  for (i = 0; i < cinfo->out_color_components; i++) {
    +    nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
    +    odither = NULL;             /* search for matching prior component */
    +    for (j = 0; j < i; j++) {
    +      if (nci == cquantize->Ncolors[j]) {
    +        odither = cquantize->odither[j];
    +        break;
    +      }
    +    }
    +    if (odither == NULL)        /* need a new table? */
    +      odither = make_odither_array(cinfo, nci);
    +    cquantize->odither[i] = odither;
    +  }
    +}
    +
    +
    +/*
    + * Map some rows of pixels to the output colormapped representation.
    + */
    +
    +METHODDEF(void)
    +color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
    +                JSAMPARRAY output_buf, int num_rows)
    +/* General case, no dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  JSAMPARRAY colorindex = cquantize->colorindex;
    +  register int pixcode, ci;
    +  register JSAMPROW ptrin, ptrout;
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +  register int nc = cinfo->out_color_components;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    ptrin = input_buf[row];
    +    ptrout = output_buf[row];
    +    for (col = width; col > 0; col--) {
    +      pixcode = 0;
    +      for (ci = 0; ci < nc; ci++) {
    +        pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
    +      }
    +      *ptrout++ = (JSAMPLE) pixcode;
    +    }
    +  }
    +}
    +
    +
    +METHODDEF(void)
    +color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
    +                 JSAMPARRAY output_buf, int num_rows)
    +/* Fast path for out_color_components==3, no dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  register int pixcode;
    +  register JSAMPROW ptrin, ptrout;
    +  JSAMPROW colorindex0 = cquantize->colorindex[0];
    +  JSAMPROW colorindex1 = cquantize->colorindex[1];
    +  JSAMPROW colorindex2 = cquantize->colorindex[2];
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    ptrin = input_buf[row];
    +    ptrout = output_buf[row];
    +    for (col = width; col > 0; col--) {
    +      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
    +      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
    +      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
    +      *ptrout++ = (JSAMPLE) pixcode;
    +    }
    +  }
    +}
    +
    +
    +METHODDEF(void)
    +quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
    +                     JSAMPARRAY output_buf, int num_rows)
    +/* General case, with ordered dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  register JSAMPROW input_ptr;
    +  register JSAMPROW output_ptr;
    +  JSAMPROW colorindex_ci;
    +  int * dither;                 /* points to active row of dither matrix */
    +  int row_index, col_index;     /* current indexes into dither matrix */
    +  int nc = cinfo->out_color_components;
    +  int ci;
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    /* Initialize output values to 0 so can process components separately */
    +    jzero_far((void FAR *) output_buf[row],
    +              (size_t) (width * SIZEOF(JSAMPLE)));
    +    row_index = cquantize->row_index;
    +    for (ci = 0; ci < nc; ci++) {
    +      input_ptr = input_buf[row] + ci;
    +      output_ptr = output_buf[row];
    +      colorindex_ci = cquantize->colorindex[ci];
    +      dither = cquantize->odither[ci][row_index];
    +      col_index = 0;
    +
    +      for (col = width; col > 0; col--) {
    +        /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
    +         * select output value, accumulate into output code for this pixel.
    +         * Range-limiting need not be done explicitly, as we have extended
    +         * the colorindex table to produce the right answers for out-of-range
    +         * inputs.  The maximum dither is +- MAXJSAMPLE; this sets the
    +         * required amount of padding.
    +         */
    +        *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
    +        input_ptr += nc;
    +        output_ptr++;
    +        col_index = (col_index + 1) & ODITHER_MASK;
    +      }
    +    }
    +    /* Advance row index for next row */
    +    row_index = (row_index + 1) & ODITHER_MASK;
    +    cquantize->row_index = row_index;
    +  }
    +}
    +
    +
    +METHODDEF(void)
    +quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
    +                      JSAMPARRAY output_buf, int num_rows)
    +/* Fast path for out_color_components==3, with ordered dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  register int pixcode;
    +  register JSAMPROW input_ptr;
    +  register JSAMPROW output_ptr;
    +  JSAMPROW colorindex0 = cquantize->colorindex[0];
    +  JSAMPROW colorindex1 = cquantize->colorindex[1];
    +  JSAMPROW colorindex2 = cquantize->colorindex[2];
    +  int * dither0;                /* points to active row of dither matrix */
    +  int * dither1;
    +  int * dither2;
    +  int row_index, col_index;     /* current indexes into dither matrix */
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    row_index = cquantize->row_index;
    +    input_ptr = input_buf[row];
    +    output_ptr = output_buf[row];
    +    dither0 = cquantize->odither[0][row_index];
    +    dither1 = cquantize->odither[1][row_index];
    +    dither2 = cquantize->odither[2][row_index];
    +    col_index = 0;
    +
    +    for (col = width; col > 0; col--) {
    +      pixcode  = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
    +                                        dither0[col_index]]);
    +      pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
    +                                        dither1[col_index]]);
    +      pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
    +                                        dither2[col_index]]);
    +      *output_ptr++ = (JSAMPLE) pixcode;
    +      col_index = (col_index + 1) & ODITHER_MASK;
    +    }
    +    row_index = (row_index + 1) & ODITHER_MASK;
    +    cquantize->row_index = row_index;
    +  }
    +}
    +
    +
    +METHODDEF(void)
    +quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
    +                    JSAMPARRAY output_buf, int num_rows)
    +/* General case, with Floyd-Steinberg dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  register LOCFSERROR cur;      /* current error or pixel value */
    +  LOCFSERROR belowerr;          /* error for pixel below cur */
    +  LOCFSERROR bpreverr;          /* error for below/prev col */
    +  LOCFSERROR bnexterr;          /* error for below/next col */
    +  LOCFSERROR delta;
    +  register FSERRPTR errorptr;   /* => fserrors[] at column before current */
    +  register JSAMPROW input_ptr;
    +  register JSAMPROW output_ptr;
    +  JSAMPROW colorindex_ci;
    +  JSAMPROW colormap_ci;
    +  int pixcode;
    +  int nc = cinfo->out_color_components;
    +  int dir;                      /* 1 for left-to-right, -1 for right-to-left */
    +  int dirnc;                    /* dir * nc */
    +  int ci;
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +  JSAMPLE *range_limit = cinfo->sample_range_limit;
    +  SHIFT_TEMPS
    +
    +  for (row = 0; row < num_rows; row++) {
    +    /* Initialize output values to 0 so can process components separately */
    +    jzero_far((void FAR *) output_buf[row],
    +              (size_t) (width * SIZEOF(JSAMPLE)));
    +    for (ci = 0; ci < nc; ci++) {
    +      input_ptr = input_buf[row] + ci;
    +      output_ptr = output_buf[row];
    +      if (cquantize->on_odd_row) {
    +        /* work right to left in this row */
    +        input_ptr += (width-1) * nc; /* so point to rightmost pixel */
    +        output_ptr += width-1;
    +        dir = -1;
    +        dirnc = -nc;
    +        errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
    +      } else {
    +        /* work left to right in this row */
    +        dir = 1;
    +        dirnc = nc;
    +        errorptr = cquantize->fserrors[ci]; /* => entry before first column */
    +      }
    +      colorindex_ci = cquantize->colorindex[ci];
    +      colormap_ci = cquantize->sv_colormap[ci];
    +      /* Preset error values: no error propagated to first pixel from left */
    +      cur = 0;
    +      /* and no error propagated to row below yet */
    +      belowerr = bpreverr = 0;
    +
    +      for (col = width; col > 0; col--) {
    +        /* cur holds the error propagated from the previous pixel on the
    +         * current line.  Add the error propagated from the previous line
    +         * to form the complete error correction term for this pixel, and
    +         * round the error term (which is expressed * 16) to an integer.
    +         * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
    +         * for either sign of the error value.
    +         * Note: errorptr points to *previous* column's array entry.
    +         */
    +        cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
    +        /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
    +         * The maximum error is +- MAXJSAMPLE; this sets the required size
    +         * of the range_limit array.
    +         */
    +        cur += GETJSAMPLE(*input_ptr);
    +        cur = GETJSAMPLE(range_limit[cur]);
    +        /* Select output value, accumulate into output code for this pixel */
    +        pixcode = GETJSAMPLE(colorindex_ci[cur]);
    +        *output_ptr += (JSAMPLE) pixcode;
    +        /* Compute actual representation error at this pixel */
    +        /* Note: we can do this even though we don't have the final */
    +        /* pixel code, because the colormap is orthogonal. */
    +        cur -= GETJSAMPLE(colormap_ci[pixcode]);
    +        /* Compute error fractions to be propagated to adjacent pixels.
    +         * Add these into the running sums, and simultaneously shift the
    +         * next-line error sums left by 1 column.
    +         */
    +        bnexterr = cur;
    +        delta = cur * 2;
    +        cur += delta;           /* form error * 3 */
    +        errorptr[0] = (FSERROR) (bpreverr + cur);
    +        cur += delta;           /* form error * 5 */
    +        bpreverr = belowerr + cur;
    +        belowerr = bnexterr;
    +        cur += delta;           /* form error * 7 */
    +        /* At this point cur contains the 7/16 error value to be propagated
    +         * to the next pixel on the current line, and all the errors for the
    +         * next line have been shifted over. We are therefore ready to move on.
    +         */
    +        input_ptr += dirnc;     /* advance input ptr to next column */
    +        output_ptr += dir;      /* advance output ptr to next column */
    +        errorptr += dir;        /* advance errorptr to current column */
    +      }
    +      /* Post-loop cleanup: we must unload the final error value into the
    +       * final fserrors[] entry.  Note we need not unload belowerr because
    +       * it is for the dummy column before or after the actual array.
    +       */
    +      errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
    +    }
    +    cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
    +  }
    +}
    +
    +
    +/*
    + * Allocate workspace for Floyd-Steinberg errors.
    + */
    +
    +LOCAL(void)
    +alloc_fs_workspace (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  size_t arraysize;
    +  int i;
    +
    +  arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
    +  for (i = 0; i < cinfo->out_color_components; i++) {
    +    cquantize->fserrors[i] = (FSERRPTR)
    +      (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
    +  }
    +}
    +
    +
    +/*
    + * Initialize for one-pass color quantization.
    + */
    +
    +METHODDEF(void)
    +start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  size_t arraysize;
    +  int i;
    +
    +  /* Install my colormap. */
    +  cinfo->colormap = cquantize->sv_colormap;
    +  cinfo->actual_number_of_colors = cquantize->sv_actual;
    +
    +  /* Initialize for desired dithering mode. */
    +  switch (cinfo->dither_mode) {
    +  case JDITHER_NONE:
    +    if (cinfo->out_color_components == 3)
    +      cquantize->pub.color_quantize = color_quantize3;
    +    else
    +      cquantize->pub.color_quantize = color_quantize;
    +    break;
    +  case JDITHER_ORDERED:
    +    if (cinfo->out_color_components == 3)
    +      cquantize->pub.color_quantize = quantize3_ord_dither;
    +    else
    +      cquantize->pub.color_quantize = quantize_ord_dither;
    +    cquantize->row_index = 0;   /* initialize state for ordered dither */
    +    /* If user changed to ordered dither from another mode,
    +     * we must recreate the color index table with padding.
    +     * This will cost extra space, but probably isn't very likely.
    +     */
    +    if (! cquantize->is_padded)
    +      create_colorindex(cinfo);
    +    /* Create ordered-dither tables if we didn't already. */
    +    if (cquantize->odither[0] == NULL)
    +      create_odither_tables(cinfo);
    +    break;
    +  case JDITHER_FS:
    +    cquantize->pub.color_quantize = quantize_fs_dither;
    +    cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
    +    /* Allocate Floyd-Steinberg workspace if didn't already. */
    +    if (cquantize->fserrors[0] == NULL)
    +      alloc_fs_workspace(cinfo);
    +    /* Initialize the propagated errors to zero. */
    +    arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
    +    for (i = 0; i < cinfo->out_color_components; i++)
    +      jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
    +    break;
    +  default:
    +    ERREXIT(cinfo, JERR_NOT_COMPILED);
    +    break;
    +  }
    +}
    +
    +
    +/*
    + * Finish up at the end of the pass.
    + */
    +
    +METHODDEF(void)
    +finish_pass_1_quant (j_decompress_ptr cinfo)
    +{
    +  /* no work in 1-pass case */
    +}
    +
    +
    +/*
    + * Switch to a new external colormap between output passes.
    + * Shouldn't get to this module!
    + */
    +
    +METHODDEF(void)
    +new_color_map_1_quant (j_decompress_ptr cinfo)
    +{
    +  ERREXIT(cinfo, JERR_MODE_CHANGE);
    +}
    +
    +
    +/*
    + * Module initialization routine for 1-pass color quantization.
    + */
    +
    +GLOBAL(void)
    +jinit_1pass_quantizer (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize;
    +
    +  cquantize = (my_cquantize_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_cquantizer));
    +  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
    +  cquantize->pub.start_pass = start_pass_1_quant;
    +  cquantize->pub.finish_pass = finish_pass_1_quant;
    +  cquantize->pub.new_color_map = new_color_map_1_quant;
    +  cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
    +  cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
    +
    +  /* Make sure my internal arrays won't overflow */
    +  if (cinfo->out_color_components > MAX_Q_COMPS)
    +    ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
    +  /* Make sure colormap indexes can be represented by JSAMPLEs */
    +  if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
    +    ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
    +
    +  /* Create the colormap and color index table. */
    +  create_colormap(cinfo);
    +  create_colorindex(cinfo);
    +
    +  /* Allocate Floyd-Steinberg workspace now if requested.
    +   * We do this now since it is FAR storage and may affect the memory
    +   * manager's space calculations.  If the user changes to FS dither
    +   * mode in a later pass, we will allocate the space then, and will
    +   * possibly overrun the max_memory_to_use setting.
    +   */
    +  if (cinfo->dither_mode == JDITHER_FS)
    +    alloc_fs_workspace(cinfo);
    +}
    +
    +#endif /* QUANT_1PASS_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jquant2.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jquant2.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jquant2.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jquant2.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1314 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jquant2.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains 2-pass color quantization (color mapping) routines.
    + * These routines provide selection of a custom color map for an image,
    + * followed by mapping of the image to that color map, with optional
    + * Floyd-Steinberg dithering.
    + * It is also possible to use just the second pass to map to an arbitrary
    + * externally-given color map.
    + *
    + * Note: ordered dithering is not supported, since there isn't any fast
    + * way to compute intercolor distances; it's unclear that ordered dither's
    + * fundamental assumptions even hold with an irregularly spaced color map.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +#ifdef QUANT_2PASS_SUPPORTED
    +
    +
    +/*
    + * This module implements the well-known Heckbert paradigm for color
    + * quantization.  Most of the ideas used here can be traced back to
    + * Heckbert's seminal paper
    + *   Heckbert, Paul.  "Color Image Quantization for Frame Buffer Display",
    + *   Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
    + *
    + * In the first pass over the image, we accumulate a histogram showing the
    + * usage count of each possible color.  To keep the histogram to a reasonable
    + * size, we reduce the precision of the input; typical practice is to retain
    + * 5 or 6 bits per color, so that 8 or 4 different input values are counted
    + * in the same histogram cell.
    + *
    + * Next, the color-selection step begins with a box representing the whole
    + * color space, and repeatedly splits the "largest" remaining box until we
    + * have as many boxes as desired colors.  Then the mean color in each
    + * remaining box becomes one of the possible output colors.
    + *
    + * The second pass over the image maps each input pixel to the closest output
    + * color (optionally after applying a Floyd-Steinberg dithering correction).
    + * This mapping is logically trivial, but making it go fast enough requires
    + * considerable care.
    + *
    + * Heckbert-style quantizers vary a good deal in their policies for choosing
    + * the "largest" box and deciding where to cut it.  The particular policies
    + * used here have proved out well in experimental comparisons, but better ones
    + * may yet be found.
    + *
    + * In earlier versions of the IJG code, this module quantized in YCbCr color
    + * space, processing the raw upsampled data without a color conversion step.
    + * This allowed the color conversion math to be done only once per colormap
    + * entry, not once per pixel.  However, that optimization precluded other
    + * useful optimizations (such as merging color conversion with upsampling)
    + * and it also interfered with desired capabilities such as quantizing to an
    + * externally-supplied colormap.  We have therefore abandoned that approach.
    + * The present code works in the post-conversion color space, typically RGB.
    + *
    + * To improve the visual quality of the results, we actually work in scaled
    + * RGB space, giving G distances more weight than R, and R in turn more than
    + * B.  To do everything in integer math, we must use integer scale factors.
    + * The 2/3/1 scale factors used here correspond loosely to the relative
    + * weights of the colors in the NTSC grayscale equation.
    + * If you want to use this code to quantize a non-RGB color space, you'll
    + * probably need to change these scale factors.
    + */
    +
    +#define R_SCALE 2               /* scale R distances by this much */
    +#define G_SCALE 3               /* scale G distances by this much */
    +#define B_SCALE 1               /* and B by this much */
    +
    +/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
    + * in jmorecfg.h.  As the code stands, it will do the right thing for R,G,B
    + * and B,G,R orders.  If you define some other weird order in jmorecfg.h,
    + * you'll get compile errors until you extend this logic.  In that case
    + * you'll probably want to tweak the histogram sizes too.
    + */
    +
    +#if RGB_RED == 0
    +#define C0_SCALE R_SCALE
    +#endif
    +#if RGB_BLUE == 0
    +#define C0_SCALE B_SCALE
    +#endif
    +#if RGB_GREEN == 1
    +#define C1_SCALE G_SCALE
    +#endif
    +#if RGB_RED == 2
    +#define C2_SCALE R_SCALE
    +#endif
    +#if RGB_BLUE == 2
    +#define C2_SCALE B_SCALE
    +#endif
    +
    +
    +/*
    + * First we have the histogram data structure and routines for creating it.
    + *
    + * The number of bits of precision can be adjusted by changing these symbols.
    + * We recommend keeping 6 bits for G and 5 each for R and B.
    + * If you have plenty of memory and cycles, 6 bits all around gives marginally
    + * better results; if you are short of memory, 5 bits all around will save
    + * some space but degrade the results.
    + * To maintain a fully accurate histogram, we'd need to allocate a "long"
    + * (preferably unsigned long) for each cell.  In practice this is overkill;
    + * we can get by with 16 bits per cell.  Few of the cell counts will overflow,
    + * and clamping those that do overflow to the maximum value will give close-
    + * enough results.  This reduces the recommended histogram size from 256Kb
    + * to 128Kb, which is a useful savings on PC-class machines.
    + * (In the second pass the histogram space is re-used for pixel mapping data;
    + * in that capacity, each cell must be able to store zero to the number of
    + * desired colors.  16 bits/cell is plenty for that too.)
    + * Since the JPEG code is intended to run in small memory model on 80x86
    + * machines, we can't just allocate the histogram in one chunk.  Instead
    + * of a true 3-D array, we use a row of pointers to 2-D arrays.  Each
    + * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
    + * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries.  Note that
    + * on 80x86 machines, the pointer row is in near memory but the actual
    + * arrays are in far memory (same arrangement as we use for image arrays).
    + */
    +
    +#define MAXNUMCOLORS  (MAXJSAMPLE+1) /* maximum size of colormap */
    +
    +/* These will do the right thing for either R,G,B or B,G,R color order,
    + * but you may not like the results for other color orders.
    + */
    +#define HIST_C0_BITS  5         /* bits of precision in R/B histogram */
    +#define HIST_C1_BITS  6         /* bits of precision in G histogram */
    +#define HIST_C2_BITS  5         /* bits of precision in B/R histogram */
    +
    +/* Number of elements along histogram axes. */
    +#define HIST_C0_ELEMS  (1<cquantize;
    +  register JSAMPROW ptr;
    +  register histptr histp;
    +  register hist3d histogram = cquantize->histogram;
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    ptr = input_buf[row];
    +    for (col = width; col > 0; col--) {
    +      /* get pixel value and index into the histogram */
    +      histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
    +                         [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
    +                         [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
    +      /* increment, check for overflow and undo increment if so. */
    +      if (++(*histp) <= 0)
    +        (*histp)--;
    +      ptr += 3;
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Next we have the really interesting routines: selection of a colormap
    + * given the completed histogram.
    + * These routines work with a list of "boxes", each representing a rectangular
    + * subset of the input color space (to histogram precision).
    + */
    +
    +typedef struct {
    +  /* The bounds of the box (inclusive); expressed as histogram indexes */
    +  int c0min, c0max;
    +  int c1min, c1max;
    +  int c2min, c2max;
    +  /* The volume (actually 2-norm) of the box */
    +  INT32 volume;
    +  /* The number of nonzero histogram cells within this box */
    +  long colorcount;
    +} box;
    +
    +typedef box * boxptr;
    +
    +
    +LOCAL(boxptr)
    +find_biggest_color_pop (boxptr boxlist, int numboxes)
    +/* Find the splittable box with the largest color population */
    +/* Returns NULL if no splittable boxes remain */
    +{
    +  register boxptr boxp;
    +  register int i;
    +  register long maxc = 0;
    +  boxptr which = NULL;
    +
    +  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
    +    if (boxp->colorcount > maxc && boxp->volume > 0) {
    +      which = boxp;
    +      maxc = boxp->colorcount;
    +    }
    +  }
    +  return which;
    +}
    +
    +
    +LOCAL(boxptr)
    +find_biggest_volume (boxptr boxlist, int numboxes)
    +/* Find the splittable box with the largest (scaled) volume */
    +/* Returns NULL if no splittable boxes remain */
    +{
    +  register boxptr boxp;
    +  register int i;
    +  register INT32 maxv = 0;
    +  boxptr which = NULL;
    +
    +  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
    +    if (boxp->volume > maxv) {
    +      which = boxp;
    +      maxv = boxp->volume;
    +    }
    +  }
    +  return which;
    +}
    +
    +
    +LOCAL(void)
    +update_box (j_decompress_ptr cinfo, boxptr boxp)
    +/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
    +/* and recompute its volume and population */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  histptr histp;
    +  int c0,c1,c2;
    +  int c0min,c0max,c1min,c1max,c2min,c2max;
    +  INT32 dist0,dist1,dist2;
    +  long ccount;
    +
    +  c0min = boxp->c0min;  c0max = boxp->c0max;
    +  c1min = boxp->c1min;  c1max = boxp->c1max;
    +  c2min = boxp->c2min;  c2max = boxp->c2max;
    +
    +  if (c0max > c0min)
    +    for (c0 = c0min; c0 <= c0max; c0++)
    +      for (c1 = c1min; c1 <= c1max; c1++) {
    +        histp = & histogram[c0][c1][c2min];
    +        for (c2 = c2min; c2 <= c2max; c2++)
    +          if (*histp++ != 0) {
    +            boxp->c0min = c0min = c0;
    +            goto have_c0min;
    +          }
    +      }
    + have_c0min:
    +  if (c0max > c0min)
    +    for (c0 = c0max; c0 >= c0min; c0--)
    +      for (c1 = c1min; c1 <= c1max; c1++) {
    +        histp = & histogram[c0][c1][c2min];
    +        for (c2 = c2min; c2 <= c2max; c2++)
    +          if (*histp++ != 0) {
    +            boxp->c0max = c0max = c0;
    +            goto have_c0max;
    +          }
    +      }
    + have_c0max:
    +  if (c1max > c1min)
    +    for (c1 = c1min; c1 <= c1max; c1++)
    +      for (c0 = c0min; c0 <= c0max; c0++) {
    +        histp = & histogram[c0][c1][c2min];
    +        for (c2 = c2min; c2 <= c2max; c2++)
    +          if (*histp++ != 0) {
    +            boxp->c1min = c1min = c1;
    +            goto have_c1min;
    +          }
    +      }
    + have_c1min:
    +  if (c1max > c1min)
    +    for (c1 = c1max; c1 >= c1min; c1--)
    +      for (c0 = c0min; c0 <= c0max; c0++) {
    +        histp = & histogram[c0][c1][c2min];
    +        for (c2 = c2min; c2 <= c2max; c2++)
    +          if (*histp++ != 0) {
    +            boxp->c1max = c1max = c1;
    +            goto have_c1max;
    +          }
    +      }
    + have_c1max:
    +  if (c2max > c2min)
    +    for (c2 = c2min; c2 <= c2max; c2++)
    +      for (c0 = c0min; c0 <= c0max; c0++) {
    +        histp = & histogram[c0][c1min][c2];
    +        for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
    +          if (*histp != 0) {
    +            boxp->c2min = c2min = c2;
    +            goto have_c2min;
    +          }
    +      }
    + have_c2min:
    +  if (c2max > c2min)
    +    for (c2 = c2max; c2 >= c2min; c2--)
    +      for (c0 = c0min; c0 <= c0max; c0++) {
    +        histp = & histogram[c0][c1min][c2];
    +        for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
    +          if (*histp != 0) {
    +            boxp->c2max = c2max = c2;
    +            goto have_c2max;
    +          }
    +      }
    + have_c2max:
    +
    +  /* Update box volume.
    +   * We use 2-norm rather than real volume here; this biases the method
    +   * against making long narrow boxes, and it has the side benefit that
    +   * a box is splittable iff norm > 0.
    +   * Since the differences are expressed in histogram-cell units,
    +   * we have to shift back to JSAMPLE units to get consistent distances;
    +   * after which, we scale according to the selected distance scale factors.
    +   */
    +  dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
    +  dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
    +  dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
    +  boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
    +
    +  /* Now scan remaining volume of box and compute population */
    +  ccount = 0;
    +  for (c0 = c0min; c0 <= c0max; c0++)
    +    for (c1 = c1min; c1 <= c1max; c1++) {
    +      histp = & histogram[c0][c1][c2min];
    +      for (c2 = c2min; c2 <= c2max; c2++, histp++)
    +        if (*histp != 0) {
    +          ccount++;
    +        }
    +    }
    +  boxp->colorcount = ccount;
    +}
    +
    +
    +LOCAL(int)
    +median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
    +            int desired_colors)
    +/* Repeatedly select and split the largest box until we have enough boxes */
    +{
    +  int n,lb;
    +  int c0,c1,c2,cmax;
    +  register boxptr b1,b2;
    +
    +  while (numboxes < desired_colors) {
    +    /* Select box to split.
    +     * Current algorithm: by population for first half, then by volume.
    +     */
    +    if (numboxes*2 <= desired_colors) {
    +      b1 = find_biggest_color_pop(boxlist, numboxes);
    +    } else {
    +      b1 = find_biggest_volume(boxlist, numboxes);
    +    }
    +    if (b1 == NULL)             /* no splittable boxes left! */
    +      break;
    +    b2 = &boxlist[numboxes];    /* where new box will go */
    +    /* Copy the color bounds to the new box. */
    +    b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
    +    b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
    +    /* Choose which axis to split the box on.
    +     * Current algorithm: longest scaled axis.
    +     * See notes in update_box about scaling distances.
    +     */
    +    c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
    +    c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
    +    c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
    +    /* We want to break any ties in favor of green, then red, blue last.
    +     * This code does the right thing for R,G,B or B,G,R color orders only.
    +     */
    +#if RGB_RED == 0
    +    cmax = c1; n = 1;
    +    if (c0 > cmax) { cmax = c0; n = 0; }
    +    if (c2 > cmax) { n = 2; }
    +#else
    +    cmax = c1; n = 1;
    +    if (c2 > cmax) { cmax = c2; n = 2; }
    +    if (c0 > cmax) { n = 0; }
    +#endif
    +    /* Choose split point along selected axis, and update box bounds.
    +     * Current algorithm: split at halfway point.
    +     * (Since the box has been shrunk to minimum volume,
    +     * any split will produce two nonempty subboxes.)
    +     * Note that lb value is max for lower box, so must be < old max.
    +     */
    +    switch (n) {
    +    case 0:
    +      lb = (b1->c0max + b1->c0min) / 2;
    +      b1->c0max = lb;
    +      b2->c0min = lb+1;
    +      break;
    +    case 1:
    +      lb = (b1->c1max + b1->c1min) / 2;
    +      b1->c1max = lb;
    +      b2->c1min = lb+1;
    +      break;
    +    case 2:
    +      lb = (b1->c2max + b1->c2min) / 2;
    +      b1->c2max = lb;
    +      b2->c2min = lb+1;
    +      break;
    +    }
    +    /* Update stats for boxes */
    +    update_box(cinfo, b1);
    +    update_box(cinfo, b2);
    +    numboxes++;
    +  }
    +  return numboxes;
    +}
    +
    +
    +LOCAL(void)
    +compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
    +/* Compute representative color for a box, put it in colormap[icolor] */
    +{
    +  /* Current algorithm: mean weighted by pixels (not colors) */
    +  /* Note it is important to get the rounding correct! */
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  histptr histp;
    +  int c0,c1,c2;
    +  int c0min,c0max,c1min,c1max,c2min,c2max;
    +  long count;
    +  long total = 0;
    +  long c0total = 0;
    +  long c1total = 0;
    +  long c2total = 0;
    +
    +  c0min = boxp->c0min;  c0max = boxp->c0max;
    +  c1min = boxp->c1min;  c1max = boxp->c1max;
    +  c2min = boxp->c2min;  c2max = boxp->c2max;
    +
    +  for (c0 = c0min; c0 <= c0max; c0++)
    +    for (c1 = c1min; c1 <= c1max; c1++) {
    +      histp = & histogram[c0][c1][c2min];
    +      for (c2 = c2min; c2 <= c2max; c2++) {
    +        if ((count = *histp++) != 0) {
    +          total += count;
    +          c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count;
    +          c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count;
    +          c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count;
    +        }
    +      }
    +    }
    +
    +  cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
    +  cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
    +  cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
    +}
    +
    +
    +LOCAL(void)
    +select_colors (j_decompress_ptr cinfo, int desired_colors)
    +/* Master routine for color selection */
    +{
    +  boxptr boxlist;
    +  int numboxes;
    +  int i;
    +
    +  /* Allocate workspace for box list */
    +  boxlist = (boxptr) (*cinfo->mem->alloc_small)
    +    ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
    +  /* Initialize one box containing whole space */
    +  numboxes = 1;
    +  boxlist[0].c0min = 0;
    +  boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
    +  boxlist[0].c1min = 0;
    +  boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
    +  boxlist[0].c2min = 0;
    +  boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
    +  /* Shrink it to actually-used volume and set its statistics */
    +  update_box(cinfo, & boxlist[0]);
    +  /* Perform median-cut to produce final box list */
    +  numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
    +  /* Compute the representative color for each box, fill colormap */
    +  for (i = 0; i < numboxes; i++)
    +    compute_color(cinfo, & boxlist[i], i);
    +  cinfo->actual_number_of_colors = numboxes;
    +  TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
    +}
    +
    +
    +/*
    + * These routines are concerned with the time-critical task of mapping input
    + * colors to the nearest color in the selected colormap.
    + *
    + * We re-use the histogram space as an "inverse color map", essentially a
    + * cache for the results of nearest-color searches.  All colors within a
    + * histogram cell will be mapped to the same colormap entry, namely the one
    + * closest to the cell's center.  This may not be quite the closest entry to
    + * the actual input color, but it's almost as good.  A zero in the cache
    + * indicates we haven't found the nearest color for that cell yet; the array
    + * is cleared to zeroes before starting the mapping pass.  When we find the
    + * nearest color for a cell, its colormap index plus one is recorded in the
    + * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
    + * when they need to use an unfilled entry in the cache.
    + *
    + * Our method of efficiently finding nearest colors is based on the "locally
    + * sorted search" idea described by Heckbert and on the incremental distance
    + * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
    + * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
    + * the distances from a given colormap entry to each cell of the histogram can
    + * be computed quickly using an incremental method: the differences between
    + * distances to adjacent cells themselves differ by a constant.  This allows a
    + * fairly fast implementation of the "brute force" approach of computing the
    + * distance from every colormap entry to every histogram cell.  Unfortunately,
    + * it needs a work array to hold the best-distance-so-far for each histogram
    + * cell (because the inner loop has to be over cells, not colormap entries).
    + * The work array elements have to be INT32s, so the work array would need
    + * 256Kb at our recommended precision.  This is not feasible in DOS machines.
    + *
    + * To get around these problems, we apply Thomas' method to compute the
    + * nearest colors for only the cells within a small subbox of the histogram.
    + * The work array need be only as big as the subbox, so the memory usage
    + * problem is solved.  Furthermore, we need not fill subboxes that are never
    + * referenced in pass2; many images use only part of the color gamut, so a
    + * fair amount of work is saved.  An additional advantage of this
    + * approach is that we can apply Heckbert's locality criterion to quickly
    + * eliminate colormap entries that are far away from the subbox; typically
    + * three-fourths of the colormap entries are rejected by Heckbert's criterion,
    + * and we need not compute their distances to individual cells in the subbox.
    + * The speed of this approach is heavily influenced by the subbox size: too
    + * small means too much overhead, too big loses because Heckbert's criterion
    + * can't eliminate as many colormap entries.  Empirically the best subbox
    + * size seems to be about 1/512th of the histogram (1/8th in each direction).
    + *
    + * Thomas' article also describes a refined method which is asymptotically
    + * faster than the brute-force method, but it is also far more complex and
    + * cannot efficiently be applied to small subboxes.  It is therefore not
    + * useful for programs intended to be portable to DOS machines.  On machines
    + * with plenty of memory, filling the whole histogram in one shot with Thomas'
    + * refined method might be faster than the present code --- but then again,
    + * it might not be any faster, and it's certainly more complicated.
    + */
    +
    +
    +/* log2(histogram cells in update box) for each axis; this can be adjusted */
    +#define BOX_C0_LOG  (HIST_C0_BITS-3)
    +#define BOX_C1_LOG  (HIST_C1_BITS-3)
    +#define BOX_C2_LOG  (HIST_C2_BITS-3)
    +
    +#define BOX_C0_ELEMS  (1<actual_number_of_colors;
    +  int maxc0, maxc1, maxc2;
    +  int centerc0, centerc1, centerc2;
    +  int i, x, ncolors;
    +  INT32 minmaxdist, min_dist, max_dist, tdist;
    +  INT32 mindist[MAXNUMCOLORS];  /* min distance to colormap entry i */
    +
    +  /* Compute true coordinates of update box's upper corner and center.
    +   * Actually we compute the coordinates of the center of the upper-corner
    +   * histogram cell, which are the upper bounds of the volume we care about.
    +   * Note that since ">>" rounds down, the "center" values may be closer to
    +   * min than to max; hence comparisons to them must be "<=", not "<".
    +   */
    +  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
    +  centerc0 = (minc0 + maxc0) >> 1;
    +  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
    +  centerc1 = (minc1 + maxc1) >> 1;
    +  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
    +  centerc2 = (minc2 + maxc2) >> 1;
    +
    +  /* For each color in colormap, find:
    +   *  1. its minimum squared-distance to any point in the update box
    +   *     (zero if color is within update box);
    +   *  2. its maximum squared-distance to any point in the update box.
    +   * Both of these can be found by considering only the corners of the box.
    +   * We save the minimum distance for each color in mindist[];
    +   * only the smallest maximum distance is of interest.
    +   */
    +  minmaxdist = 0x7FFFFFFFL;
    +
    +  for (i = 0; i < numcolors; i++) {
    +    /* We compute the squared-c0-distance term, then add in the other two. */
    +    x = GETJSAMPLE(cinfo->colormap[0][i]);
    +    if (x < minc0) {
    +      tdist = (x - minc0) * C0_SCALE;
    +      min_dist = tdist*tdist;
    +      tdist = (x - maxc0) * C0_SCALE;
    +      max_dist = tdist*tdist;
    +    } else if (x > maxc0) {
    +      tdist = (x - maxc0) * C0_SCALE;
    +      min_dist = tdist*tdist;
    +      tdist = (x - minc0) * C0_SCALE;
    +      max_dist = tdist*tdist;
    +    } else {
    +      /* within cell range so no contribution to min_dist */
    +      min_dist = 0;
    +      if (x <= centerc0) {
    +        tdist = (x - maxc0) * C0_SCALE;
    +        max_dist = tdist*tdist;
    +      } else {
    +        tdist = (x - minc0) * C0_SCALE;
    +        max_dist = tdist*tdist;
    +      }
    +    }
    +
    +    x = GETJSAMPLE(cinfo->colormap[1][i]);
    +    if (x < minc1) {
    +      tdist = (x - minc1) * C1_SCALE;
    +      min_dist += tdist*tdist;
    +      tdist = (x - maxc1) * C1_SCALE;
    +      max_dist += tdist*tdist;
    +    } else if (x > maxc1) {
    +      tdist = (x - maxc1) * C1_SCALE;
    +      min_dist += tdist*tdist;
    +      tdist = (x - minc1) * C1_SCALE;
    +      max_dist += tdist*tdist;
    +    } else {
    +      /* within cell range so no contribution to min_dist */
    +      if (x <= centerc1) {
    +        tdist = (x - maxc1) * C1_SCALE;
    +        max_dist += tdist*tdist;
    +      } else {
    +        tdist = (x - minc1) * C1_SCALE;
    +        max_dist += tdist*tdist;
    +      }
    +    }
    +
    +    x = GETJSAMPLE(cinfo->colormap[2][i]);
    +    if (x < minc2) {
    +      tdist = (x - minc2) * C2_SCALE;
    +      min_dist += tdist*tdist;
    +      tdist = (x - maxc2) * C2_SCALE;
    +      max_dist += tdist*tdist;
    +    } else if (x > maxc2) {
    +      tdist = (x - maxc2) * C2_SCALE;
    +      min_dist += tdist*tdist;
    +      tdist = (x - minc2) * C2_SCALE;
    +      max_dist += tdist*tdist;
    +    } else {
    +      /* within cell range so no contribution to min_dist */
    +      if (x <= centerc2) {
    +        tdist = (x - maxc2) * C2_SCALE;
    +        max_dist += tdist*tdist;
    +      } else {
    +        tdist = (x - minc2) * C2_SCALE;
    +        max_dist += tdist*tdist;
    +      }
    +    }
    +
    +    mindist[i] = min_dist;      /* save away the results */
    +    if (max_dist < minmaxdist)
    +      minmaxdist = max_dist;
    +  }
    +
    +  /* Now we know that no cell in the update box is more than minmaxdist
    +   * away from some colormap entry.  Therefore, only colors that are
    +   * within minmaxdist of some part of the box need be considered.
    +   */
    +  ncolors = 0;
    +  for (i = 0; i < numcolors; i++) {
    +    if (mindist[i] <= minmaxdist)
    +      colorlist[ncolors++] = (JSAMPLE) i;
    +  }
    +  return ncolors;
    +}
    +
    +
    +LOCAL(void)
    +find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
    +                  int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
    +/* Find the closest colormap entry for each cell in the update box,
    + * given the list of candidate colors prepared by find_nearby_colors.
    + * Return the indexes of the closest entries in the bestcolor[] array.
    + * This routine uses Thomas' incremental distance calculation method to
    + * find the distance from a colormap entry to successive cells in the box.
    + */
    +{
    +  int ic0, ic1, ic2;
    +  int i, icolor;
    +  register INT32 * bptr;        /* pointer into bestdist[] array */
    +  JSAMPLE * cptr;               /* pointer into bestcolor[] array */
    +  INT32 dist0, dist1;           /* initial distance values */
    +  register INT32 dist2;         /* current distance in inner loop */
    +  INT32 xx0, xx1;               /* distance increments */
    +  register INT32 xx2;
    +  INT32 inc0, inc1, inc2;       /* initial values for increments */
    +  /* This array holds the distance to the nearest-so-far color for each cell */
    +  INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
    +
    +  /* Initialize best-distance for each cell of the update box */
    +  bptr = bestdist;
    +  for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
    +    *bptr++ = 0x7FFFFFFFL;
    +
    +  /* For each color selected by find_nearby_colors,
    +   * compute its distance to the center of each cell in the box.
    +   * If that's less than best-so-far, update best distance and color number.
    +   */
    +
    +  /* Nominal steps between cell centers ("x" in Thomas article) */
    +#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
    +#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
    +#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
    +
    +  for (i = 0; i < numcolors; i++) {
    +    icolor = GETJSAMPLE(colorlist[i]);
    +    /* Compute (square of) distance from minc0/c1/c2 to this color */
    +    inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
    +    dist0 = inc0*inc0;
    +    inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
    +    dist0 += inc1*inc1;
    +    inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
    +    dist0 += inc2*inc2;
    +    /* Form the initial difference increments */
    +    inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
    +    inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
    +    inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
    +    /* Now loop over all cells in box, updating distance per Thomas method */
    +    bptr = bestdist;
    +    cptr = bestcolor;
    +    xx0 = inc0;
    +    for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
    +      dist1 = dist0;
    +      xx1 = inc1;
    +      for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
    +        dist2 = dist1;
    +        xx2 = inc2;
    +        for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
    +          if (dist2 < *bptr) {
    +            *bptr = dist2;
    +            *cptr = (JSAMPLE) icolor;
    +          }
    +          dist2 += xx2;
    +          xx2 += 2 * STEP_C2 * STEP_C2;
    +          bptr++;
    +          cptr++;
    +        }
    +        dist1 += xx1;
    +        xx1 += 2 * STEP_C1 * STEP_C1;
    +      }
    +      dist0 += xx0;
    +      xx0 += 2 * STEP_C0 * STEP_C0;
    +    }
    +  }
    +}
    +
    +
    +LOCAL(void)
    +fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
    +/* Fill the inverse-colormap entries in the update box that contains */
    +/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
    +/* we can fill as many others as we wish.) */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  int minc0, minc1, minc2;      /* lower left corner of update box */
    +  int ic0, ic1, ic2;
    +  register JSAMPLE * cptr;      /* pointer into bestcolor[] array */
    +  register histptr cachep;      /* pointer into main cache array */
    +  /* This array lists the candidate colormap indexes. */
    +  JSAMPLE colorlist[MAXNUMCOLORS];
    +  int numcolors;                /* number of candidate colors */
    +  /* This array holds the actually closest colormap index for each cell. */
    +  JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
    +
    +  /* Convert cell coordinates to update box ID */
    +  c0 >>= BOX_C0_LOG;
    +  c1 >>= BOX_C1_LOG;
    +  c2 >>= BOX_C2_LOG;
    +
    +  /* Compute true coordinates of update box's origin corner.
    +   * Actually we compute the coordinates of the center of the corner
    +   * histogram cell, which are the lower bounds of the volume we care about.
    +   */
    +  minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
    +  minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
    +  minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
    +
    +  /* Determine which colormap entries are close enough to be candidates
    +   * for the nearest entry to some cell in the update box.
    +   */
    +  numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
    +
    +  /* Determine the actually nearest colors. */
    +  find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
    +                   bestcolor);
    +
    +  /* Save the best color numbers (plus 1) in the main cache array */
    +  c0 <<= BOX_C0_LOG;            /* convert ID back to base cell indexes */
    +  c1 <<= BOX_C1_LOG;
    +  c2 <<= BOX_C2_LOG;
    +  cptr = bestcolor;
    +  for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
    +    for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
    +      cachep = & histogram[c0+ic0][c1+ic1][c2];
    +      for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
    +        *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
    +      }
    +    }
    +  }
    +}
    +
    +
    +/*
    + * Map some rows of pixels to the output colormapped representation.
    + */
    +
    +METHODDEF(void)
    +pass2_no_dither (j_decompress_ptr cinfo,
    +                 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
    +/* This version performs no dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  register JSAMPROW inptr, outptr;
    +  register histptr cachep;
    +  register int c0, c1, c2;
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +
    +  for (row = 0; row < num_rows; row++) {
    +    inptr = input_buf[row];
    +    outptr = output_buf[row];
    +    for (col = width; col > 0; col--) {
    +      /* get pixel value and index into the cache */
    +      c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
    +      c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
    +      c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
    +      cachep = & histogram[c0][c1][c2];
    +      /* If we have not seen this color before, find nearest colormap entry */
    +      /* and update the cache */
    +      if (*cachep == 0)
    +        fill_inverse_cmap(cinfo, c0,c1,c2);
    +      /* Now emit the colormap index for this cell */
    +      *outptr++ = (JSAMPLE) (*cachep - 1);
    +    }
    +  }
    +}
    +
    +
    +METHODDEF(void)
    +pass2_fs_dither (j_decompress_ptr cinfo,
    +                 JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
    +/* This version performs Floyd-Steinberg dithering */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */
    +  LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
    +  LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
    +  register FSERRPTR errorptr;   /* => fserrors[] at column before current */
    +  JSAMPROW inptr;               /* => current input pixel */
    +  JSAMPROW outptr;              /* => current output pixel */
    +  histptr cachep;
    +  int dir;                      /* +1 or -1 depending on direction */
    +  int dir3;                     /* 3*dir, for advancing inptr & errorptr */
    +  int row;
    +  JDIMENSION col;
    +  JDIMENSION width = cinfo->output_width;
    +  JSAMPLE *range_limit = cinfo->sample_range_limit;
    +  int *error_limit = cquantize->error_limiter;
    +  JSAMPROW colormap0 = cinfo->colormap[0];
    +  JSAMPROW colormap1 = cinfo->colormap[1];
    +  JSAMPROW colormap2 = cinfo->colormap[2];
    +  SHIFT_TEMPS
    +
    +  for (row = 0; row < num_rows; row++) {
    +    inptr = input_buf[row];
    +    outptr = output_buf[row];
    +    if (cquantize->on_odd_row) {
    +      /* work right to left in this row */
    +      inptr += (width-1) * 3;   /* so point to rightmost pixel */
    +      outptr += width-1;
    +      dir = -1;
    +      dir3 = -3;
    +      errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
    +      cquantize->on_odd_row = FALSE; /* flip for next time */
    +    } else {
    +      /* work left to right in this row */
    +      dir = 1;
    +      dir3 = 3;
    +      errorptr = cquantize->fserrors; /* => entry before first real column */
    +      cquantize->on_odd_row = TRUE; /* flip for next time */
    +    }
    +    /* Preset error values: no error propagated to first pixel from left */
    +    cur0 = cur1 = cur2 = 0;
    +    /* and no error propagated to row below yet */
    +    belowerr0 = belowerr1 = belowerr2 = 0;
    +    bpreverr0 = bpreverr1 = bpreverr2 = 0;
    +
    +    for (col = width; col > 0; col--) {
    +      /* curN holds the error propagated from the previous pixel on the
    +       * current line.  Add the error propagated from the previous line
    +       * to form the complete error correction term for this pixel, and
    +       * round the error term (which is expressed * 16) to an integer.
    +       * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
    +       * for either sign of the error value.
    +       * Note: errorptr points to *previous* column's array entry.
    +       */
    +      cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
    +      cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
    +      cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
    +      /* Limit the error using transfer function set by init_error_limit.
    +       * See comments with init_error_limit for rationale.
    +       */
    +      cur0 = error_limit[cur0];
    +      cur1 = error_limit[cur1];
    +      cur2 = error_limit[cur2];
    +      /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
    +       * The maximum error is +- MAXJSAMPLE (or less with error limiting);
    +       * this sets the required size of the range_limit array.
    +       */
    +      cur0 += GETJSAMPLE(inptr[0]);
    +      cur1 += GETJSAMPLE(inptr[1]);
    +      cur2 += GETJSAMPLE(inptr[2]);
    +      cur0 = GETJSAMPLE(range_limit[cur0]);
    +      cur1 = GETJSAMPLE(range_limit[cur1]);
    +      cur2 = GETJSAMPLE(range_limit[cur2]);
    +      /* Index into the cache with adjusted pixel value */
    +      cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
    +      /* If we have not seen this color before, find nearest colormap */
    +      /* entry and update the cache */
    +      if (*cachep == 0)
    +        fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
    +      /* Now emit the colormap index for this cell */
    +      { register int pixcode = *cachep - 1;
    +        *outptr = (JSAMPLE) pixcode;
    +        /* Compute representation error for this pixel */
    +        cur0 -= GETJSAMPLE(colormap0[pixcode]);
    +        cur1 -= GETJSAMPLE(colormap1[pixcode]);
    +        cur2 -= GETJSAMPLE(colormap2[pixcode]);
    +      }
    +      /* Compute error fractions to be propagated to adjacent pixels.
    +       * Add these into the running sums, and simultaneously shift the
    +       * next-line error sums left by 1 column.
    +       */
    +      { register LOCFSERROR bnexterr, delta;
    +
    +        bnexterr = cur0;        /* Process component 0 */
    +        delta = cur0 * 2;
    +        cur0 += delta;          /* form error * 3 */
    +        errorptr[0] = (FSERROR) (bpreverr0 + cur0);
    +        cur0 += delta;          /* form error * 5 */
    +        bpreverr0 = belowerr0 + cur0;
    +        belowerr0 = bnexterr;
    +        cur0 += delta;          /* form error * 7 */
    +        bnexterr = cur1;        /* Process component 1 */
    +        delta = cur1 * 2;
    +        cur1 += delta;          /* form error * 3 */
    +        errorptr[1] = (FSERROR) (bpreverr1 + cur1);
    +        cur1 += delta;          /* form error * 5 */
    +        bpreverr1 = belowerr1 + cur1;
    +        belowerr1 = bnexterr;
    +        cur1 += delta;          /* form error * 7 */
    +        bnexterr = cur2;        /* Process component 2 */
    +        delta = cur2 * 2;
    +        cur2 += delta;          /* form error * 3 */
    +        errorptr[2] = (FSERROR) (bpreverr2 + cur2);
    +        cur2 += delta;          /* form error * 5 */
    +        bpreverr2 = belowerr2 + cur2;
    +        belowerr2 = bnexterr;
    +        cur2 += delta;          /* form error * 7 */
    +      }
    +      /* At this point curN contains the 7/16 error value to be propagated
    +       * to the next pixel on the current line, and all the errors for the
    +       * next line have been shifted over.  We are therefore ready to move on.
    +       */
    +      inptr += dir3;            /* Advance pixel pointers to next column */
    +      outptr += dir;
    +      errorptr += dir3;         /* advance errorptr to current column */
    +    }
    +    /* Post-loop cleanup: we must unload the final error values into the
    +     * final fserrors[] entry.  Note we need not unload belowerrN because
    +     * it is for the dummy column before or after the actual array.
    +     */
    +    errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
    +    errorptr[1] = (FSERROR) bpreverr1;
    +    errorptr[2] = (FSERROR) bpreverr2;
    +  }
    +}
    +
    +
    +/*
    + * Initialize the error-limiting transfer function (lookup table).
    + * The raw F-S error computation can potentially compute error values of up to
    + * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
    + * much less, otherwise obviously wrong pixels will be created.  (Typical
    + * effects include weird fringes at color-area boundaries, isolated bright
    + * pixels in a dark area, etc.)  The standard advice for avoiding this problem
    + * is to ensure that the "corners" of the color cube are allocated as output
    + * colors; then repeated errors in the same direction cannot cause cascading
    + * error buildup.  However, that only prevents the error from getting
    + * completely out of hand; Aaron Giles reports that error limiting improves
    + * the results even with corner colors allocated.
    + * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
    + * well, but the smoother transfer function used below is even better.  Thanks
    + * to Aaron Giles for this idea.
    + */
    +
    +LOCAL(void)
    +init_error_limit (j_decompress_ptr cinfo)
    +/* Allocate and fill in the error_limiter table */
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  int * table;
    +  int in, out;
    +
    +  table = (int *) (*cinfo->mem->alloc_small)
    +    ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
    +  table += MAXJSAMPLE;          /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
    +  cquantize->error_limiter = table;
    +
    +#define STEPSIZE ((MAXJSAMPLE+1)/16)
    +  /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
    +  out = 0;
    +  for (in = 0; in < STEPSIZE; in++, out++) {
    +    table[in] = out; table[-in] = -out;
    +  }
    +  /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
    +  for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
    +    table[in] = out; table[-in] = -out;
    +  }
    +  /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
    +  for (; in <= MAXJSAMPLE; in++) {
    +    table[in] = out; table[-in] = -out;
    +  }
    +#undef STEPSIZE
    +}
    +
    +
    +/*
    + * Finish up at the end of each pass.
    + */
    +
    +METHODDEF(void)
    +finish_pass1 (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +
    +  /* Select the representative colors and fill in cinfo->colormap */
    +  cinfo->colormap = cquantize->sv_colormap;
    +  select_colors(cinfo, cquantize->desired);
    +  /* Force next pass to zero the color index table */
    +  cquantize->needs_zeroed = TRUE;
    +}
    +
    +
    +METHODDEF(void)
    +finish_pass2 (j_decompress_ptr cinfo)
    +{
    +  /* no work */
    +}
    +
    +
    +/*
    + * Initialize for each processing pass.
    + */
    +
    +METHODDEF(void)
    +start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +  hist3d histogram = cquantize->histogram;
    +  int i;
    +
    +  /* Only F-S dithering or no dithering is supported. */
    +  /* If user asks for ordered dither, give him F-S. */
    +  if (cinfo->dither_mode != JDITHER_NONE)
    +    cinfo->dither_mode = JDITHER_FS;
    +
    +  if (is_pre_scan) {
    +    /* Set up method pointers */
    +    cquantize->pub.color_quantize = prescan_quantize;
    +    cquantize->pub.finish_pass = finish_pass1;
    +    cquantize->needs_zeroed = TRUE; /* Always zero histogram */
    +  } else {
    +    /* Set up method pointers */
    +    if (cinfo->dither_mode == JDITHER_FS)
    +      cquantize->pub.color_quantize = pass2_fs_dither;
    +    else
    +      cquantize->pub.color_quantize = pass2_no_dither;
    +    cquantize->pub.finish_pass = finish_pass2;
    +
    +    /* Make sure color count is acceptable */
    +    i = cinfo->actual_number_of_colors;
    +    if (i < 1)
    +      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
    +    if (i > MAXNUMCOLORS)
    +      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
    +
    +    if (cinfo->dither_mode == JDITHER_FS) {
    +      size_t arraysize = (size_t) ((cinfo->output_width + 2) *
    +                                   (3 * SIZEOF(FSERROR)));
    +      /* Allocate Floyd-Steinberg workspace if we didn't already. */
    +      if (cquantize->fserrors == NULL)
    +        cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
    +          ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
    +      /* Initialize the propagated errors to zero. */
    +      jzero_far((void FAR *) cquantize->fserrors, arraysize);
    +      /* Make the error-limit table if we didn't already. */
    +      if (cquantize->error_limiter == NULL)
    +        init_error_limit(cinfo);
    +      cquantize->on_odd_row = FALSE;
    +    }
    +
    +  }
    +  /* Zero the histogram or inverse color map, if necessary */
    +  if (cquantize->needs_zeroed) {
    +    for (i = 0; i < HIST_C0_ELEMS; i++) {
    +      jzero_far((void FAR *) histogram[i],
    +                HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
    +    }
    +    cquantize->needs_zeroed = FALSE;
    +  }
    +}
    +
    +
    +/*
    + * Switch to a new external colormap between output passes.
    + */
    +
    +METHODDEF(void)
    +new_color_map_2_quant (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
    +
    +  /* Reset the inverse color map */
    +  cquantize->needs_zeroed = TRUE;
    +}
    +
    +
    +/*
    + * Module initialization routine for 2-pass color quantization.
    + */
    +
    +GLOBAL(void)
    +jinit_2pass_quantizer (j_decompress_ptr cinfo)
    +{
    +  my_cquantize_ptr cquantize;
    +  int i;
    +
    +  cquantize = (my_cquantize_ptr)
    +    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +                                SIZEOF(my_cquantizer));
    +  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
    +  cquantize->pub.start_pass = start_pass_2_quant;
    +  cquantize->pub.new_color_map = new_color_map_2_quant;
    +  cquantize->fserrors = NULL;   /* flag optional arrays not allocated */
    +  cquantize->error_limiter = NULL;
    +
    +  /* Make sure jdmaster didn't give me a case I can't handle */
    +  if (cinfo->out_color_components != 3)
    +    ERREXIT(cinfo, JERR_NOTIMPL);
    +
    +  /* Allocate the histogram/inverse colormap storage */
    +  cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
    +    ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
    +  for (i = 0; i < HIST_C0_ELEMS; i++) {
    +    cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
    +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +       HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
    +  }
    +  cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
    +
    +  /* Allocate storage for the completed colormap, if required.
    +   * We do this now since it is FAR storage and may affect
    +   * the memory manager's space calculations.
    +   */
    +  if (cinfo->enable_2pass_quant) {
    +    /* Make sure color count is acceptable */
    +    int desired = cinfo->desired_number_of_colors;
    +    /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
    +    if (desired < 8)
    +      ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
    +    /* Make sure colormap indexes can be represented by JSAMPLEs */
    +    if (desired > MAXNUMCOLORS)
    +      ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
    +    cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
    +      ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
    +    cquantize->desired = desired;
    +  } else
    +    cquantize->sv_colormap = NULL;
    +
    +  /* Only F-S dithering or no dithering is supported. */
    +  /* If user asks for ordered dither, give him F-S. */
    +  if (cinfo->dither_mode != JDITHER_NONE)
    +    cinfo->dither_mode = JDITHER_FS;
    +
    +  /* Allocate Floyd-Steinberg workspace if necessary.
    +   * This isn't really needed until pass 2, but again it is FAR storage.
    +   * Although we will cope with a later change in dither_mode,
    +   * we do not promise to honor max_memory_to_use if dither_mode changes.
    +   */
    +  if (cinfo->dither_mode == JDITHER_FS) {
    +    cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
    +      ((j_common_ptr) cinfo, JPOOL_IMAGE,
    +       (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
    +    /* Might as well create the error-limiting table too. */
    +    init_error_limit(cinfo);
    +  }
    +}
    +
    +#endif /* QUANT_2PASS_SUPPORTED */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jutils.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jutils.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jutils.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jutils.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,183 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jutils.c
    + *
    + * Copyright (C) 1991-1996, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains tables and miscellaneous utility routines needed
    + * for both compression and decompression.
    + * Note we prefix all global names with "j" to minimize conflicts with
    + * a surrounding application.
    + */
    +
    +#define JPEG_INTERNALS
    +#include "jinclude.h"
    +#include "jpeglib.h"
    +
    +
    +/*
    + * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
    + * of a DCT block read in natural order (left to right, top to bottom).
    + */
    +
    +#if 0                           /* This table is not actually needed in v6a */
    +
    +const int jpeg_zigzag_order[DCTSIZE2] = {
    +   0,  1,  5,  6, 14, 15, 27, 28,
    +   2,  4,  7, 13, 16, 26, 29, 42,
    +   3,  8, 12, 17, 25, 30, 41, 43,
    +   9, 11, 18, 24, 31, 40, 44, 53,
    +  10, 19, 23, 32, 39, 45, 52, 54,
    +  20, 22, 33, 38, 46, 51, 55, 60,
    +  21, 34, 37, 47, 50, 56, 59, 61,
    +  35, 36, 48, 49, 57, 58, 62, 63
    +};
    +
    +#endif
    +
    +/*
    + * jpeg_natural_order[i] is the natural-order position of the i'th element
    + * of zigzag order.
    + *
    + * When reading corrupted data, the Huffman decoders could attempt
    + * to reference an entry beyond the end of this array (if the decoded
    + * zero run length reaches past the end of the block).  To prevent
    + * wild stores without adding an inner-loop test, we put some extra
    + * "63"s after the real entries.  This will cause the extra coefficient
    + * to be stored in location 63 of the block, not somewhere random.
    + * The worst case would be a run-length of 15, which means we need 16
    + * fake entries.
    + */
    +
    +const int jpeg_natural_order[DCTSIZE2+16] = {
    +  0,  1,  8, 16,  9,  2,  3, 10,
    + 17, 24, 32, 25, 18, 11,  4,  5,
    + 12, 19, 26, 33, 40, 48, 41, 34,
    + 27, 20, 13,  6,  7, 14, 21, 28,
    + 35, 42, 49, 56, 57, 50, 43, 36,
    + 29, 22, 15, 23, 30, 37, 44, 51,
    + 58, 59, 52, 45, 38, 31, 39, 46,
    + 53, 60, 61, 54, 47, 55, 62, 63,
    + 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
    + 63, 63, 63, 63, 63, 63, 63, 63
    +};
    +
    +
    +/*
    + * Arithmetic utilities
    + */
    +
    +GLOBAL(long)
    +jdiv_round_up (long a, long b)
    +/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
    +/* Assumes a >= 0, b > 0 */
    +{
    +  return (a + b - 1L) / b;
    +}
    +
    +
    +GLOBAL(long)
    +jround_up (long a, long b)
    +/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
    +/* Assumes a >= 0, b > 0 */
    +{
    +  a += b - 1L;
    +  return a - (a % b);
    +}
    +
    +
    +/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
    + * and coefficient-block arrays.  This won't work on 80x86 because the arrays
    + * are FAR and we're assuming a small-pointer memory model.  However, some
    + * DOS compilers provide far-pointer versions of memcpy() and memset() even
    + * in the small-model libraries.  These will be used if USE_FMEM is defined.
    + * Otherwise, the routines below do it the hard way.  (The performance cost
    + * is not all that great, because these routines aren't very heavily used.)
    + */
    +
    +#ifndef NEED_FAR_POINTERS       /* normal case, same as regular macros */
    +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
    +#define FMEMZERO(target,size)   MEMZERO(target,size)
    +#else                           /* 80x86 case, define if we can */
    +#ifdef USE_FMEM
    +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
    +#define FMEMZERO(target,size)   _fmemset((void FAR *)(target), 0, (size_t)(size))
    +#endif
    +#endif
    +
    +
    +GLOBAL(void)
    +jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
    +                   JSAMPARRAY output_array, int dest_row,
    +                   int num_rows, JDIMENSION num_cols)
    +/* Copy some rows of samples from one place to another.
    + * num_rows rows are copied from input_array[source_row++]
    + * to output_array[dest_row++]; these areas may overlap for duplication.
    + * The source and destination arrays must be at least as wide as num_cols.
    + */
    +{
    +  register JSAMPROW inptr, outptr;
    +#ifdef FMEMCOPY
    +  register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
    +#else
    +  register JDIMENSION count;
    +#endif
    +  register int row;
    +
    +  input_array += source_row;
    +  output_array += dest_row;
    +
    +  for (row = num_rows; row > 0; row--) {
    +    inptr = *input_array++;
    +    outptr = *output_array++;
    +#ifdef FMEMCOPY
    +    FMEMCOPY(outptr, inptr, count);
    +#else
    +    for (count = num_cols; count > 0; count--)
    +      *outptr++ = *inptr++;     /* needn't bother with GETJSAMPLE() here */
    +#endif
    +  }
    +}
    +
    +
    +GLOBAL(void)
    +jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
    +                 JDIMENSION num_blocks)
    +/* Copy a row of coefficient blocks from one place to another. */
    +{
    +#ifdef FMEMCOPY
    +  FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
    +#else
    +  register JCOEFPTR inptr, outptr;
    +  register long count;
    +
    +  inptr = (JCOEFPTR) input_row;
    +  outptr = (JCOEFPTR) output_row;
    +  for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
    +    *outptr++ = *inptr++;
    +  }
    +#endif
    +}
    +
    +
    +GLOBAL(void)
    +jzero_far (void FAR * target, size_t bytestozero)
    +/* Zero out a chunk of FAR memory. */
    +/* This might be sample-array data, block-array data, or alloc_large data. */
    +{
    +#ifdef FMEMZERO
    +  FMEMZERO(target, bytestozero);
    +#else
    +  register char FAR * ptr = (char FAR *) target;
    +  register size_t count;
    +
    +  for (count = bytestozero; count > 0; count--) {
    +    *ptr++ = 0;
    +  }
    +#endif
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jversion.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jversion.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/jversion.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/jversion.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,18 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * jversion.h
    + *
    + * Copyright (C) 1991-1998, Thomas G. Lane.
    + * This file is part of the Independent JPEG Group's software.
    + * For conditions of distribution and use, see the accompanying README file.
    + *
    + * This file contains software version identification.
    + */
    +
    +
    +#define JVERSION        "6b  27-Mar-1998"
    +
    +#define JCOPYRIGHT      "Copyright (C) 1998, Thomas G. Lane"
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/README openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/README
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libjavajpeg/README	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libjavajpeg/README	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,385 @@
    +The Independent JPEG Group's JPEG software
    +==========================================
    +
    +README for release 6b of 27-Mar-1998
    +====================================
    +
    +This distribution contains the sixth public release of the Independent JPEG
    +Group's free JPEG software.  You are welcome to redistribute this software and
    +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
    +
    +Serious users of this software (particularly those incorporating it into
    +larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
    +our electronic mailing list.  Mailing list members are notified of updates
    +and have a chance to participate in technical discussions, etc.
    +
    +This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
    +Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
    +Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
    +Group.
    +
    +IJG is not affiliated with the official ISO JPEG standards committee.
    +
    +
    +DOCUMENTATION ROADMAP
    +=====================
    +
    +This file contains the following sections:
    +
    +OVERVIEW            General description of JPEG and the IJG software.
    +LEGAL ISSUES        Copyright, lack of warranty, terms of distribution.
    +REFERENCES          Where to learn more about JPEG.
    +ARCHIVE LOCATIONS   Where to find newer versions of this software.
    +RELATED SOFTWARE    Other stuff you should get.
    +FILE FORMAT WARS    Software *not* to get.
    +TO DO               Plans for future IJG releases.
    +
    +Other documentation files in the distribution are:
    +
    +User documentation:
    +  install.doc       How to configure and install the IJG software.
    +  usage.doc         Usage instructions for cjpeg, djpeg, jpegtran,
    +                    rdjpgcom, and wrjpgcom.
    +  *.1               Unix-style man pages for programs (same info as usage.doc).
    +  wizard.doc        Advanced usage instructions for JPEG wizards only.
    +  change.log        Version-to-version change highlights.
    +Programmer and internal documentation:
    +  libjpeg.doc       How to use the JPEG library in your own programs.
    +  example.c         Sample code for calling the JPEG library.
    +  structure.doc     Overview of the JPEG library's internal structure.
    +  filelist.doc      Road map of IJG files.
    +  coderules.doc     Coding style rules --- please read if you contribute code.
    +
    +Please read at least the files install.doc and usage.doc.  Useful information
    +can also be found in the JPEG FAQ (Frequently Asked Questions) article.  See
    +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
    +
    +If you want to understand how the JPEG code works, we suggest reading one or
    +more of the REFERENCES, then looking at the documentation files (in roughly
    +the order listed) before diving into the code.
    +
    +
    +OVERVIEW
    +========
    +
    +This package contains C software to implement JPEG image compression and
    +decompression.  JPEG (pronounced "jay-peg") is a standardized compression
    +method for full-color and gray-scale images.  JPEG is intended for compressing
    +"real-world" scenes; line drawings, cartoons and other non-realistic images
    +are not its strong suit.  JPEG is lossy, meaning that the output image is not
    +exactly identical to the input image.  Hence you must not use JPEG if you
    +have to have identical output bits.  However, on typical photographic images,
    +very good compression levels can be obtained with no visible change, and
    +remarkably high compression levels are possible if you can tolerate a
    +low-quality image.  For more details, see the references, or just experiment
    +with various compression settings.
    +
    +This software implements JPEG baseline, extended-sequential, and progressive
    +compression processes.  Provision is made for supporting all variants of these
    +processes, although some uncommon parameter settings aren't implemented yet.
    +For legal reasons, we are not distributing code for the arithmetic-coding
    +variants of JPEG; see LEGAL ISSUES.  We have made no provision for supporting
    +the hierarchical or lossless processes defined in the standard.
    +
    +We provide a set of library routines for reading and writing JPEG image files,
    +plus two sample applications "cjpeg" and "djpeg", which use the library to
    +perform conversion between JPEG and some other popular image file formats.
    +The library is intended to be reused in other applications.
    +
    +In order to support file conversion and viewing software, we have included
    +considerable functionality beyond the bare JPEG coding/decoding capability;
    +for example, the color quantization modules are not strictly part of JPEG
    +decoding, but they are essential for output to colormapped file formats or
    +colormapped displays.  These extra functions can be compiled out of the
    +library if not required for a particular application.  We have also included
    +"jpegtran", a utility for lossless transcoding between different JPEG
    +processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
    +inserting and extracting textual comments in JFIF files.
    +
    +The emphasis in designing this software has been on achieving portability and
    +flexibility, while also making it fast enough to be useful.  In particular,
    +the software is not intended to be read as a tutorial on JPEG.  (See the
    +REFERENCES section for introductory material.)  Rather, it is intended to
    +be reliable, portable, industrial-strength code.  We do not claim to have
    +achieved that goal in every aspect of the software, but we strive for it.
    +
    +We welcome the use of this software as a component of commercial products.
    +No royalty is required, but we do ask for an acknowledgement in product
    +documentation, as described under LEGAL ISSUES.
    +
    +
    +LEGAL ISSUES
    +============
    +
    +In plain English:
    +
    +1. We don't promise that this software works.  (But if you find any bugs,
    +   please let us know!)
    +2. You can use this software for whatever you want.  You don't have to pay us.
    +3. You may not pretend that you wrote this software.  If you use it in a
    +   program, you must acknowledge somewhere in your documentation that
    +   you've used the IJG code.
    +
    +In legalese:
    +
    +The authors make NO WARRANTY or representation, either express or implied,
    +with respect to this software, its quality, accuracy, merchantability, or
    +fitness for a particular purpose.  This software is provided "AS IS", and you,
    +its user, assume the entire risk as to its quality and accuracy.
    +
    +This software is copyright (C) 1991-1998, Thomas G. Lane.
    +All Rights Reserved except as specified below.
    +
    +Permission is hereby granted to use, copy, modify, and distribute this
    +software (or portions thereof) for any purpose, without fee, subject to these
    +conditions:
    +(1) If any part of the source code for this software is distributed, then this
    +README file must be included, with this copyright and no-warranty notice
    +unaltered; and any additions, deletions, or changes to the original files
    +must be clearly indicated in accompanying documentation.
    +(2) If only executable code is distributed, then the accompanying
    +documentation must state that "this software is based in part on the work of
    +the Independent JPEG Group".
    +(3) Permission for use of this software is granted only if the user accepts
    +full responsibility for any undesirable consequences; the authors accept
    +NO LIABILITY for damages of any kind.
    +
    +These conditions apply to any software derived from or based on the IJG code,
    +not just to the unmodified library.  If you use our work, you ought to
    +acknowledge us.
    +
    +Permission is NOT granted for the use of any IJG author's name or company name
    +in advertising or publicity relating to this software or products derived from
    +it.  This software may be referred to only as "the Independent JPEG Group's
    +software".
    +
    +We specifically permit and encourage the use of this software as the basis of
    +commercial products, provided that all warranty or liability claims are
    +assumed by the product vendor.
    +
    +
    +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
    +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
    +ansi2knr.c is NOT covered by the above copyright and conditions, but instead
    +by the usual distribution terms of the Free Software Foundation; principally,
    +that you must include source code if you redistribute it.  (See the file
    +ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
    +of any program generated from the IJG code, this does not limit you more than
    +the foregoing paragraphs do.
    +
    +The Unix configuration script "configure" was produced with GNU Autoconf.
    +It is copyright by the Free Software Foundation but is freely distributable.
    +The same holds for its supporting scripts (config.guess, config.sub,
    +ltconfig, ltmain.sh).  Another support script, install-sh, is copyright
    +by M.I.T. but is also freely distributable.
    +
    +It appears that the arithmetic coding option of the JPEG spec is covered by
    +patents owned by IBM, AT&T, and Mitsubishi.  Hence arithmetic coding cannot
    +legally be used without obtaining one or more licenses.  For this reason,
    +support for arithmetic coding has been removed from the free JPEG software.
    +(Since arithmetic coding provides only a marginal gain over the unpatented
    +Huffman mode, it is unlikely that very many implementations will support it.)
    +So far as we are aware, there are no patent restrictions on the remaining
    +code.
    +
    +The IJG distribution formerly included code to read and write GIF files.
    +To avoid entanglement with the Unisys LZW patent, GIF reading support has
    +been removed altogether, and the GIF writer has been simplified to produce
    +"uncompressed GIFs".  This technique does not use the LZW algorithm; the
    +resulting GIF files are larger than usual, but are readable by all standard
    +GIF decoders.
    +
    +We are required to state that
    +    "The Graphics Interchange Format(c) is the Copyright property of
    +    CompuServe Incorporated.  GIF(sm) is a Service Mark property of
    +    CompuServe Incorporated."
    +
    +
    +REFERENCES
    +==========
    +
    +We highly recommend reading one or more of these references before trying to
    +understand the innards of the JPEG software.
    +
    +The best short technical introduction to the JPEG compression algorithm is
    +	Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
    +	Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
    +(Adjacent articles in that issue discuss MPEG motion picture compression,
    +applications of JPEG, and related topics.)  If you don't have the CACM issue
    +handy, a PostScript file containing a revised version of Wallace's article is
    +available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz.  The file (actually
    +a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
    +omits the sample images that appeared in CACM, but it includes corrections
    +and some added material.  Note: the Wallace article is copyright ACM and IEEE,
    +and it may not be used for commercial purposes.
    +
    +A somewhat less technical, more leisurely introduction to JPEG can be found in
    +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
    +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1.  This book provides
    +good explanations and example C code for a multitude of compression methods
    +including JPEG.  It is an excellent source if you are comfortable reading C
    +code but don't know much about data compression in general.  The book's JPEG
    +sample code is far from industrial-strength, but when you are ready to look
    +at a full implementation, you've got one here...
    +
    +The best full description of JPEG is the textbook "JPEG Still Image Data
    +Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
    +by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.  Price US$59.95, 638 pp.
    +The book includes the complete text of the ISO JPEG standards (DIS 10918-1
    +and draft DIS 10918-2).  This is by far the most complete exposition of JPEG
    +in existence, and we highly recommend it.
    +
    +The JPEG standard itself is not available electronically; you must order a
    +paper copy through ISO or ITU.  (Unless you feel a need to own a certified
    +official copy, we recommend buying the Pennebaker and Mitchell book instead;
    +it's much cheaper and includes a great deal of useful explanatory material.)
    +In the USA, copies of the standard may be ordered from ANSI Sales at (212)
    +642-4900, or from Global Engineering Documents at (800) 854-7179.  (ANSI
    +doesn't take credit card orders, but Global does.)  It's not cheap: as of
    +1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
    +shipping/handling.  The standard is divided into two parts, Part 1 being the
    +actual specification, while Part 2 covers compliance testing methods.  Part 1
    +is titled "Digital Compression and Coding of Continuous-tone Still Images,
    +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
    +10918-1, ITU-T T.81.  Part 2 is titled "Digital Compression and Coding of
    +Continuous-tone Still Images, Part 2: Compliance testing" and has document
    +numbers ISO/IEC IS 10918-2, ITU-T T.83.
    +
    +Some extensions to the original JPEG standard are defined in JPEG Part 3,
    +a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84.  IJG
    +currently does not support any Part 3 extensions.
    +
    +The JPEG standard does not specify all details of an interchangeable file
    +format.  For the omitted details we follow the "JFIF" conventions, revision
    +1.02.  A copy of the JFIF spec is available from:
    +	Literature Department
    +	C-Cube Microsystems, Inc.
    +	1778 McCarthy Blvd.
    +	Milpitas, CA 95035
    +	phone (408) 944-6300,  fax (408) 944-6314
    +A PostScript version of this document is available by FTP at
    +ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz.  There is also a plain text
    +version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
    +the figures.
    +
    +The TIFF 6.0 file format specification can be obtained by FTP from
    +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation scheme
    +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
    +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
    +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
    +(Compression tag 7).  Copies of this Note can be obtained from ftp.sgi.com or
    +from ftp://ftp.uu.net/graphics/jpeg/.  It is expected that the next revision
    +of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
    +Although IJG's own code does not support TIFF/JPEG, the free libtiff library
    +uses our library to implement TIFF/JPEG per the Note.  libtiff is available
    +from ftp://ftp.sgi.com/graphics/tiff/.
    +
    +
    +ARCHIVE LOCATIONS
    +=================
    +
    +The "official" archive site for this software is ftp.uu.net (Internet
    +address 192.48.96.9).  The most recent released version can always be found
    +there in directory graphics/jpeg.  This particular version will be archived
    +as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz.  If you don't have
    +direct Internet access, UUNET's archives are also available via UUCP; contact
    +help@uunet.uu.net for information on retrieving files that way.
    +
    +Numerous Internet sites maintain copies of the UUNET files.  However, only
    +ftp.uu.net is guaranteed to have the latest official version.
    +
    +You can also obtain this software in DOS-compatible "zip" archive format from
    +the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
    +on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
    +"JPEG Tools".  Again, these versions may sometimes lag behind the ftp.uu.net
    +release.
    +
    +The JPEG FAQ (Frequently Asked Questions) article is a useful source of
    +general information about JPEG.  It is updated constantly and therefore is
    +not included in this distribution.  The FAQ is posted every two weeks to
    +Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
    +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
    +and other news.answers archive sites, including the official news.answers
    +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
    +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
    +with body
    +	send usenet/news.answers/jpeg-faq/part1
    +	send usenet/news.answers/jpeg-faq/part2
    +
    +
    +RELATED SOFTWARE
    +================
    +
    +Numerous viewing and image manipulation programs now support JPEG.  (Quite a
    +few of them use this library to do so.)  The JPEG FAQ described above lists
    +some of the more popular free and shareware viewers, and tells where to
    +obtain them on Internet.
    +
    +If you are on a Unix machine, we highly recommend Jef Poskanzer's free
    +PBMPLUS software, which provides many useful operations on PPM-format image
    +files.  In particular, it can convert PPM images to and from a wide range of
    +other formats, thus making cjpeg/djpeg considerably more useful.  The latest
    +version is distributed by the NetPBM group, and is available from numerous
    +sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
    +Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
    +you are likely to have difficulty making it work on any non-Unix machine.
    +
    +A different free JPEG implementation, written by the PVRG group at Stanford,
    +is available from ftp://havefun.stanford.edu/pub/jpeg/.  This program
    +is designed for research and experimentation rather than production use;
    +it is slower, harder to use, and less portable than the IJG code, but it
    +is easier to read and modify.  Also, the PVRG code supports lossless JPEG,
    +which we do not.  (On the other hand, it doesn't do progressive JPEG.)
    +
    +
    +FILE FORMAT WARS
    +================
    +
    +Some JPEG programs produce files that are not compatible with our library.
    +The root of the problem is that the ISO JPEG committee failed to specify a
    +concrete file format.  Some vendors "filled in the blanks" on their own,
    +creating proprietary formats that no one else could read.  (For example, none
    +of the early commercial JPEG implementations for the Macintosh were able to
    +exchange compressed files.)
    +
    +The file format we have adopted is called JFIF (see REFERENCES).  This format
    +has been agreed to by a number of major commercial JPEG vendors, and it has
    +become the de facto standard.  JFIF is a minimal or "low end" representation.
    +We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
    +Technical Note #2) for "high end" applications that need to record a lot of
    +additional data about an image.  TIFF/JPEG is fairly new and not yet widely
    +supported, unfortunately.
    +
    +The upcoming JPEG Part 3 standard defines a file format called SPIFF.
    +SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
    +be able to read the most common variant of SPIFF.  SPIFF has some technical
    +advantages over JFIF, but its major claim to fame is simply that it is an
    +official standard rather than an informal one.  At this point it is unclear
    +whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
    +standard.  IJG intends to support SPIFF once the standard is frozen, but we
    +have not decided whether it should become our default output format or not.
    +(In any case, our decoder will remain capable of reading JFIF indefinitely.)
    +
    +Various proprietary file formats incorporating JPEG compression also exist.
    +We have little or no sympathy for the existence of these formats.  Indeed,
    +one of the original reasons for developing this free software was to help
    +force convergence on common, open format standards for JPEG files.  Don't
    +use a proprietary file format!
    +
    +
    +TO DO
    +=====
    +
    +The major thrust for v7 will probably be improvement of visual quality.
    +The current method for scaling the quantization tables is known not to be
    +very good at low Q values.  We also intend to investigate block boundary
    +smoothing, "poor man's variable quantization", and other means of improving
    +quality-vs-file-size performance without sacrificing compatibility.
    +
    +In future versions, we are considering supporting some of the upcoming JPEG
    +Part 3 extensions --- principally, variable quantization and the SPIFF file
    +format.
    +
    +As always, speeding things up is of great interest.
    +
    +Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/COPYING openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/COPYING
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/COPYING	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/COPYING	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,19 @@
    +The GIFLIB distribution is Copyright (c) 1997  Eric S. Raymond
    +
    +Permission is hereby granted, free of charge, to any person obtaining a copy
    +of this software and associated documentation files (the "Software"), to deal
    +in the Software without restriction, including without limitation the rights
    +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +copies of the Software, and to permit persons to whom the Software is
    +furnished to do so, subject to the following conditions:
    +
    +The above copyright notice and this permission notice shall be included in
    +all copies or substantial portions of the Software.
    +
    +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    +THE SOFTWARE.
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/dgif_lib.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1265 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/******************************************************************************
    +
    +dgif_lib.c - GIF decoding
    +
    +The functions here and in egif_lib.c are partitioned carefully so that
    +if you only require one of read and write capability, only one of these
    +two modules will be linked.  Preserve this property!
    +
    +SPDX-License-Identifier: MIT
    +
    +*****************************************************************************/
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#ifdef _WIN32
    +#include 
    +#else
    +#include 
    +#endif /* _WIN32 */
    +
    +#include "gif_lib.h"
    +#include "gif_lib_private.h"
    +
    +/* compose unsigned little endian value */
    +#define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
    +
    +/* avoid extra function call in case we use fread (TVT) */
    +static int InternalRead(GifFileType *gif, GifByteType *buf, int len) {
    +    //fprintf(stderr, "### Read: %d\n", len);
    +    return
    +    (((GifFilePrivateType*)gif->Private)->Read ?
    +     ((GifFilePrivateType*)gif->Private)->Read(gif,buf,len) :
    +     fread(buf,1,len,((GifFilePrivateType*)gif->Private)->File));
    +}
    +
    +static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
    +static int DGifSetupDecompress(GifFileType *GifFile);
    +static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
    +                              int LineLen);
    +static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
    +static int DGifDecompressInput(GifFileType *GifFile, int *Code);
    +static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
    +                             GifByteType *NextByte);
    +
    +/******************************************************************************
    + Open a new GIF file for read, given by its name.
    + Returns dynamically allocated GifFileType pointer which serves as the GIF
    + info record.
    +******************************************************************************/
    +GifFileType *
    +DGifOpenFileName(const char *FileName, int *Error)
    +{
    +    int FileHandle;
    +    GifFileType *GifFile;
    +
    +    if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_OPEN_FAILED;
    +        return NULL;
    +    }
    +
    +    GifFile = DGifOpenFileHandle(FileHandle, Error);
    +    return GifFile;
    +}
    +
    +/******************************************************************************
    + Update a new GIF file, given its file handle.
    + Returns dynamically allocated GifFileType pointer which serves as the GIF
    + info record.
    +******************************************************************************/
    +GifFileType *
    +DGifOpenFileHandle(int FileHandle, int *Error)
    +{
    +    char Buf[GIF_STAMP_LEN + 1];
    +    GifFileType *GifFile;
    +    GifFilePrivateType *Private;
    +    FILE *f;
    +
    +    GifFile = (GifFileType *)malloc(sizeof(GifFileType));
    +    if (GifFile == NULL) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +        (void)close(FileHandle);
    +        return NULL;
    +    }
    +
    +    /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
    +
    +    /* Belt and suspenders, in case the null pointer isn't zero */
    +    GifFile->SavedImages = NULL;
    +    GifFile->SColorMap = NULL;
    +
    +    Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
    +    if (Private == NULL) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +        (void)close(FileHandle);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
    +
    +#ifdef _WIN32
    +    _setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */
    +#endif /* _WIN32 */
    +
    +    f = fdopen(FileHandle, "rb");    /* Make it into a stream: */
    +
    +    /*@-mustfreeonly@*/
    +    GifFile->Private = (void *)Private;
    +    Private->FileHandle = FileHandle;
    +    Private->File = f;
    +    Private->FileState = FILE_STATE_READ;
    +    Private->Read = NULL;        /* don't use alternate input method (TVT) */
    +    GifFile->UserData = NULL;    /* TVT */
    +    /*@=mustfreeonly@*/
    +
    +    /* Let's see if this is a GIF file: */
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_READ_FAILED;
    +        (void)fclose(f);
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    /* Check for GIF prefix at start of file */
    +    Buf[GIF_STAMP_LEN] = 0;
    +    if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_GIF_FILE;
    +        (void)fclose(f);
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    +        (void)fclose(f);
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    GifFile->Error = 0;
    +
    +    /* What version of GIF? */
    +    Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
    +
    +    return GifFile;
    +}
    +
    +/******************************************************************************
    + GifFileType constructor with user supplied input function (TVT)
    +******************************************************************************/
    +GifFileType *
    +DGifOpen(void *userData, InputFunc readFunc, int *Error)
    +{
    +    char Buf[GIF_STAMP_LEN + 1];
    +    GifFileType *GifFile;
    +    GifFilePrivateType *Private;
    +
    +    GifFile = (GifFileType *)malloc(sizeof(GifFileType));
    +    if (GifFile == NULL) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +        return NULL;
    +    }
    +
    +    memset(GifFile, '\0', sizeof(GifFileType));
    +
    +    /* Belt and suspenders, in case the null pointer isn't zero */
    +    GifFile->SavedImages = NULL;
    +    GifFile->SColorMap = NULL;
    +
    +    Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
    +    if (!Private) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +    /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
    +
    +    GifFile->Private = (void *)Private;
    +    Private->FileHandle = 0;
    +    Private->File = NULL;
    +    Private->FileState = FILE_STATE_READ;
    +
    +    Private->Read = readFunc;    /* TVT */
    +    GifFile->UserData = userData;    /* TVT */
    +
    +    /* Lets see if this is a GIF file: */
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_READ_FAILED;
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    /* Check for GIF prefix at start of file */
    +    Buf[GIF_STAMP_LEN] = '\0';
    +    if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NOT_GIF_FILE;
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        return NULL;
    +    }
    +
    +    if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    +        free((char *)Private);
    +        free((char *)GifFile);
    +        if (Error != NULL)
    +            *Error = D_GIF_ERR_NO_SCRN_DSCR;
    +        return NULL;
    +    }
    +
    +    GifFile->Error = 0;
    +
    +    /* What version of GIF? */
    +    Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
    +
    +    return GifFile;
    +}
    +
    +/******************************************************************************
    + This routine should be called before any other DGif calls. Note that
    + this routine is called automatically from DGif file open routines.
    +******************************************************************************/
    +int
    +DGifGetScreenDesc(GifFileType *GifFile)
    +{
    +    int BitsPerPixel;
    +    bool SortFlag;
    +    GifByteType Buf[3];
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    /* Put the screen descriptor into the file: */
    +    if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
    +        DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
    +        return GIF_ERROR;
    +
    +    if (InternalRead(GifFile, Buf, 3) != 3) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        GifFreeMapObject(GifFile->SColorMap);
    +        GifFile->SColorMap = NULL;
    +        return GIF_ERROR;
    +    }
    +    GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
    +    SortFlag = (Buf[0] & 0x08) != 0;
    +    BitsPerPixel = (Buf[0] & 0x07) + 1;
    +    GifFile->SBackGroundColor = Buf[1];
    +    GifFile->AspectByte = Buf[2];
    +    if (Buf[0] & 0x80) {    /* Do we have global color map? */
    +        int i;
    +
    +        GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
    +        if (GifFile->SColorMap == NULL) {
    +            GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +            return GIF_ERROR;
    +        }
    +
    +        /* Get the global color map: */
    +        GifFile->SColorMap->SortFlag = SortFlag;
    +        for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
    +            /* coverity[check_return] */
    +            if (InternalRead(GifFile, Buf, 3) != 3) {
    +                GifFreeMapObject(GifFile->SColorMap);
    +                GifFile->SColorMap = NULL;
    +                GifFile->Error = D_GIF_ERR_READ_FAILED;
    +                return GIF_ERROR;
    +            }
    +            GifFile->SColorMap->Colors[i].Red = Buf[0];
    +            GifFile->SColorMap->Colors[i].Green = Buf[1];
    +            GifFile->SColorMap->Colors[i].Blue = Buf[2];
    +        }
    +    } else {
    +        GifFile->SColorMap = NULL;
    +    }
    +
    +    /*
    +     * No check here for whether the background color is in range for the
    +     * screen color map.  Possibly there should be.
    +     */
    +
    +    return GIF_OK;
    +}
    +
    +const char *
    +DGifGetGifVersion(GifFileType *GifFile)
    +{
    +    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    +
    +    if (Private->gif89)
    +        return GIF89_STAMP;
    +    else
    +        return GIF87_STAMP;
    +}
    +
    +/******************************************************************************
    + This routine should be called before any attempt to read an image.
    +******************************************************************************/
    +int
    +DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
    +{
    +    GifByteType Buf;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, &Buf, 1) != 1) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        return GIF_ERROR;
    +    }
    +
    +    //fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
    +    switch (Buf) {
    +      case DESCRIPTOR_INTRODUCER:
    +          *Type = IMAGE_DESC_RECORD_TYPE;
    +          break;
    +      case EXTENSION_INTRODUCER:
    +          *Type = EXTENSION_RECORD_TYPE;
    +          break;
    +      case TERMINATOR_INTRODUCER:
    +          *Type = TERMINATE_RECORD_TYPE;
    +          break;
    +      default:
    +          *Type = UNDEFINED_RECORD_TYPE;
    +          GifFile->Error = D_GIF_ERR_WRONG_RECORD;
    +          return GIF_ERROR;
    +    }
    +
    +    return GIF_OK;
    +}
    +
    +int
    +DGifGetImageHeader(GifFileType *GifFile)
    +{
    +    unsigned int BitsPerPixel;
    +    GifByteType Buf[3];
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
    +        DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
    +        DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
    +        DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
    +        return GIF_ERROR;
    +    if (InternalRead(GifFile, Buf, 1) != 1) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        GifFreeMapObject(GifFile->Image.ColorMap);
    +        GifFile->Image.ColorMap = NULL;
    +        return GIF_ERROR;
    +    }
    +    BitsPerPixel = (Buf[0] & 0x07) + 1;
    +    GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
    +
    +    /* Setup the colormap */
    +    if (GifFile->Image.ColorMap) {
    +        GifFreeMapObject(GifFile->Image.ColorMap);
    +        GifFile->Image.ColorMap = NULL;
    +    }
    +    /* Does this image have local color map? */
    +    if (Buf[0] & 0x80) {
    +        unsigned int i;
    +
    +        GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
    +        if (GifFile->Image.ColorMap == NULL) {
    +            GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +            return GIF_ERROR;
    +        }
    +
    +        /* Get the image local color map: */
    +        for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
    +            /* coverity[check_return] */
    +            if (InternalRead(GifFile, Buf, 3) != 3) {
    +                GifFreeMapObject(GifFile->Image.ColorMap);
    +                GifFile->Error = D_GIF_ERR_READ_FAILED;
    +                GifFile->Image.ColorMap = NULL;
    +                return GIF_ERROR;
    +            }
    +            GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
    +            GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
    +            GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
    +        }
    +    }
    +
    +    Private->PixelCount = (long)GifFile->Image.Width *
    +       (long)GifFile->Image.Height;
    +
    +    /* Reset decompress algorithm parameters. */
    +    return DGifSetupDecompress(GifFile);
    +}
    +
    +/******************************************************************************
    + This routine should be called before any attempt to read an image.
    + Note it is assumed the Image desc. header has been read.
    +******************************************************************************/
    +int
    +DGifGetImageDesc(GifFileType *GifFile)
    +{
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +    SavedImage *sp;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    if (DGifGetImageHeader(GifFile) == GIF_ERROR) {
    +        return GIF_ERROR;
    +    }
    +
    +    if (GifFile->SavedImages) {
    +        SavedImage* new_saved_images =
    +            (SavedImage *)reallocarray(GifFile->SavedImages,
    +                            (GifFile->ImageCount + 1), sizeof(SavedImage));
    +        if (new_saved_images == NULL) {
    +            GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +            return GIF_ERROR;
    +        }
    +        GifFile->SavedImages = new_saved_images;
    +    } else {
    +        if ((GifFile->SavedImages =
    +             (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
    +            GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +            return GIF_ERROR;
    +        }
    +    }
    +
    +    sp = &GifFile->SavedImages[GifFile->ImageCount];
    +    memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
    +    if (GifFile->Image.ColorMap != NULL) {
    +        sp->ImageDesc.ColorMap = GifMakeMapObject(
    +                                 GifFile->Image.ColorMap->ColorCount,
    +                                 GifFile->Image.ColorMap->Colors);
    +        if (sp->ImageDesc.ColorMap == NULL) {
    +            GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    +            return GIF_ERROR;
    +        }
    +    }
    +    sp->RasterBits = (unsigned char *)NULL;
    +    sp->ExtensionBlockCount = 0;
    +    sp->ExtensionBlocks = (ExtensionBlock *) NULL;
    +
    +    GifFile->ImageCount++;
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Get one full scanned line (Line) of length LineLen from GIF file.
    +******************************************************************************/
    +int
    +DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
    +{
    +    GifByteType *Dummy;
    +    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    if (!LineLen)
    +        LineLen = GifFile->Image.Width;
    +
    +    if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
    +        GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
    +        return GIF_ERROR;
    +    }
    +
    +    if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
    +        if (Private->PixelCount == 0) {
    +            /* We probably won't be called any more, so let's clean up
    +             * everything before we return: need to flush out all the
    +             * rest of image until an empty block (size 0)
    +             * detected. We use GetCodeNext.
    +             */
    +            do
    +                if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    +                    return GIF_ERROR;
    +            while (Dummy != NULL) ;
    +        }
    +        return GIF_OK;
    +    } else
    +        return GIF_ERROR;
    +}
    +
    +/******************************************************************************
    + Put one pixel (Pixel) into GIF file.
    +******************************************************************************/
    +int
    +DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
    +{
    +    GifByteType *Dummy;
    +    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +    if (--Private->PixelCount > 0xffff0000UL)
    +    {
    +        GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
    +        return GIF_ERROR;
    +    }
    +
    +    if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
    +        if (Private->PixelCount == 0) {
    +            /* We probably won't be called any more, so let's clean up
    +             * everything before we return: need to flush out all the
    +             * rest of image until an empty block (size 0)
    +             * detected. We use GetCodeNext.
    +             */
    +            do
    +                if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    +                    return GIF_ERROR;
    +            while (Dummy != NULL) ;
    +        }
    +        return GIF_OK;
    +    } else
    +        return GIF_ERROR;
    +}
    +
    +/******************************************************************************
    + Get an extension block (see GIF manual) from GIF file. This routine only
    + returns the first data block, and DGifGetExtensionNext should be called
    + after this one until NULL extension is returned.
    + The Extension should NOT be freed by the user (not dynamically allocated).
    + Note it is assumed the Extension description header has been read.
    +******************************************************************************/
    +int
    +DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
    +{
    +    GifByteType Buf;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    //fprintf(stderr, "### -> DGifGetExtension:\n");
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, &Buf, 1) != 1) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        return GIF_ERROR;
    +    }
    +    *ExtCode = Buf;
    +    //fprintf(stderr, "### <- DGifGetExtension: %02x, about to call next\n", Buf);
    +
    +    return DGifGetExtensionNext(GifFile, Extension);
    +}
    +
    +/******************************************************************************
    + Get a following extension block (see GIF manual) from GIF file. This
    + routine should be called until NULL Extension is returned.
    + The Extension should NOT be freed by the user (not dynamically allocated).
    +******************************************************************************/
    +int
    +DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
    +{
    +    GifByteType Buf;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    //fprintf(stderr, "### -> DGifGetExtensionNext\n");
    +    if (InternalRead(GifFile, &Buf, 1) != 1) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        return GIF_ERROR;
    +    }
    +    //fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
    +
    +    if (Buf > 0) {
    +        *Extension = Private->Buf;    /* Use private unused buffer. */
    +        (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    +        /* coverity[tainted_data,check_return] */
    +        if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) {
    +            GifFile->Error = D_GIF_ERR_READ_FAILED;
    +            return GIF_ERROR;
    +        }
    +    } else
    +        *Extension = NULL;
    +    //fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Extract a Graphics Control Block from raw extension data
    +******************************************************************************/
    +
    +int DGifExtensionToGCB(const size_t GifExtensionLength,
    +                       const GifByteType *GifExtension,
    +                       GraphicsControlBlock *GCB)
    +{
    +    if (GifExtensionLength != 4) {
    +        return GIF_ERROR;
    +    }
    +
    +    GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
    +    GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
    +    GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
    +    if (GifExtension[0] & 0x01)
    +        GCB->TransparentColor = (int)GifExtension[3];
    +    else
    +        GCB->TransparentColor = NO_TRANSPARENT_COLOR;
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Extract the Graphics Control Block for a saved image, if it exists.
    +******************************************************************************/
    +
    +int DGifSavedExtensionToGCB(GifFileType *GifFile,
    +                int ImageIndex, GraphicsControlBlock *GCB)
    +{
    +    int i;
    +
    +    if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
    +        return GIF_ERROR;
    +
    +    GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
    +    GCB->UserInputFlag = false;
    +    GCB->DelayTime = 0;
    +    GCB->TransparentColor = NO_TRANSPARENT_COLOR;
    +
    +    for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
    +        ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
    +        if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
    +            return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
    +    }
    +
    +    return GIF_ERROR;
    +}
    +
    +/******************************************************************************
    + This routine should be called last, to close the GIF file.
    +******************************************************************************/
    +int
    +DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
    +{
    +    GifFilePrivateType *Private;
    +
    +    if (GifFile == NULL || GifFile->Private == NULL)
    +        return GIF_ERROR;
    +
    +    if (GifFile->Image.ColorMap) {
    +        GifFreeMapObject(GifFile->Image.ColorMap);
    +        GifFile->Image.ColorMap = NULL;
    +    }
    +
    +    if (GifFile->SColorMap) {
    +        GifFreeMapObject(GifFile->SColorMap);
    +        GifFile->SColorMap = NULL;
    +    }
    +
    +    if (GifFile->SavedImages) {
    +        GifFreeSavedImages(GifFile);
    +        GifFile->SavedImages = NULL;
    +    }
    +
    +    GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
    +
    +    Private = (GifFilePrivateType *) GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        if (ErrorCode != NULL)
    +            *ErrorCode = D_GIF_ERR_NOT_READABLE;
    +        free((char *)GifFile->Private);
    +        free(GifFile);
    +        return GIF_ERROR;
    +    }
    +
    +    if (Private->File && (fclose(Private->File) != 0)) {
    +        if (ErrorCode != NULL)
    +            *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
    +        free((char *)GifFile->Private);
    +        free(GifFile);
    +        return GIF_ERROR;
    +    }
    +
    +    free((char *)GifFile->Private);
    +    free(GifFile);
    +    if (ErrorCode != NULL)
    +        *ErrorCode = D_GIF_SUCCEEDED;
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Get 2 bytes (word) from the given file:
    +******************************************************************************/
    +static int
    +DGifGetWord(GifFileType *GifFile, GifWord *Word)
    +{
    +    unsigned char c[2];
    +
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, c, 2) != 2) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        return GIF_ERROR;
    +    }
    +
    +    *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Get the image code in compressed form.  This routine can be called if the
    + information needed to be piped out as is. Obviously this is much faster
    + than decoding and encoding again. This routine should be followed by calls
    + to DGifGetCodeNext, until NULL block is returned.
    + The block should NOT be freed by the user (not dynamically allocated).
    +******************************************************************************/
    +int
    +DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
    +{
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    *CodeSize = Private->BitsPerPixel;
    +
    +    return DGifGetCodeNext(GifFile, CodeBlock);
    +}
    +
    +/******************************************************************************
    + Continue to get the image code in compressed form. This routine should be
    + called until NULL block is returned.
    + The block should NOT be freed by the user (not dynamically allocated).
    +******************************************************************************/
    +int
    +DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
    +{
    +    GifByteType Buf;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    /* coverity[tainted_data_argument] */
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, &Buf, 1) != 1) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;
    +        return GIF_ERROR;
    +    }
    +
    +    /* coverity[lower_bounds] */
    +    if (Buf > 0) {
    +        *CodeBlock = Private->Buf;    /* Use private unused buffer. */
    +        (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    +        /* coverity[tainted_data] */
    +        if (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
    +            GifFile->Error = D_GIF_ERR_READ_FAILED;
    +            return GIF_ERROR;
    +        }
    +    } else {
    +        *CodeBlock = NULL;
    +        Private->Buf[0] = 0;    /* Make sure the buffer is empty! */
    +        Private->PixelCount = 0;    /* And local info. indicate image read. */
    +    }
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Setup the LZ decompression for this image:
    +******************************************************************************/
    +static int
    +DGifSetupDecompress(GifFileType *GifFile)
    +{
    +    int i, BitsPerPixel;
    +    GifByteType CodeSize;
    +    GifPrefixType *Prefix;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    /* coverity[check_return] */
    +    if (InternalRead(GifFile, &CodeSize, 1) < 1) {    /* Read Code size from file. */
    +        return GIF_ERROR;    /* Failed to read Code size. */
    +    }
    +    BitsPerPixel = CodeSize;
    +
    +    /* this can only happen on a severely malformed GIF */
    +    if (BitsPerPixel > 8) {
    +        GifFile->Error = D_GIF_ERR_READ_FAILED;    /* somewhat bogus error code */
    +        return GIF_ERROR;    /* Failed to read Code size. */
    +    }
    +
    +    Private->Buf[0] = 0;    /* Input Buffer empty. */
    +    Private->BitsPerPixel = BitsPerPixel;
    +    Private->ClearCode = (1 << BitsPerPixel);
    +    Private->EOFCode = Private->ClearCode + 1;
    +    Private->RunningCode = Private->EOFCode + 1;
    +    Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */
    +    Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */
    +    Private->StackPtr = 0;    /* No pixels on the pixel stack. */
    +    Private->LastCode = NO_SUCH_CODE;
    +    Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */
    +    Private->CrntShiftDWord = 0;
    +
    +    Prefix = Private->Prefix;
    +    for (i = 0; i <= LZ_MAX_CODE; i++)
    +        Prefix[i] = NO_SUCH_CODE;
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + The LZ decompression routine:
    + This version decompress the given GIF file into Line of length LineLen.
    + This routine can be called few times (one per scan line, for example), in
    + order the complete the whole image.
    +******************************************************************************/
    +static int
    +DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
    +{
    +    int i = 0;
    +    int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
    +    GifByteType *Stack, *Suffix;
    +    GifPrefixType *Prefix;
    +    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    +
    +    StackPtr = Private->StackPtr;
    +    Prefix = Private->Prefix;
    +    Suffix = Private->Suffix;
    +    Stack = Private->Stack;
    +    EOFCode = Private->EOFCode;
    +    ClearCode = Private->ClearCode;
    +    LastCode = Private->LastCode;
    +
    +    if (StackPtr > LZ_MAX_CODE) {
    +        return GIF_ERROR;
    +    }
    +
    +    if (StackPtr != 0) {
    +        /* Let pop the stack off before continueing to read the GIF file: */
    +        while (StackPtr != 0 && i < LineLen)
    +            Line[i++] = Stack[--StackPtr];
    +    }
    +
    +    while (i < LineLen) {    /* Decode LineLen items. */
    +        if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
    +            return GIF_ERROR;
    +
    +        if (CrntCode == EOFCode) {
    +            /* Note however that usually we will not be here as we will stop
    +             * decoding as soon as we got all the pixel, or EOF code will
    +             * not be read at all, and DGifGetLine/Pixel clean everything.  */
    +            GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
    +            return GIF_ERROR;
    +        } else if (CrntCode == ClearCode) {
    +            /* We need to start over again: */
    +            for (j = 0; j <= LZ_MAX_CODE; j++)
    +                Prefix[j] = NO_SUCH_CODE;
    +            Private->RunningCode = Private->EOFCode + 1;
    +            Private->RunningBits = Private->BitsPerPixel + 1;
    +            Private->MaxCode1 = 1 << Private->RunningBits;
    +            LastCode = Private->LastCode = NO_SUCH_CODE;
    +        } else {
    +            /* Its regular code - if in pixel range simply add it to output
    +             * stream, otherwise trace to codes linked list until the prefix
    +             * is in pixel range: */
    +            if (CrntCode < ClearCode) {
    +                /* This is simple - its pixel scalar, so add it to output: */
    +                Line[i++] = CrntCode;
    +            } else {
    +                /* Its a code to needed to be traced: trace the linked list
    +                 * until the prefix is a pixel, while pushing the suffix
    +                 * pixels on our stack. If we done, pop the stack in reverse
    +                 * (thats what stack is good for!) order to output.  */
    +                if (Prefix[CrntCode] == NO_SUCH_CODE) {
    +                    CrntPrefix = LastCode;
    +
    +                    /* Only allowed if CrntCode is exactly the running code:
    +                     * In that case CrntCode = XXXCode, CrntCode or the
    +                     * prefix code is last code and the suffix char is
    +                     * exactly the prefix of last code! */
    +                    if (CrntCode == Private->RunningCode - 2) {
    +                        Suffix[Private->RunningCode - 2] =
    +                           Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
    +                                                                 LastCode,
    +                                                                 ClearCode);
    +                    } else {
    +                        Suffix[Private->RunningCode - 2] =
    +                           Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
    +                                                                 CrntCode,
    +                                                                 ClearCode);
    +                    }
    +                } else
    +                    CrntPrefix = CrntCode;
    +
    +                /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
    +                 * during the trace. As we might loop forever, in case of
    +                 * defective image, we use StackPtr as loop counter and stop
    +                 * before overflowing Stack[]. */
    +                while (StackPtr < LZ_MAX_CODE &&
    +                       CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
    +                    Stack[StackPtr++] = Suffix[CrntPrefix];
    +                    CrntPrefix = Prefix[CrntPrefix];
    +                }
    +                if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
    +                    GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
    +                    return GIF_ERROR;
    +                }
    +                /* Push the last character on stack: */
    +                Stack[StackPtr++] = CrntPrefix;
    +
    +                /* Now lets pop all the stack into output: */
    +                while (StackPtr != 0 && i < LineLen)
    +                    Line[i++] = Stack[--StackPtr];
    +            }
    +            if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < (LZ_MAX_CODE+1) && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
    +                Prefix[Private->RunningCode - 2] = LastCode;
    +
    +                if (CrntCode == Private->RunningCode - 2) {
    +                    /* Only allowed if CrntCode is exactly the running code:
    +                     * In that case CrntCode = XXXCode, CrntCode or the
    +                     * prefix code is last code and the suffix char is
    +                     * exactly the prefix of last code! */
    +                    Suffix[Private->RunningCode - 2] =
    +                       DGifGetPrefixChar(Prefix, LastCode, ClearCode);
    +                } else {
    +                    Suffix[Private->RunningCode - 2] =
    +                       DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
    +                }
    +            }
    +            LastCode = CrntCode;
    +        }
    +    }
    +
    +    Private->LastCode = LastCode;
    +    Private->StackPtr = StackPtr;
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + Routine to trace the Prefixes linked list until we get a prefix which is
    + not code, but a pixel value (less than ClearCode). Returns that pixel value.
    + If image is defective, we might loop here forever, so we limit the loops to
    + the maximum possible if image O.k. - LZ_MAX_CODE times.
    +******************************************************************************/
    +static int
    +DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
    +{
    +    int i = 0;
    +
    +    while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
    +        if (Code > LZ_MAX_CODE) {
    +            return NO_SUCH_CODE;
    +        }
    +        Code = Prefix[Code];
    +    }
    +    return Code;
    +}
    +
    +/******************************************************************************
    + Interface for accessing the LZ codes directly. Set Code to the real code
    + (12bits), or to -1 if EOF code is returned.
    +******************************************************************************/
    +int
    +DGifGetLZCodes(GifFileType *GifFile, int *Code)
    +{
    +    GifByteType *CodeBlock;
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    if (!IS_READABLE(Private)) {
    +        /* This file was NOT open for reading: */
    +        GifFile->Error = D_GIF_ERR_NOT_READABLE;
    +        return GIF_ERROR;
    +    }
    +
    +    if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
    +        return GIF_ERROR;
    +
    +    if (*Code == Private->EOFCode) {
    +        /* Skip rest of codes (hopefully only NULL terminating block): */
    +        do {
    +            if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
    +                return GIF_ERROR;
    +        } while (CodeBlock != NULL) ;
    +
    +        *Code = -1;
    +    } else if (*Code == Private->ClearCode) {
    +        /* We need to start over again: */
    +        Private->RunningCode = Private->EOFCode + 1;
    +        Private->RunningBits = Private->BitsPerPixel + 1;
    +        Private->MaxCode1 = 1 << Private->RunningBits;
    +    }
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + The LZ decompression input routine:
    + This routine is responsable for the decompression of the bit stream from
    + 8 bits (bytes) packets, into the real codes.
    + Returns GIF_OK if read successfully.
    +******************************************************************************/
    +static int
    +DGifDecompressInput(GifFileType *GifFile, int *Code)
    +{
    +    static const unsigned short CodeMasks[] = {
    +        0x0000, 0x0001, 0x0003, 0x0007,
    +        0x000f, 0x001f, 0x003f, 0x007f,
    +        0x00ff, 0x01ff, 0x03ff, 0x07ff,
    +        0x0fff
    +    };
    +
    +    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    +
    +    GifByteType NextByte;
    +
    +    /* The image can't contain more than LZ_BITS per code. */
    +    if (Private->RunningBits > LZ_BITS) {
    +        GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
    +        return GIF_ERROR;
    +    }
    +
    +    while (Private->CrntShiftState < Private->RunningBits) {
    +        /* Needs to get more bytes from input stream for next code: */
    +        if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
    +            return GIF_ERROR;
    +        }
    +        Private->CrntShiftDWord |=
    +            ((unsigned long)NextByte) << Private->CrntShiftState;
    +        Private->CrntShiftState += 8;
    +    }
    +    *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
    +
    +    Private->CrntShiftDWord >>= Private->RunningBits;
    +    Private->CrntShiftState -= Private->RunningBits;
    +
    +    /* If code cannot fit into RunningBits bits, must raise its size. Note
    +     * however that codes above 4095 are used for special signaling.
    +     * If we're using LZ_BITS bits already and we're at the max code, just
    +     * keep using the table as it is, don't increment Private->RunningCode.
    +     */
    +    if (Private->RunningCode < LZ_MAX_CODE + 2 &&
    +        ++Private->RunningCode > Private->MaxCode1 &&
    +        Private->RunningBits < LZ_BITS) {
    +        Private->MaxCode1 <<= 1;
    +        Private->RunningBits++;
    +    }
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + This routines read one GIF data block at a time and buffers it internally
    + so that the decompression routine could access it.
    + The routine returns the next byte from its internal buffer (or read next
    + block in if buffer empty) and returns GIF_OK if succesful.
    +******************************************************************************/
    +static int
    +DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
    +{
    +    if (Buf[0] == 0) {
    +        /* Needs to read the next buffer - this one is empty: */
    +        /* coverity[check_return] */
    +        if (InternalRead(GifFile, Buf, 1) != 1) {
    +            GifFile->Error = D_GIF_ERR_READ_FAILED;
    +            return GIF_ERROR;
    +        }
    +        /* There shouldn't be any empty data blocks here as the LZW spec
    +         * says the LZW termination code should come first.  Therefore we
    +         * shouldn't be inside this routine at that point.
    +         */
    +        if (Buf[0] == 0) {
    +            GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
    +            return GIF_ERROR;
    +        }
    +        if (InternalRead(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
    +            GifFile->Error = D_GIF_ERR_READ_FAILED;
    +            return GIF_ERROR;
    +        }
    +        *NextByte = Buf[1];
    +        Buf[1] = 2;    /* We use now the second place as last char read! */
    +        Buf[0]--;
    +    } else {
    +        *NextByte = Buf[Buf[1]++];
    +        Buf[0]--;
    +    }
    +
    +    return GIF_OK;
    +}
    +
    +/******************************************************************************
    + This routine reads an entire GIF into core, hanging all its state info off
    + the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
    + first to initialize I/O.  Its inverse is EGifSpew().
    +*******************************************************************************/
    +int
    +DGifSlurp(GifFileType *GifFile)
    +{
    +    size_t ImageSize;
    +    GifRecordType RecordType;
    +    SavedImage *sp;
    +    GifByteType *ExtData;
    +    int ExtFunction;
    +
    +    GifFile->ExtensionBlocks = NULL;
    +    GifFile->ExtensionBlockCount = 0;
    +
    +    do {
    +        if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
    +            return (GIF_ERROR);
    +
    +        switch (RecordType) {
    +          case IMAGE_DESC_RECORD_TYPE:
    +              if (DGifGetImageDesc(GifFile) == GIF_ERROR)
    +                  return (GIF_ERROR);
    +
    +              sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
    +              /* Allocate memory for the image */
    +              if (sp->ImageDesc.Width <= 0 || sp->ImageDesc.Height <= 0 ||
    +                      sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
    +                  return GIF_ERROR;
    +              }
    +              ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
    +
    +              if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
    +                  return GIF_ERROR;
    +              }
    +              sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
    +                      sizeof(GifPixelType));
    +
    +              if (sp->RasterBits == NULL) {
    +                  return GIF_ERROR;
    +              }
    +
    +              if (sp->ImageDesc.Interlace) {
    +                  int i, j;
    +                   /*
    +                    * The way an interlaced image should be read -
    +                    * offsets and jumps...
    +                    */
    +                  int InterlacedOffset[] = { 0, 4, 2, 1 };
    +                  int InterlacedJumps[] = { 8, 8, 4, 2 };
    +                  /* Need to perform 4 passes on the image */
    +                  for (i = 0; i < 4; i++)
    +                      for (j = InterlacedOffset[i];
    +                       j < sp->ImageDesc.Height;
    +                       j += InterlacedJumps[i]) {
    +                      if (DGifGetLine(GifFile,
    +                              sp->RasterBits+j*sp->ImageDesc.Width,
    +                              sp->ImageDesc.Width) == GIF_ERROR)
    +                          return GIF_ERROR;
    +                      }
    +              }
    +              else {
    +                  if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
    +                      return (GIF_ERROR);
    +              }
    +
    +              if (GifFile->ExtensionBlocks) {
    +                  sp->ExtensionBlocks = GifFile->ExtensionBlocks;
    +                  sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
    +
    +                  GifFile->ExtensionBlocks = NULL;
    +                  GifFile->ExtensionBlockCount = 0;
    +              }
    +              break;
    +
    +          case EXTENSION_RECORD_TYPE:
    +              if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
    +                  return (GIF_ERROR);
    +              /* Create an extension block with our data */
    +              if (ExtData != NULL) {
    +                  if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
    +                               &GifFile->ExtensionBlocks,
    +                               ExtFunction, ExtData[0], &ExtData[1])
    +                      == GIF_ERROR)
    +                      return (GIF_ERROR);
    +              }
    +              for (;;) {
    +                  if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
    +                      return (GIF_ERROR);
    +                  if (ExtData == NULL)
    +                      break;
    +                  /* Continue the extension block */
    +                  if (ExtData != NULL)
    +                      if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
    +                                   &GifFile->ExtensionBlocks,
    +                                   CONTINUE_EXT_FUNC_CODE,
    +                                   ExtData[0], &ExtData[1]) == GIF_ERROR)
    +                              return (GIF_ERROR);
    +              }
    +              break;
    +
    +          case TERMINATE_RECORD_TYPE:
    +              break;
    +
    +          default:    /* Should be trapped by DGifGetRecordType */
    +              break;
    +        }
    +    } while (RecordType != TERMINATE_RECORD_TYPE);
    +
    +    /* Sanity check for corrupted file */
    +    if (GifFile->ImageCount == 0) {
    +        GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
    +        return(GIF_ERROR);
    +    }
    +
    +    return (GIF_OK);
    +}
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,444 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/*****************************************************************************
    +
    + GIF construction tools
    +
    +SPDX-License-Identifier: MIT
    +
    +****************************************************************************/
    +
    +#include 
    +#include 
    +#include 
    +
    +#include "gif_lib.h"
    +#include "gif_lib_private.h"
    +
    +#define MAX(x, y)    (((x) > (y)) ? (x) : (y))
    +
    +/******************************************************************************
    + Miscellaneous utility functions
    +******************************************************************************/
    +
    +/* return smallest bitfield size n will fit in */
    +int
    +GifBitSize(int n)
    +{
    +    register int i;
    +
    +    for (i = 1; i <= 8; i++)
    +        if ((1 << i) >= n)
    +            break;
    +    return (i);
    +}
    +
    +/******************************************************************************
    +  Color map object functions
    +******************************************************************************/
    +
    +/*
    + * Allocate a color map of given size; initialize with contents of
    + * ColorMap if that pointer is non-NULL.
    + */
    +ColorMapObject *
    +GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
    +{
    +    ColorMapObject *Object;
    +
    +    /*** FIXME: Our ColorCount has to be a power of two.  Is it necessary to
    +     * make the user know that or should we automatically round up instead? */
    +    if (ColorCount != (1 << GifBitSize(ColorCount))) {
    +        return ((ColorMapObject *) NULL);
    +    }
    +
    +    Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
    +    if (Object == (ColorMapObject *) NULL) {
    +        return ((ColorMapObject *) NULL);
    +    }
    +
    +    Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
    +    if (Object->Colors == (GifColorType *) NULL) {
    +        free(Object);
    +        return ((ColorMapObject *) NULL);
    +    }
    +
    +    Object->ColorCount = ColorCount;
    +    Object->BitsPerPixel = GifBitSize(ColorCount);
    +    Object->SortFlag = false;
    +
    +    if (ColorMap != NULL) {
    +        memcpy((char *)Object->Colors,
    +               (char *)ColorMap, ColorCount * sizeof(GifColorType));
    +    }
    +
    +    return (Object);
    +}
    +
    +/*******************************************************************************
    +Free a color map object
    +*******************************************************************************/
    +void
    +GifFreeMapObject(ColorMapObject *Object)
    +{
    +    if (Object != NULL) {
    +        (void)free(Object->Colors);
    +        (void)free(Object);
    +    }
    +}
    +
    +#ifdef DEBUG
    +void
    +DumpColorMap(ColorMapObject *Object,
    +             FILE * fp)
    +{
    +    if (Object != NULL) {
    +        int i, j, Len = Object->ColorCount;
    +
    +        for (i = 0; i < Len; i += 4) {
    +            for (j = 0; j < 4 && j < Len; j++) {
    +                (void)fprintf(fp, "%3d: %02x %02x %02x   ", i + j,
    +                              Object->Colors[i + j].Red,
    +                              Object->Colors[i + j].Green,
    +                              Object->Colors[i + j].Blue);
    +            }
    +            (void)fprintf(fp, "\n");
    +        }
    +    }
    +}
    +#endif /* DEBUG */
    +
    +/*******************************************************************************
    + Compute the union of two given color maps and return it.  If result can't
    + fit into 256 colors, NULL is returned, the allocated union otherwise.
    + ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
    + copied iff they didn't exist before.  ColorTransIn2 maps the old
    + ColorIn2 into the ColorUnion color map table./
    +*******************************************************************************/
    +ColorMapObject *
    +GifUnionColorMap(const ColorMapObject *ColorIn1,
    +              const ColorMapObject *ColorIn2,
    +              GifPixelType ColorTransIn2[])
    +{
    +    int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
    +    ColorMapObject *ColorUnion;
    +
    +    /*
    +     * We don't worry about duplicates within either color map; if
    +     * the caller wants to resolve those, he can perform unions
    +     * with an empty color map.
    +     */
    +
    +    /* Allocate table which will hold the result for sure. */
    +    ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
    +                               ColorIn2->ColorCount) * 2, NULL);
    +
    +    if (ColorUnion == NULL)
    +        return (NULL);
    +
    +    /*
    +     * Copy ColorIn1 to ColorUnion.
    +     */
    +    for (i = 0; i < ColorIn1->ColorCount; i++)
    +        ColorUnion->Colors[i] = ColorIn1->Colors[i];
    +    CrntSlot = ColorIn1->ColorCount;
    +
    +    /*
    +     * Potentially obnoxious hack:
    +     *
    +     * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
    +     * of table 1.  This is very useful if your display is limited to
    +     * 16 colors.
    +     */
    +    while (ColorIn1->Colors[CrntSlot - 1].Red == 0
    +           && ColorIn1->Colors[CrntSlot - 1].Green == 0
    +           && ColorIn1->Colors[CrntSlot - 1].Blue == 0)
    +        CrntSlot--;
    +
    +    /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
    +    for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
    +        /* Let's see if this color already exists: */
    +        for (j = 0; j < ColorIn1->ColorCount; j++)
    +            if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i],
    +                        sizeof(GifColorType)) == 0)
    +                break;
    +
    +        if (j < ColorIn1->ColorCount)
    +            ColorTransIn2[i] = j;    /* color exists in Color1 */
    +        else {
    +            /* Color is new - copy it to a new slot: */
    +            ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
    +            ColorTransIn2[i] = CrntSlot++;
    +        }
    +    }
    +
    +    if (CrntSlot > 256) {
    +        GifFreeMapObject(ColorUnion);
    +        return ((ColorMapObject *) NULL);
    +    }
    +
    +    NewGifBitSize = GifBitSize(CrntSlot);
    +    RoundUpTo = (1 << NewGifBitSize);
    +
    +    if (RoundUpTo != ColorUnion->ColorCount) {
    +        register GifColorType *Map = ColorUnion->Colors;
    +
    +        /*
    +         * Zero out slots up to next power of 2.
    +         * We know these slots exist because of the way ColorUnion's
    +         * start dimension was computed.
    +         */
    +        for (j = CrntSlot; j < RoundUpTo; j++)
    +            Map[j].Red = Map[j].Green = Map[j].Blue = 0;
    +
    +        /* perhaps we can shrink the map? */
    +        if (RoundUpTo < ColorUnion->ColorCount) {
    +            GifColorType *new_map = (GifColorType *)reallocarray(Map,
    +                                 RoundUpTo, sizeof(GifColorType));
    +            if( new_map == NULL ) {
    +                GifFreeMapObject(ColorUnion);
    +                return ((ColorMapObject *) NULL);
    +            }
    +            ColorUnion->Colors = new_map;
    +        }
    +    }
    +
    +    ColorUnion->ColorCount = RoundUpTo;
    +    ColorUnion->BitsPerPixel = NewGifBitSize;
    +
    +    return (ColorUnion);
    +}
    +
    +/*******************************************************************************
    + Apply a given color translation to the raster bits of an image
    +*******************************************************************************/
    +void
    +GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
    +{
    +    register int i;
    +    register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
    +
    +    for (i = 0; i < RasterSize; i++)
    +        Image->RasterBits[i] = Translation[Image->RasterBits[i]];
    +}
    +
    +/******************************************************************************
    + Extension record functions
    +******************************************************************************/
    +int
    +GifAddExtensionBlock(int *ExtensionBlockCount,
    +                     ExtensionBlock **ExtensionBlocks,
    +                     int Function,
    +                     unsigned int Len,
    +                     unsigned char ExtData[])
    +{
    +    ExtensionBlock *ep;
    +
    +    if (*ExtensionBlocks == NULL)
    +        *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
    +    else {
    +        ExtensionBlock* ep_new = (ExtensionBlock *)reallocarray
    +                                      (*ExtensionBlocks, (*ExtensionBlockCount + 1),
    +                                      sizeof(ExtensionBlock));
    +        if( ep_new == NULL )
    +            return (GIF_ERROR);
    +        *ExtensionBlocks = ep_new;
    +    }
    +
    +    if (*ExtensionBlocks == NULL)
    +        return (GIF_ERROR);
    +
    +    ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
    +
    +    ep->Function = Function;
    +    ep->ByteCount=Len;
    +    ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
    +    if (ep->Bytes == NULL)
    +        return (GIF_ERROR);
    +
    +    if (ExtData != NULL) {
    +        memcpy(ep->Bytes, ExtData, Len);
    +    }
    +
    +    return (GIF_OK);
    +}
    +
    +void
    +GifFreeExtensions(int *ExtensionBlockCount,
    +                  ExtensionBlock **ExtensionBlocks)
    +{
    +    ExtensionBlock *ep;
    +
    +    if (*ExtensionBlocks == NULL)
    +        return;
    +
    +    for (ep = *ExtensionBlocks;
    +         ep < (*ExtensionBlocks + *ExtensionBlockCount);
    +         ep++)
    +        (void)free((char *)ep->Bytes);
    +    (void)free((char *)*ExtensionBlocks);
    +    *ExtensionBlocks = NULL;
    +    *ExtensionBlockCount = 0;
    +}
    +
    +/******************************************************************************
    + Image block allocation functions
    +******************************************************************************/
    +
    +/* Private Function:
    + * Frees the last image in the GifFile->SavedImages array
    + */
    +void
    +FreeLastSavedImage(GifFileType *GifFile)
    +{
    +    SavedImage *sp;
    +
    +    if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
    +        return;
    +
    +    /* Remove one SavedImage from the GifFile */
    +    GifFile->ImageCount--;
    +    sp = &GifFile->SavedImages[GifFile->ImageCount];
    +
    +    /* Deallocate its Colormap */
    +    if (sp->ImageDesc.ColorMap != NULL) {
    +        GifFreeMapObject(sp->ImageDesc.ColorMap);
    +        sp->ImageDesc.ColorMap = NULL;
    +    }
    +
    +    /* Deallocate the image data */
    +    if (sp->RasterBits != NULL)
    +        free((char *)sp->RasterBits);
    +
    +    /* Deallocate any extensions */
    +    GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
    +
    +    /*** FIXME: We could realloc the GifFile->SavedImages structure but is
    +     * there a point to it? Saves some memory but we'd have to do it every
    +     * time.  If this is used in GifFreeSavedImages then it would be inefficient
    +     * (The whole array is going to be deallocated.)  If we just use it when
    +     * we want to free the last Image it's convenient to do it here.
    +     */
    +}
    +
    +/*
    + * Append an image block to the SavedImages array
    + */
    +SavedImage *
    +GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
    +{
    +    if (GifFile->SavedImages == NULL)
    +        GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
    +    else {
    +        SavedImage* newSavedImages = (SavedImage *)reallocarray(GifFile->SavedImages,
    +                               (GifFile->ImageCount + 1), sizeof(SavedImage));
    +        if( newSavedImages == NULL)
    +            return ((SavedImage *)NULL);
    +        GifFile->SavedImages = newSavedImages;
    +    }
    +    if (GifFile->SavedImages == NULL)
    +        return ((SavedImage *)NULL);
    +    else {
    +        SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
    +
    +        if (CopyFrom != NULL) {
    +            memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
    +
    +            /*
    +             * Make our own allocated copies of the heap fields in the
    +             * copied record.  This guards against potential aliasing
    +             * problems.
    +             */
    +
    +            /* first, the local color map */
    +            if (CopyFrom->ImageDesc.ColorMap != NULL) {
    +                sp->ImageDesc.ColorMap = GifMakeMapObject(
    +                                         CopyFrom->ImageDesc.ColorMap->ColorCount,
    +                                         CopyFrom->ImageDesc.ColorMap->Colors);
    +                if (sp->ImageDesc.ColorMap == NULL) {
    +                    FreeLastSavedImage(GifFile);
    +                    return (SavedImage *)(NULL);
    +                }
    +            }
    +
    +            /* next, the raster */
    +            sp->RasterBits = (unsigned char *)reallocarray(NULL,
    +                                                  (CopyFrom->ImageDesc.Height *
    +                                                  CopyFrom->ImageDesc.Width),
    +                                                  sizeof(GifPixelType));
    +            if (sp->RasterBits == NULL) {
    +                FreeLastSavedImage(GifFile);
    +                return (SavedImage *)(NULL);
    +            }
    +            memcpy(sp->RasterBits, CopyFrom->RasterBits,
    +                   sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
    +                   CopyFrom->ImageDesc.Width);
    +
    +            /* finally, the extension blocks */
    +            if (CopyFrom->ExtensionBlocks != NULL) {
    +                sp->ExtensionBlocks = (ExtensionBlock *)reallocarray(NULL,
    +                                      CopyFrom->ExtensionBlockCount,
    +                                      sizeof(ExtensionBlock));
    +                if (sp->ExtensionBlocks == NULL) {
    +                    FreeLastSavedImage(GifFile);
    +                    return (SavedImage *)(NULL);
    +                }
    +                memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
    +                       sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
    +            }
    +        }
    +        else {
    +            memset((char *)sp, '\0', sizeof(SavedImage));
    +        }
    +
    +        return (sp);
    +    }
    +}
    +
    +void
    +GifFreeSavedImages(GifFileType *GifFile)
    +{
    +    SavedImage *sp;
    +
    +    if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
    +        return;
    +    }
    +    for (sp = GifFile->SavedImages;
    +         sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
    +        if (sp->ImageDesc.ColorMap != NULL) {
    +            GifFreeMapObject(sp->ImageDesc.ColorMap);
    +            sp->ImageDesc.ColorMap = NULL;
    +        }
    +
    +        if (sp->RasterBits != NULL)
    +            free((char *)sp->RasterBits);
    +
    +        GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);
    +    }
    +    free((char *)GifFile->SavedImages);
    +    GifFile->SavedImages = NULL;
    +}
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_err.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,123 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/*****************************************************************************
    +
    +gif_err.c - handle error reporting for the GIF library.
    +
    +SPDX-License-Identifier: MIT
    +
    +****************************************************************************/
    +
    +#include 
    +
    +#include "gif_lib.h"
    +#include "gif_lib_private.h"
    +
    +/*****************************************************************************
    + Return a string description of  the last GIF error
    +*****************************************************************************/
    +const char *
    +GifErrorString(int ErrorCode)
    +{
    +    const char *Err;
    +
    +    switch (ErrorCode) {
    +      case E_GIF_ERR_OPEN_FAILED:
    +        Err = "Failed to open given file";
    +        break;
    +      case E_GIF_ERR_WRITE_FAILED:
    +        Err = "Failed to write to given file";
    +        break;
    +      case E_GIF_ERR_HAS_SCRN_DSCR:
    +        Err = "Screen descriptor has already been set";
    +        break;
    +      case E_GIF_ERR_HAS_IMAG_DSCR:
    +        Err = "Image descriptor is still active";
    +        break;
    +      case E_GIF_ERR_NO_COLOR_MAP:
    +        Err = "Neither global nor local color map";
    +        break;
    +      case E_GIF_ERR_DATA_TOO_BIG:
    +        Err = "Number of pixels bigger than width * height";
    +        break;
    +      case E_GIF_ERR_NOT_ENOUGH_MEM:
    +        Err = "Failed to allocate required memory";
    +        break;
    +      case E_GIF_ERR_DISK_IS_FULL:
    +        Err = "Write failed (disk full?)";
    +        break;
    +      case E_GIF_ERR_CLOSE_FAILED:
    +        Err = "Failed to close given file";
    +        break;
    +      case E_GIF_ERR_NOT_WRITEABLE:
    +        Err = "Given file was not opened for write";
    +        break;
    +      case D_GIF_ERR_OPEN_FAILED:
    +        Err = "Failed to open given file";
    +        break;
    +      case D_GIF_ERR_READ_FAILED:
    +        Err = "Failed to read from given file";
    +        break;
    +      case D_GIF_ERR_NOT_GIF_FILE:
    +        Err = "Data is not in GIF format";
    +        break;
    +      case D_GIF_ERR_NO_SCRN_DSCR:
    +        Err = "No screen descriptor detected";
    +        break;
    +      case D_GIF_ERR_NO_IMAG_DSCR:
    +        Err = "No Image Descriptor detected";
    +        break;
    +      case D_GIF_ERR_NO_COLOR_MAP:
    +        Err = "Neither global nor local color map";
    +        break;
    +      case D_GIF_ERR_WRONG_RECORD:
    +        Err = "Wrong record type detected";
    +        break;
    +      case D_GIF_ERR_DATA_TOO_BIG:
    +        Err = "Number of pixels bigger than width * height";
    +        break;
    +      case D_GIF_ERR_NOT_ENOUGH_MEM:
    +        Err = "Failed to allocate required memory";
    +        break;
    +      case D_GIF_ERR_CLOSE_FAILED:
    +        Err = "Failed to close given file";
    +        break;
    +      case D_GIF_ERR_NOT_READABLE:
    +        Err = "Given file was not opened for read";
    +        break;
    +      case D_GIF_ERR_IMAGE_DEFECT:
    +        Err = "Image is defective, decoding aborted";
    +        break;
    +      case D_GIF_ERR_EOF_TOO_SOON:
    +        Err = "Image EOF detected before image complete";
    +        break;
    +      default:
    +        Err = NULL;
    +        break;
    +    }
    +    return Err;
    +}
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_hash.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,69 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/******************************************************************************
    +
    +gif_hash.h - magfic constants and declarations for GIF LZW
    +
    +SPDX-License-Identifier: MIT
    +
    +******************************************************************************/
    +
    +#ifndef _GIF_HASH_H_
    +#define _GIF_HASH_H_
    +
    +/** Begin JDK modifications to support building on Windows **/
    +#ifndef _WIN32
    +#include 
    +#endif
    +/** End JDK modifications to support building on Windows **/
    +#include 
    +
    +#define HT_SIZE         8192    /* 12bits = 4096 or twice as big! */
    +#define HT_KEY_MASK     0x1FFF  /* 13bits keys */
    +#define HT_KEY_NUM_BITS 13      /* 13bits keys */
    +#define HT_MAX_KEY      8191    /* 13bits - 1, maximal code possible */
    +#define HT_MAX_CODE     4095    /* Biggest code possible in 12 bits. */
    +
    +/* The 32 bits of the long are divided into two parts for the key & code:   */
    +/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
    +/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits.           */
    +/* The key is the upper 20 bits.  The code is the lower 12. */
    +#define HT_GET_KEY(l)    (l >> 12)
    +#define HT_GET_CODE(l)   (l & 0x0FFF)
    +#define HT_PUT_KEY(l)    (l << 12)
    +#define HT_PUT_CODE(l)   (l & 0x0FFF)
    +
    +typedef struct GifHashTableType {
    +    uint32_t HTable[HT_SIZE];
    +} GifHashTableType;
    +
    +GifHashTableType *_InitHashTable(void);
    +void _ClearHashTable(GifHashTableType *HashTable);
    +void _InsertHashTable(GifHashTableType *HashTable, uint32_t Key, int Code);
    +int _ExistsHashTable(GifHashTableType *HashTable, uint32_t Key);
    +
    +#endif /* _GIF_HASH_H_ */
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,335 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/******************************************************************************
    +
    +gif_lib.h - service library for decoding and encoding GIF images
    +
    +SPDX-License-Identifier: MIT
    +
    +*****************************************************************************/
    +
    +#ifndef _GIF_LIB_H_
    +#define _GIF_LIB_H_ 1
    +
    +#ifdef __cplusplus
    +extern "C" {
    +#endif /* __cplusplus */
    +
    +#define GIFLIB_MAJOR 5
    +#define GIFLIB_MINOR 2
    +#define GIFLIB_RELEASE 1
    +
    +#define GIF_ERROR   0
    +#define GIF_OK      1
    +
    +#include 
    +/** Begin JDK modifications to support building using old compilers**/
    +//#include 
    +#ifdef bool
    +#undef bool
    +#endif
    +typedef int bool;
    +#define false 0
    +#define true 1
    +/** End JDK modifications to support building using old compilers**/
    +
    +#define GIF_STAMP "GIFVER"          /* First chars in file - GIF stamp.  */
    +#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
    +#define GIF_VERSION_POS 3           /* Version first character in stamp. */
    +#define GIF87_STAMP "GIF87a"        /* First chars in file - GIF stamp.  */
    +#define GIF89_STAMP "GIF89a"        /* First chars in file - GIF stamp.  */
    +
    +typedef unsigned char GifPixelType;
    +typedef unsigned char *GifRowType;
    +typedef unsigned char GifByteType;
    +typedef unsigned int GifPrefixType;
    +typedef int GifWord;
    +
    +typedef struct GifColorType {
    +    GifByteType Red, Green, Blue;
    +} GifColorType;
    +
    +typedef struct ColorMapObject {
    +    int ColorCount;
    +    int BitsPerPixel;
    +    bool SortFlag;
    +    GifColorType *Colors;    /* on malloc(3) heap */
    +} ColorMapObject;
    +
    +typedef struct GifImageDesc {
    +    GifWord Left, Top, Width, Height;   /* Current image dimensions. */
    +    bool Interlace;                     /* Sequential/Interlaced lines. */
    +    ColorMapObject *ColorMap;           /* The local color map */
    +} GifImageDesc;
    +
    +typedef struct ExtensionBlock {
    +    int ByteCount;
    +    GifByteType *Bytes; /* on malloc(3) heap */
    +    int Function;       /* The block function code */
    +#define CONTINUE_EXT_FUNC_CODE    0x00    /* continuation subblock */
    +#define COMMENT_EXT_FUNC_CODE     0xfe    /* comment */
    +#define GRAPHICS_EXT_FUNC_CODE    0xf9    /* graphics control (GIF89) */
    +#define PLAINTEXT_EXT_FUNC_CODE   0x01    /* plaintext */
    +#define APPLICATION_EXT_FUNC_CODE 0xff    /* application block (GIF89) */
    +} ExtensionBlock;
    +
    +typedef struct SavedImage {
    +    GifImageDesc ImageDesc;
    +    GifByteType *RasterBits;         /* on malloc(3) heap */
    +    int ExtensionBlockCount;         /* Count of extensions before image */
    +    ExtensionBlock *ExtensionBlocks; /* Extensions before image */
    +} SavedImage;
    +
    +typedef struct GifFileType {
    +    GifWord SWidth, SHeight;         /* Size of virtual canvas */
    +    GifWord SColorResolution;        /* How many colors can we generate? */
    +    GifWord SBackGroundColor;        /* Background color for virtual canvas */
    +    GifByteType AspectByte;          /* Used to compute pixel aspect ratio */
    +    ColorMapObject *SColorMap;       /* Global colormap, NULL if nonexistent. */
    +    int ImageCount;                  /* Number of current image (both APIs) */
    +    GifImageDesc Image;              /* Current image (low-level API) */
    +    SavedImage *SavedImages;         /* Image sequence (high-level API) */
    +    int ExtensionBlockCount;         /* Count extensions past last image */
    +    ExtensionBlock *ExtensionBlocks; /* Extensions past last image */
    +    int Error;                       /* Last error condition reported */
    +    void *UserData;                  /* hook to attach user data (TVT) */
    +    void *Private;                   /* Don't mess with this! */
    +} GifFileType;
    +
    +#define GIF_ASPECT_RATIO(n)    ((n)+15.0/64.0)
    +
    +typedef enum {
    +    UNDEFINED_RECORD_TYPE,
    +    SCREEN_DESC_RECORD_TYPE,
    +    IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
    +    EXTENSION_RECORD_TYPE,  /* Begin with '!' */
    +    TERMINATE_RECORD_TYPE   /* Begin with ';' */
    +} GifRecordType;
    +
    +/* func type to read gif data from arbitrary sources (TVT) */
    +typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
    +
    +/* func type to write gif data to arbitrary targets.
    + * Returns count of bytes written. (MRB)
    + */
    +typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
    +
    +/******************************************************************************
    + GIF89 structures
    +******************************************************************************/
    +
    +typedef struct GraphicsControlBlock {
    +    int DisposalMode;
    +#define DISPOSAL_UNSPECIFIED      0       /* No disposal specified. */
    +#define DISPOSE_DO_NOT            1       /* Leave image in place */
    +#define DISPOSE_BACKGROUND        2       /* Set area too background color */
    +#define DISPOSE_PREVIOUS          3       /* Restore to previous content */
    +    bool UserInputFlag;      /* User confirmation required before disposal */
    +    int DelayTime;           /* pre-display delay in 0.01sec units */
    +    int TransparentColor;    /* Palette index for transparency, -1 if none */
    +#define NO_TRANSPARENT_COLOR    -1
    +} GraphicsControlBlock;
    +
    +/******************************************************************************
    + GIF encoding routines
    +******************************************************************************/
    +
    +/* Main entry points */
    +GifFileType *EGifOpenFileName(const char *GifFileName,
    +                              const bool GifTestExistence, int *Error);
    +GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
    +GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
    +int EGifSpew(GifFileType * GifFile);
    +const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
    +int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
    +
    +#define E_GIF_SUCCEEDED          0
    +#define E_GIF_ERR_OPEN_FAILED    1    /* And EGif possible errors. */
    +#define E_GIF_ERR_WRITE_FAILED   2
    +#define E_GIF_ERR_HAS_SCRN_DSCR  3
    +#define E_GIF_ERR_HAS_IMAG_DSCR  4
    +#define E_GIF_ERR_NO_COLOR_MAP   5
    +#define E_GIF_ERR_DATA_TOO_BIG   6
    +#define E_GIF_ERR_NOT_ENOUGH_MEM 7
    +#define E_GIF_ERR_DISK_IS_FULL   8
    +#define E_GIF_ERR_CLOSE_FAILED   9
    +#define E_GIF_ERR_NOT_WRITEABLE  10
    +
    +/* These are legacy.  You probably do not want to call them directly */
    +int EGifPutScreenDesc(GifFileType *GifFile,
    +                      const int GifWidth, const int GifHeight,
    +                      const int GifColorRes,
    +                      const int GifBackGround,
    +                      const ColorMapObject *GifColorMap);
    +int EGifPutImageDesc(GifFileType *GifFile,
    +                     const int GifLeft, const int GifTop,
    +                     const int GifWidth, const int GifHeight,
    +                     const bool GifInterlace,
    +                     const ColorMapObject *GifColorMap);
    +void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
    +int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
    +                int GifLineLen);
    +int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
    +int EGifPutComment(GifFileType *GifFile, const char *GifComment);
    +int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
    +int EGifPutExtensionBlock(GifFileType *GifFile,
    +                         const int GifExtLen, const void *GifExtension);
    +int EGifPutExtensionTrailer(GifFileType *GifFile);
    +int EGifPutExtension(GifFileType *GifFile, const int GifExtCode,
    +                     const int GifExtLen,
    +                     const void *GifExtension);
    +int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
    +                const GifByteType *GifCodeBlock);
    +int EGifPutCodeNext(GifFileType *GifFile,
    +                    const GifByteType *GifCodeBlock);
    +
    +/******************************************************************************
    + GIF decoding routines
    +******************************************************************************/
    +
    +/* Main entry points */
    +GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
    +GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
    +int DGifSlurp(GifFileType * GifFile);
    +GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error);    /* new one (TVT) */
    +    int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
    +
    +#define D_GIF_SUCCEEDED          0
    +#define D_GIF_ERR_OPEN_FAILED    101    /* And DGif possible errors. */
    +#define D_GIF_ERR_READ_FAILED    102
    +#define D_GIF_ERR_NOT_GIF_FILE   103
    +#define D_GIF_ERR_NO_SCRN_DSCR   104
    +#define D_GIF_ERR_NO_IMAG_DSCR   105
    +#define D_GIF_ERR_NO_COLOR_MAP   106
    +#define D_GIF_ERR_WRONG_RECORD   107
    +#define D_GIF_ERR_DATA_TOO_BIG   108
    +#define D_GIF_ERR_NOT_ENOUGH_MEM 109
    +#define D_GIF_ERR_CLOSE_FAILED   110
    +#define D_GIF_ERR_NOT_READABLE   111
    +#define D_GIF_ERR_IMAGE_DEFECT   112
    +#define D_GIF_ERR_EOF_TOO_SOON   113
    +
    +/* These are legacy.  You probably do not want to call them directly */
    +int DGifGetScreenDesc(GifFileType *GifFile);
    +int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
    +int DGifGetImageHeader(GifFileType *GifFile);
    +int DGifGetImageDesc(GifFileType *GifFile);
    +int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
    +int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
    +int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
    +                     GifByteType **GifExtension);
    +int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
    +int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
    +                GifByteType **GifCodeBlock);
    +int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
    +int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
    +const char *DGifGetGifVersion(GifFileType *GifFile);
    +
    +
    +/******************************************************************************
    + Error handling and reporting.
    +******************************************************************************/
    +extern const char *GifErrorString(int ErrorCode);     /* new in 2012 - ESR */
    +
    +/*****************************************************************************
    + Everything below this point is new after version 1.2, supporting `slurp
    + mode' for doing I/O in two big belts with all the image-bashing in core.
    +******************************************************************************/
    +
    +/******************************************************************************
    + Color map handling from gif_alloc.c
    +******************************************************************************/
    +
    +extern ColorMapObject *GifMakeMapObject(int ColorCount,
    +                                     const GifColorType *ColorMap);
    +extern void GifFreeMapObject(ColorMapObject *Object);
    +extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
    +                                     const ColorMapObject *ColorIn2,
    +                                     GifPixelType ColorTransIn2[]);
    +extern int GifBitSize(int n);
    +
    +/******************************************************************************
    + Support for the in-core structures allocation (slurp mode).
    +******************************************************************************/
    +
    +extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
    +extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
    +                                ExtensionBlock **ExtensionBlocks,
    +                                int Function,
    +                                unsigned int Len, unsigned char ExtData[]);
    +extern void GifFreeExtensions(int *ExtensionBlock_Count,
    +                              ExtensionBlock **ExtensionBlocks);
    +extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
    +                                  const SavedImage *CopyFrom);
    +extern void GifFreeSavedImages(GifFileType *GifFile);
    +
    +/******************************************************************************
    + 5.x functions for GIF89 graphics control blocks
    +******************************************************************************/
    +
    +int DGifExtensionToGCB(const size_t GifExtensionLength,
    +                       const GifByteType *GifExtension,
    +                       GraphicsControlBlock *GCB);
    +size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
    +                          GifByteType *GifExtension);
    +
    +int DGifSavedExtensionToGCB(GifFileType *GifFile,
    +                            int ImageIndex,
    +                            GraphicsControlBlock *GCB);
    +int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB,
    +                            GifFileType *GifFile,
    +                            int ImageIndex);
    +
    +/******************************************************************************
    + The library's internal utility font
    +******************************************************************************/
    +
    +#define GIF_FONT_WIDTH  8
    +#define GIF_FONT_HEIGHT 8
    +extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
    +
    +extern void GifDrawText8x8(SavedImage *Image,
    +                     const int x, const int y,
    +                     const char *legend, const int color);
    +
    +extern void GifDrawBox(SavedImage *Image,
    +                    const int x, const int y,
    +                    const int w, const int d, const int color);
    +
    +extern void GifDrawRectangle(SavedImage *Image,
    +                   const int x, const int y,
    +                   const int w, const int d, const int color);
    +
    +extern void GifDrawBoxedText8x8(SavedImage *Image,
    +                          const int x, const int y,
    +                          const char *legend,
    +                          const int border, const int bg, const int fg);
    +
    +#ifdef __cplusplus
    +}
    +#endif /* __cplusplus */
    +#endif /* _GIF_LIB_H */
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/gif_lib_private.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,94 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/****************************************************************************
    +
    +gif_lib_private.h - internal giflib routines and structures
    +
    +SPDX-License-Identifier: MIT
    +
    +****************************************************************************/
    +
    +#ifndef _GIF_LIB_PRIVATE_H
    +#define _GIF_LIB_PRIVATE_H
    +
    +#include "gif_lib.h"
    +#include "gif_hash.h"
    +
    +#ifndef SIZE_MAX
    +    #define SIZE_MAX     UINTPTR_MAX
    +#endif
    +
    +#define EXTENSION_INTRODUCER      0x21
    +#define DESCRIPTOR_INTRODUCER     0x2c
    +#define TERMINATOR_INTRODUCER     0x3b
    +
    +#define LZ_MAX_CODE         4095    /* Biggest code possible in 12 bits. */
    +#define LZ_BITS             12
    +
    +#define FLUSH_OUTPUT        4096    /* Impossible code, to signal flush. */
    +#define FIRST_CODE          4097    /* Impossible code, to signal first. */
    +#define NO_SUCH_CODE        4098    /* Impossible code, to signal empty. */
    +
    +#define FILE_STATE_WRITE    0x01
    +#define FILE_STATE_SCREEN   0x02
    +#define FILE_STATE_IMAGE    0x04
    +#define FILE_STATE_READ     0x08
    +
    +#define IS_READABLE(Private)    (Private->FileState & FILE_STATE_READ)
    +#define IS_WRITEABLE(Private)   (Private->FileState & FILE_STATE_WRITE)
    +
    +typedef struct GifFilePrivateType {
    +    GifWord FileState, FileHandle,  /* Where all this data goes to! */
    +      BitsPerPixel,     /* Bits per pixel (Codes uses at least this + 1). */
    +      ClearCode,   /* The CLEAR LZ code. */
    +      EOFCode,     /* The EOF LZ code. */
    +      RunningCode, /* The next code algorithm can generate. */
    +      RunningBits, /* The number of bits required to represent RunningCode. */
    +      MaxCode1,    /* 1 bigger than max. possible code, in RunningBits bits. */
    +      LastCode,    /* The code before the current code. */
    +      CrntCode,    /* Current algorithm code. */
    +      StackPtr,    /* For character stack (see below). */
    +      CrntShiftState;    /* Number of bits in CrntShiftDWord. */
    +    unsigned long CrntShiftDWord;   /* For bytes decomposition into codes. */
    +    unsigned long PixelCount;   /* Number of pixels in image. */
    +    FILE *File;    /* File as stream. */
    +    InputFunc Read;     /* function to read gif input (TVT) */
    +    OutputFunc Write;   /* function to write gif output (MRB) */
    +    GifByteType Buf[256];   /* Compressed input is buffered here. */
    +    GifByteType Stack[LZ_MAX_CODE]; /* Decoded pixels are stacked here. */
    +    GifByteType Suffix[LZ_MAX_CODE + 1];    /* So we can trace the codes. */
    +    GifPrefixType Prefix[LZ_MAX_CODE + 1];
    +    GifHashTableType *HashTable;
    +    bool gif89;
    +} GifFilePrivateType;
    +
    +#ifndef HAVE_REALLOCARRAY
    +extern void *openbsd_reallocarray(void *optr, size_t nmemb, size_t size);
    +#define reallocarray openbsd_reallocarray
    +#endif
    +
    +#endif /* _GIF_LIB_PRIVATE_H */
    +
    +/* end */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/giflib/openbsd-reallocarray.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,99 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/*    $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $    */
    +/*
    + * Copyright (c) 2008 Otto Moerbeek 
    + * SPDX-License-Identifier: MIT
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +#ifndef SIZE_MAX
    +    #define SIZE_MAX     UINTPTR_MAX
    +#endif
    +
    +/*
    + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
    + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
    + */
    +#define MUL_NO_OVERFLOW    ((size_t)1 << (sizeof(size_t) * 4))
    +
    +void *
    +openbsd_reallocarray(void *optr, size_t nmemb, size_t size)
    +{
    +    if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
    +        nmemb > 0 && SIZE_MAX / nmemb < size) {
    +        errno = ENOMEM;
    +        return NULL;
    +    }
    +    /*
    +     * Head off variations in realloc behavior on different
    +     * platforms (reported by MarkR )
    +     *
    +     * The behaviour of reallocarray is implementation-defined if
    +     * nmemb or size is zero. It can return NULL or non-NULL
    +     * depending on the platform.
    +     * https://www.securecoding.cert.org/confluence/display/c/MEM04-C.Beware+of+zero-lengthallocations
    +     *
    +     * Here are some extracts from realloc man pages on different platforms.
    +     *
    +     * void realloc( void memblock, size_t size );
    +     *
    +     * Windows:
    +     *
    +     * If there is not enough available memory to expand the block
    +     * to the given size, the original block is left unchanged,
    +     * and NULL is returned.  If size is zero, then the block
    +     * pointed to by memblock is freed; the return value is NULL,
    +     * and memblock is left pointing at a freed block.
    +     *
    +     * OpenBSD:
    +     *
    +     * If size or nmemb is equal to 0, a unique pointer to an
    +     * access protected, zero sized object is returned. Access via
    +     * this pointer will generate a SIGSEGV exception.
    +     *
    +     * Linux:
    +     *
    +     * If size was equal to 0, either NULL or a pointer suitable
    +     * to be passed to free() is returned.
    +     *
    +     * OS X:
    +     *
    +     * If size is zero and ptr is not NULL, a new, minimum sized
    +     * object is allocated and the original object is freed.
    +     *
    +     * It looks like images with zero width or height can trigger
    +     * this, and fuzzing behaviour will differ by platform, so
    +     * fuzzing on one platform may not detect zero-size allocation
    +     * problems on other platforms.
    +     */
    +    if (size == 0 || nmemb == 0)
    +        return NULL;
    +    return realloc(optr, size * nmemb);
    +}
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,6109 @@
    +CHANGES - changes for libpng
    +
    +version 0.1 [March 29, 1995]
    +  initial work-in-progress release
    +
    +version 0.2 [April 1, 1995]
    +  added reader into png.h
    +  fixed small problems in stub file
    +
    +version 0.3 [April 8, 1995]
    +  added pull reader
    +  split up pngwrite.c to several files
    +  added pnglib.txt
    +  added example.c
    +  cleaned up writer, adding a few new transformations
    +  fixed some bugs in writer
    +  interfaced with zlib 0.5
    +  added K&R support
    +  added check for 64 KB blocks for 16 bit machines
    +
    +version 0.4 [April 26, 1995]
    +  cleaned up code and commented code
    +  simplified time handling into png_time
    +  created png_color_16 and png_color_8 to handle color needs
    +  cleaned up color type defines
    +  fixed various bugs
    +  made various names more consistent
    +  interfaced with zlib 0.71
    +  cleaned up zTXt reader and writer (using zlib's Reset functions)
    +  split transformations into pngrtran.c and pngwtran.c
    +
    +version 0.5 [April 30, 1995]
    +  interfaced with zlib 0.8
    +  fixed many reading and writing bugs
    +  saved using 3 spaces instead of tabs
    +
    +version 0.6 [May 1, 1995]
    +  first beta release
    +  added png_large_malloc() and png_large_free()
    +  added png_size_t
    +  cleaned up some compiler warnings
    +  added png_start_read_image()
    +
    +version 0.7 [June 24, 1995]
    +  cleaned up lots of bugs
    +  finished dithering and other stuff
    +  added test program
    +  changed name from pnglib to libpng
    +
    +version 0.71 [June 26, 1995]
    +  changed pngtest.png for zlib 0.93
    +  fixed error in libpng.txt and example.c
    +
    +version 0.8 [August 20, 1995]
    +  cleaned up some bugs
    +  added png_set_filler()
    +  split up pngstub.c into pngmem.c, pngio.c, and pngerror.c
    +  added #define's to remove unwanted code
    +  moved png_info_init() to png.c
    +  added old_size into png_realloc()
    +  added functions to manually set filtering and compression info
    +  changed compression parameters based on image type
    +  optimized filter selection code
    +  added version info
    +  changed external functions passing floats to doubles (k&r problems?)
    +  put all the configurable stuff in pngconf.h
    +  enabled png_set_shift to work with paletted images on read
    +  added png_read_update_info() - updates info structure with transformations
    +
    +Version 0.81 [August, 1995]
    +  incorporated Tim Wegner's medium model code (thanks, Tim)
    +
    +Version 0.82 [September, 1995]
    +  [unspecified changes]
    +
    +Version 0.85 [December, 1995]
    +  added more medium model code (almost everything's a far)
    +  added i/o, error, and memory callback functions
    +  fixed some bugs (16-bit, 4-bit interlaced, etc.)
    +  added first run progressive reader (barely tested)
    +
    +Version 0.86 [January, 1996]
    +  fixed bugs
    +  improved documentation
    +
    +Version 0.87 [January, 1996]
    +  fixed medium model bugs
    +  fixed other bugs introduced in 0.85 and 0.86
    +  added some minor documentation
    +
    +Version 0.88 [January, 1996]
    +  fixed progressive bugs
    +  replaced tabs with spaces
    +  cleaned up documentation
    +  added callbacks for read/write and warning/error functions
    +
    +Version 0.89 [June 5, 1996]
    +  Added new initialization API to make libpng work better with shared libs
    +    we now have png_create_read_struct(), png_create_write_struct(),
    +    png_create_info_struct(), png_destroy_read_struct(), and
    +    png_destroy_write_struct() instead of the separate calls to
    +    malloc and png_read_init(), png_info_init(), and png_write_init()
    +  Changed warning/error callback functions to fix bug - this means you
    +    should use the new initialization API if you were using the old
    +    png_set_message_fn() calls, and that the old API no longer exists
    +    so that people are aware that they need to change their code
    +  Changed filter selection API to allow selection of multiple filters
    +    since it didn't work in previous versions of libpng anyways
    +  Optimized filter selection code
    +  Fixed png_set_background() to allow using an arbitrary RGB color for
    +    paletted images
    +  Fixed gamma and background correction for paletted images, so
    +    png_correct_palette is not needed unless you are correcting an
    +    external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
    +    in pngconf.h) - if nobody uses this, it may disappear in the future.
    +  Fixed bug with Borland 64K memory allocation (Alexander Lehmann)
    +  Fixed bug in interlace handling (Smarasderagd, I think)
    +  Added more error checking for writing and image to reduce invalid files
    +  Separated read and write functions so that they won't both be linked
    +    into a binary when only reading or writing functionality is used
    +  New pngtest image also has interlacing and zTXt
    +  Updated documentation to reflect new API
    +
    +Version 0.89c [June 17, 1996]
    +  Bug fixes.
    +
    +Version 0.90 [January, 1997]
    +  Made CRC errors/warnings on critical and ancillary chunks configurable
    +  libpng will use the zlib CRC routines by (compile-time) default
    +  Changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
    +  Added external C++ wrapper statements to png.h (Gilles Dauphin)
    +  Allow PNG file to be read when some or all of file signature has already
    +    been read from the beginning of the stream.  ****This affects the size
    +    of info_struct and invalidates all programs that use a shared libpng****
    +  Fixed png_filler() declarations
    +  Fixed? background color conversions
    +  Fixed order of error function pointers to match documentation
    +  Current chunk name is now available in png_struct to reduce the number
    +    of nearly identical error messages (will simplify multi-lingual
    +    support when available)
    +  Try to get ready for unknown-chunk callback functions:
    +    - previously read critical chunks are flagged, so the chunk handling
    +      routines can determine if the chunk is in the right place
    +    - all chunk handling routines have the same prototypes, so we will
    +      be able to handle all chunks via a callback mechanism
    +  Try to fix Linux "setjmp" buffer size problems
    +  Removed png_large_malloc, png_large_free, and png_realloc functions.
    +
    +Version 0.95 [March, 1997]
    +  Fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
    +  Fixed bug in PNG file signature compares when start != 0
    +  Changed parameter type of png_set_filler(...filler...) from png_byte
    +    to png_uint_32
    +  Added test for MACOS to ensure that both math.h and fp.h are not #included
    +  Added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
    +  Added "packswap" transformation, which changes the endianness of
    +    packed-pixel bytes (Kevin Bracey)
    +  Added "strip_alpha" transformation, which removes the alpha channel of
    +    input images without using it (not necessarily a good idea)
    +  Added "swap_alpha" transformation, which puts the alpha channel in front
    +    of the color bytes instead of after
    +  Removed all implicit variable tests which assume NULL == 0 (I think)
    +  Changed several variables to "png_size_t" to show 16/32-bit limitations
    +  Added new pCAL chunk read/write support
    +  Added experimental filter selection weighting (Greg Roelofs)
    +  Removed old png_set_rgbx() and png_set_xrgb() functions that have been
    +    obsolete for about 2 years now (use png_set_filler() instead)
    +  Added macros to read 16- and 32-bit ints directly from buffer, to be
    +    used only on those systems that support it (namely PowerPC and 680x0)
    +    With some testing, this may become the default for MACOS/PPC systems.
    +  Only calculate CRC on data if we are going to use it
    +  Added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
    +  Added macros for simple libpng debugging output selectable at compile time
    +  Removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
    +  More description of info_struct in libpng.txt and png.h
    +  More instructions in example.c
    +  More chunk types tested in pngtest.c
    +  Renamed pngrcb.c to pngset.c, and all png_read_ functions to be
    +    png_set_.  We now have corresponding png_get_
    +    functions in pngget.c to get information in info_ptr.  This isolates
    +    the application from the internal organization of png_info_struct
    +    (good for shared library implementations).
    +
    +Version 0.96 [May, 1997]
    +  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() 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)
    +  Added typecasts to quiet compiler errors
    +  Added more debugging info
    +
    +Version 0.97 [January, 1998]
    +  Removed PNG_USE_OWN_CRC capability
    +  Relocated png_set_crc_action from pngrutil.c to pngrtran.c
    +  Fixed typecasts of "new_key", etc. (Andreas Dilger)
    +  Added RFC 1152 [sic] date support
    +  Fixed bug in gamma handling of 4-bit grayscale
    +  Added 2-bit grayscale gamma handling (Glenn R-P)
    +  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;
    +    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 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 0.98 [January, 1998]
    +  Cleaned up some typos in libpng.txt and in code documentation
    +  Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
    +  Cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
    +  Changed recommendation about file_gamma for PC images to .51 from .45,
    +    in example.c and libpng.txt, added comments to distinguish between
    +    screen_gamma, viewing_gamma, and display_gamma.
    +  Changed all references to RFC1152 to read RFC1123 and changed the
    +    PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
    +  Added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
    +  Changed srgb_intent from png_byte to int to avoid compiler bugs
    +
    +Version 0.99 [January 30, 1998]
    +  Free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
    +  Fixed a longstanding "packswap" bug in pngtrans.c
    +  Fixed some inconsistencies in pngconf.h that prevented compiling with
    +    PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
    +  Fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
    +  Changed recommendation about file_gamma for PC images to .50 from .51 in
    +    example.c and libpng.txt, and changed file_gamma for sRGB images to .45
    +  Added a number of functions to access information from the png structure
    +    png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
    +  Added TARGET_MACOS similar to zlib-1.0.8
    +  Define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
    +  Added type casting to all png_malloc() function calls
    +
    +Version 0.99a [January 31, 1998]
    +  Added type casts and parentheses to all returns that return a value.(Tim W.)
    +
    +Version 0.99b [February 4, 1998]
    +  Added type cast png_uint_32 on malloc function calls where needed.
    +  Changed type of num_hist from png_uint_32 to int (same as num_palette).
    +  Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
    +  Renamed makefile.elf to makefile.lnx.
    +
    +Version 0.99c [February 7, 1998]
    +  More type casting.  Removed erroneous overflow test in pngmem.c.
    +  Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
    +  Added UNIX manual pages libpng.3 (incorporating libpng.txt) and  png.5.
    +
    +Version 0.99d [February 11, 1998]
    +  Renamed "far_to_near()" "png_far_to_near()"
    +  Revised libpng.3
    +  Version 99c "buffered" operations didn't work as intended.  Replaced them
    +    with png_memcpy_check() and png_memset_check().
    +  Added many "if (png_ptr == NULL) return" to quell compiler warnings about
    +    unused png_ptr, mostly in pngget.c and pngset.c.
    +  Check for overlength tRNS chunk present when indexed-color PLTE is read.
    +  Cleaned up spelling errors in libpng.3/libpng.txt
    +  Corrected a problem with png_get_tRNS() which returned undefined trans array
    +
    +Version 0.99e [February 28, 1998]
    +  Corrected png_get_tRNS() again.
    +  Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
    +  Touched up example.c to make more of it compileable, although the entire
    +    file still can't be compiled (Willem van Schaik)
    +  Fixed a bug in png_do_shift() (Bryan Tsai)
    +  Added a space in png.h prototype for png_write_chunk_start()
    +  Replaced pngtest.png with one created with zlib 1.1.1
    +  Changed pngtest to report PASS even when file size is different (Jean-loup G.)
    +  Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
    +
    +Version 0.99f [March 5, 1998]
    +  Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
    +  Moved makefiles into a "scripts" directory, and added INSTALL instruction file
    +  Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
    +  Added pointers to "note on libpng versions" in makefile.lnx and README
    +  Added row callback feature when reading and writing nonprogressive rows
    +    and added a test of this feature in pngtest.c
    +  Added user transform callbacks, with test of the feature in pngtest.c
    +
    +Version 0.99g [March 6, 1998, morning]
    +  Minor changes to pngtest.c to suppress compiler warnings.
    +  Removed "beta" language from documentation.
    +
    +Version 0.99h [March 6, 1998, evening]
    +  Minor changes to previous minor changes to pngtest.c
    +  Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
    +    and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
    +  Added user transform capability
    +
    +Version 1.00 [March 7, 1998]
    +  Changed several typedefs in pngrutil.c
    +  Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
    +  Replaced "while(1)" with "for(;;)"
    +  Added PNGARG() to prototypes in pngtest.c and removed some prototypes
    +  Updated some of the makefiles (Tom Lane)
    +  Changed some typedefs (s_start, etc.) in pngrutil.c
    +  Fixed dimensions of "short_months" array in pngwrite.c
    +  Replaced ansi2knr.c with the one from jpeg-v6
    +
    +Version 1.0.0 [March 8, 1998]
    +  Changed name from 1.00 to 1.0.0 (Adam Costello)
    +  Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
    +
    +Version 1.0.0a [March 9, 1998]
    +  Fixed three bugs in pngrtran.c to make gamma+background handling consistent
    +    (Greg Roelofs)
    +  Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
    +    for major, minor, and bugfix releases.  This is 10001. (Adam Costello,
    +    Tom Lane)
    +  Make months range from 1-12 in png_convert_to_rfc1123
    +
    +Version 1.0.0b [March 13, 1998]
    +  Quieted compiler complaints about two empty "for" loops in pngrutil.c
    +  Minor changes to makefile.s2x
    +  Removed #ifdef/#endif around a png_free() in pngread.c
    +
    +Version 1.0.1 [March 14, 1998]
    +  Changed makefile.s2x to reduce security risk of using a relative pathname
    +  Fixed some typos in the documentation (Greg).
    +  Fixed a problem with value of "channels" returned by png_read_update_info()
    +
    +Version 1.0.1a [April 21, 1998]
    +  Optimized Paeth calculations by replacing abs() function calls with intrinsics
    +  plus other loop optimizations. Improves avg decoding speed by about 20%.
    +  Commented out i386istic "align" compiler flags in makefile.lnx.
    +  Reduced the default warning level in some makefiles, to make them consistent.
    +  Removed references to IJG and JPEG in the ansi2knr.c copyright statement.
    +  Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.
    +  Added grayscale and 16-bit capability to png_do_read_filler().
    +  Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes
    +    too large when writing an image with bit_depth < 8 (Bob Dellaca).
    +  Corrected some bugs in the experimental weighted filtering heuristics.
    +  Moved a misplaced pngrutil code block that truncates tRNS if it has more
    +    than num_palette entries -- test was done before num_palette was defined.
    +  Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).
    +  Changed compiler flags in makefile.wat for better optimization
    +    (Pawel Mrochen).
    +
    +Version 1.0.1b [May 2, 1998]
    +  Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).
    +  Relocated the png_composite macros from pngrtran.c to png.h (Greg).
    +  Added makefile.sco (contributed by Mike Hopkirk).
    +  Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a.
    +  Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.
    +  More work on the Paeth-filtering, achieving imperceptible speedup
    +    (A Kleinert).
    +  More work on loop optimization which may help when compiled with C++
    +    compilers.
    +  Added warnings when people try to use transforms they've defined out.
    +  Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran.
    +  Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)
    +
    +Version 1.0.1c [May 11, 1998]
    +  Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for
    +    filler bytes should have been 0xff instead of 0xf.
    +  Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.
    +  Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED
    +    out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h
    +  Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED,
    +    for consistency, in pngconf.h
    +  Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier
    +    to remove unwanted capabilities via the compile line
    +  Made some corrections to grammar (which, it's) in documentation (Greg).
    +  Corrected example.c, use of row_pointers in png_write_image().
    +
    +Version 1.0.1d [May 24, 1998]
    +  Corrected several statements that used side effects illegally in pngrutil.c
    +    and pngtrans.c, that were introduced in version 1.0.1b
    +  Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)
    +  More corrections to example.c, use of row_pointers in png_write_image()
    +    and png_read_rows().
    +  Added pngdll.mak and pngdef.pas to scripts directory, contributed by
    +    Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5
    +  Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)
    +  Changed several loops from count-down to count-up, for consistency.
    +
    +Version 1.0.1e [June 6, 1998]
    +  Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and
    +    added warnings when people try to set png_read_fn and png_write_fn in
    +    the same structure.
    +  Added a test such that png_do_gamma will be done when num_trans==0
    +    for truecolor images that have defined a background.  This corrects an
    +    error that was introduced in libpng-0.90 that can cause gamma processing
    +    to be skipped.
    +  Added tests in png.h to include "trans" and "trans_values" in structures
    +    when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.
    +  Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()
    +  Moved png_convert_to_rfc_1123() from pngwrite.c to png.c
    +  Added capability for user-provided malloc_fn() and free_fn() functions,
    +    and revised pngtest.c to demonstrate their use, replacing the
    +    PNGTEST_DEBUG_MEM feature.
    +  Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).
    +
    +Version 1.0.2 [June 14, 1998]
    +  Fixed two bugs in makefile.bor .
    +
    +Version 1.0.2a [December 30, 1998]
    +  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
    +  Fixed a bug in png_do_filler() that made it fail to write filler bytes in
    +    the left-most pixel of each row (Kevin Bracey).
    +  Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
    +    in pngtest.c (Duncan Simpson).
    +  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
    +    even when no tIME chunk was present in the source file.
    +  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
    +  Fixed a problem in png_read_push_finish_row(), which would not skip some
    +    passes that it should skip, for images that are less than 3 pixels high.
    +  Interchanged the order of calls to png_do_swap() and png_do_shift()
    +    in pngwtran.c (John Cromer).
    +  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
    +  Changed "bad adaptive filter type" from error to warning in pngrutil.c .
    +  Fixed a documentation error about default filtering with 8-bit indexed-color.
    +  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
    +    (L. Peter Deutsch).
    +  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
    +  Added png_get_copyright() and png_get_header_version() functions.
    +  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
    +  Added information about debugging in libpng.txt and libpng.3 .
    +  Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and
    +    makefile.sco.
    +  Removed lines after Dynamic Dependencies" in makefile.aco .
    +  Revised makefile.dec to make a shared library (Jeremie Petit).
    +  Removed trailing blanks from all files.
    +
    +Version 1.0.2a [January 6, 1999]
    +  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
    +  Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
    +  Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
    +  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
    +    which is obsolete.
    +
    +Version 1.0.3 [January 14, 1999]
    +  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
    +  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
    +
    +Version 1.0.3a [August 12, 1999]
    +  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
    +    if an attempt is made to read an interlaced image when it's not supported.
    +  Added check if png_ptr->trans is defined before freeing it in pngread.c
    +  Modified the Y2K statement to include versions back to version 0.71
    +  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
    +  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
    +  Replaced leading blanks with tab characters in makefile.hux
    +  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
    +  Changed (float)red and (float)green to (double)red, (double)green
    +    in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
    +  Fixed a bug in pngconf.h that omitted  when PNG_DEBUG==0 (K Bracey).
    +  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
    +  Updated documentation to refer to the PNG-1.2 specification.
    +  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
    +    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
    +  Fixed bugs in calculation of the length of rowbytes when adding alpha
    +    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
    +  Added function png_set_user_transform_info() to store user_transform_ptr,
    +    user_depth, and user_channels into the png_struct, and a function
    +    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
    +  Added function png_set_empty_plte_permitted() to make libpng useable
    +    in MNG applications.
    +  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
    +  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
    +    consistent with PNG-1.2, and allow variance of 500 before complaining.
    +  Added assembler code contributed by Intel in file pngvcrd.c and modified
    +    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation,
    +    Gilles Vollant)
    +  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
    +  Added some aliases for png_set_expand() in pngrtran.c, namely
    +    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
    +    (Greg Roelofs, in "PNG: The Definitive Guide").
    +  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
    +
    +Version 1.0.3b [August 26, 1999]
    +  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
    +  Changed leading blanks to tabs in all makefiles.
    +  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
    +  Made alternate versions of  png_set_expand() in pngrtran.c, namely
    +    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
    +    (Greg Roelofs, in "PNG: The Definitive Guide").  Deleted the 1.0.3a aliases.
    +  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
    +  Revised calculation of num_blocks in pngmem.c to avoid a potentially
    +    negative shift distance, whose results are undefined in the C language.
    +  Added a check in pngset.c to prevent writing multiple tIME chunks.
    +  Added a check in pngwrite.c to detect invalid small window_bits sizes.
    +
    +Version 1.0.3d [September 4, 1999]
    +  Fixed type casting of igamma in pngrutil.c
    +  Added new png_expand functions to scripts/pngdef.pas and pngos2.def
    +  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
    +
    +Version 1.0.4 [September 24, 1999, not distributed publicly]
    +  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
    +  Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
    +  Made several minor corrections to pngtest.c
    +  Renamed the makefiles with longer but more user friendly extensions.
    +  Copied the PNG copyright and license to a separate LICENSE file.
    +  Revised documentation, png.h, and example.c to remove reference to
    +    "viewing_gamma" which no longer appears in the PNG specification.
    +  Revised pngvcrd.c to use MMX code for interlacing only on the final pass.
    +  Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a
    +  Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX
    +    assembler code) and makefile.vcwin32 (doesn't).
    +  Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)
    +  Added a copy of pngnow.png to the distribution.
    +
    +Version 1.0.4a [September 25, 1999]
    +  Increase max_pixel_depth in pngrutil.c if a user transform needs it.
    +  Changed several division operations to right-shifts in pngvcrd.c
    +
    +Version 1.0.4b [September 30, 1999]
    +  Added parentheses in line 3732 of pngvcrd.c
    +  Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1
    +
    +Version 1.0.4c [October 1, 1999]
    +  Added a "png_check_version" function in png.c and pngtest.c that will generate
    +    a helpful compiler error if an old png.h is found in the search path.
    +  Changed type of png_user_transform_depth|channels from int to png_byte.
    +  Added "Libpng is OSI Certified Open Source Software" statement to png.h
    +
    +Version 1.0.4d [October 6, 1999]
    +  Changed 0.45 to 0.45455 in png_set_sRGB()
    +  Removed unused PLTE entries from pngnow.png
    +  Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
    +
    +Version 1.0.4e [October 10, 1999]
    +  Fixed sign error in pngvcrd.c (Greg Roelofs)
    +  Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
    +
    +Version 1.0.4f [October 15, 1999]
    +  Surrounded example.c code with #if 0 .. #endif to prevent people from
    +    inadvertently trying to compile it.
    +  Changed png_get_header_version() from a function to a macro in png.h
    +  Added type casting mostly in pngrtran.c and pngwtran.c
    +  Removed some pointless "ptr = NULL" in pngmem.c
    +  Added a "contrib" directory containing the source code from Greg's book.
    +
    +Version 1.0.5 [October 15, 1999]
    +  Minor editing of the INSTALL and README files.
    +
    +Version 1.0.5a [October 23, 1999]
    +  Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)
    +  Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)
    +  Further optimization and bugfix of pngvcrd.c
    +  Revised pngset.c so that it does not allocate or free memory in the user's
    +    text_ptr structure.  Instead, it makes its own copy.
    +  Created separate write_end_info_struct in pngtest.c for a more severe test.
    +  Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.
    +
    +Version 1.0.5b [November 23, 1999]
    +  Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and
    +    PNG_FLAG_WROTE_tIME from flags to mode.
    +  Added png_write_info_before_PLTE() function.
    +  Fixed some typecasting in contrib/gregbook/*.c
    +  Updated scripts/makevms.com and added makevms.com to contrib/gregbook
    +    and contrib/pngminus (Martin Zinser)
    +
    +Version 1.0.5c [November 26, 1999]
    +  Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr.
    +  Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to
    +    accommodate making DLL's: Moved usr_png_ver from global variable to function
    +    png_get_header_ver() in png.c.  Moved png_sig to png_sig_bytes in png.c and
    +    eliminated use of png_sig in pngwutil.c.  Moved the various png_CHNK arrays
    +    into pngtypes.h.  Eliminated use of global png_pass arrays.  Declared the
    +    png_CHNK and png_pass arrays to be "const".  Made the global arrays
    +    available to applications (although none are used in libpng itself) when
    +    PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.
    +  Removed some extraneous "-I" from contrib/pngminus/makefile.std
    +  Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
    +  Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
    +
    +Version 1.0.5d [November 29, 1999]
    +  Add type cast (png_const_charp) two places in png.c
    +  Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
    +  Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
    +    to applications a macro "PNG_USE_LOCAL_ARRAYS".
    +  comment out (with #ifdef) all the new declarations when
    +    PNG_USE_GLOBAL_ARRAYS is defined.
    +  Added PNG_EXPORT_VAR macro to accommodate making DLL's.
    +
    +Version 1.0.5e [November 30, 1999]
    +  Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
    +    structure; refactored the inflate/deflate support to make adding new chunks
    +    with trailing compressed parts easier in the future, and added new functions
    +    png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
    +    png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
    +    NOTE: Applications that write text chunks MUST define png_text->lang
    +    before calling png_set_text(). It must be set to NULL if you want to
    +    write tEXt or zTXt chunks.  If you want your application to be able to
    +    run with older versions of libpng, use
    +
    +      #ifdef PNG_iTXt_SUPPORTED
    +         png_text[i].lang = NULL;
    +      #endif
    +
    +  Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned
    +    offsets (Eric S. Raymond).
    +  Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into
    +    PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED
    +    macros, leaving the separate macros also available.
    +  Removed comments on #endifs at the end of many short, non-nested #if-blocks.
    +
    +Version 1.0.5f [December 6, 1999]
    +  Changed makefile.solaris to issue a warning about potential problems when
    +    the ucb "ld" is in the path ahead of the ccs "ld".
    +  Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3.
    +  Added sCAL chunk support (Eric S. Raymond).
    +
    +Version 1.0.5g [December 7, 1999]
    +  Fixed "png_free_spallettes" typo in png.h
    +  Added code to handle new chunks in pngpread.c
    +  Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block
    +  Added "translated_key" to png_text structure and png_write_iTXt().
    +  Added code in pngwrite.c to work around a newly discovered zlib bug.
    +
    +Version 1.0.5h [December 10, 1999]
    +  NOTE: regarding the note for version 1.0.5e, the following must also
    +    be included in your code:
    +        png_text[i].translated_key = NULL;
    +  Unknown chunk handling is now supported.
    +  Option to eliminate all floating point support was added.  Some new
    +    fixed-point functions such as png_set_gAMA_fixed() were added.
    +  Expanded tabs and removed trailing blanks in source files.
    +
    +Version 1.0.5i [December 13, 1999]
    +  Added some type casts to silence compiler warnings.
    +  Renamed "png_free_spalette" to "png_free_spalettes" for consistency.
    +  Removed leading blanks from a #define in pngvcrd.c
    +  Added some parameters to the new png_set_keep_unknown_chunks() function.
    +  Added a test for up->location != 0 in the first instance of writing
    +    unknown chunks in pngwrite.c
    +  Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to
    +    prevent recursion.
    +  Added png_free_hIST() function.
    +  Various patches to fix bugs in the sCAL and integer cHRM processing,
    +    and to add some convenience macros for use with sCAL.
    +
    +Version 1.0.5j [December 21, 1999]
    +  Changed "unit" parameter of png_write_sCAL from png_byte to int, to work
    +    around buggy compilers.
    +  Added new type "png_fixed_point" for integers that hold float*100000 values
    +  Restored backward compatibility of tEXt/zTXt chunk processing:
    +    Restored the first four members of png_text to the same order as v.1.0.5d.
    +    Added members "lang_key" and "itxt_length" to png_text struct.  Set
    +    text_length=0 when "text" contains iTXt data.  Use the "compression"
    +    member to distinguish among tEXt/zTXt/iTXt types.  Added
    +    PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.
    +    The "Note" above, about backward incompatibility of libpng-1.0.5e, no
    +    longer applies.
    +  Fixed png_read|write_iTXt() to read|write parameters in the right order,
    +    and to write the iTXt chunk after IDAT if it appears in the end_ptr.
    +  Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)
    +  Reversed the order of trying to write floating-point and fixed-point gAMA.
    +
    +Version 1.0.5k [December 27, 1999]
    +  Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))"
    +  Added png_handle_as_unknown() function (Glenn)
    +  Added png_free_chunk_list() function and chunk_list and num_chunk_list members
    +    of png_ptr.
    +  Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.
    +  Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings
    +    about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)
    +  Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).
    +  Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.
    +  Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().
    +
    +Version 1.0.5l [January 1, 2000]
    +  Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()
    +    for setting a callback function to handle unknown chunks and for
    +    retrieving the associated user pointer (Glenn).
    +
    +Version 1.0.5m [January 7, 2000]
    +  Added high-level functions png_read_png(), png_write_png(), png_free_pixels().
    +
    +Version 1.0.5n [January 9, 2000]
    +  Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its
    +    own memory for info_ptr->palette.  This makes it safe for the calling
    +    application to free its copy of the palette any time after it calls
    +    png_set_PLTE().
    +
    +Version 1.0.5o [January 20, 2000]
    +  Cosmetic changes only (removed some trailing blanks and TABs)
    +
    +Version 1.0.5p [January 31, 2000]
    +  Renamed pngdll.mak to makefile.bd32
    +  Cosmetic changes in pngtest.c
    +
    +Version 1.0.5q [February 5, 2000]
    +  Relocated the makefile.solaris warning about PATH problems.
    +  Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)
    +  Revised makefile.gcmmx
    +  Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
    +
    +Version 1.0.5r [February 7, 2000]
    +  Removed superfluous prototype for png_get_itxt from png.h
    +  Fixed a bug in pngrtran.c that improperly expanded the background color.
    +  Return *num_text=0 from png_get_text() when appropriate, and fix documentation
    +    of png_get_text() in libpng.txt/libpng.3.
    +
    +Version 1.0.5s [February 18, 2000]
    +  Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the
    +    new error handler that's planned for the next libpng release, and changed
    +    example.c, pngtest.c, and contrib programs to use this macro.
    +  Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)
    +  Fixed a bug in png_read_png() that caused it to fail to expand some images
    +    that it should have expanded.
    +  Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions
    +    in pngget.c
    +  Changed the allocation of palette, history, and trans arrays back to
    +    the version 1.0.5 method (linking instead of copying) which restores
    +    backward compatibility with version 1.0.5.  Added some remarks about
    +    that in example.c.  Added "free_me" member to info_ptr and png_ptr
    +    and added png_free_data() function.
    +  Updated makefile.linux and makefile.gccmmx to make directories conditionally.
    +  Made cosmetic changes to pngasmrd.h
    +  Added png_set_rows() and png_get_rows(), for use with png_read|write_png().
    +  Modified png_read_png() to allocate info_ptr->row_pointers only if it
    +    hasn't already been allocated.
    +
    +Version 1.0.5t [March 4, 2000]
    +  Changed png_jmp_env() migration aiding macro to png_jmpbuf().
    +  Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c
    +  Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when
    +    PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b
    +  Files in contrib/gregbook were revised to use png_jmpbuf() and to select
    +    a 24-bit visual if one is available, and to allow abbreviated options.
    +  Files in contrib/pngminus were revised to use the png_jmpbuf() macro.
    +  Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s
    +
    +Version 1.0.5u [March 5, 2000]
    +  Simplified the code that detects old png.h in png.c and pngtest.c
    +  Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)
    +  Increased precision of rgb_to_gray calculations from 8 to 15 bits and
    +    added png_set_rgb_to_gray_fixed() function.
    +  Added makefile.bc32 (32-bit Borland C++, C mode)
    +
    +Version 1.0.5v [March 11, 2000]
    +  Added some parentheses to the png_jmpbuf macro definition.
    +  Updated references to the zlib home page, which has moved to freesoftware.com.
    +  Corrected bugs in documentation regarding png_read_row() and png_write_row().
    +  Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.
    +  Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,
    +    revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)
    +
    +Version 1.0.6 [March 20, 2000]
    +  Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c
    +  Added makefile.sggcc (SGI IRIX with gcc)
    +
    +Version 1.0.6d [April 7, 2000]
    +  Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO
    +  Added data_length parameter to png_decompress_chunk() function
    +  Revised documentation to remove reference to abandoned png_free_chnk functions
    +  Fixed an error in png_rgb_to_gray_fixed()
    +  Revised example.c, usage of png_destroy_write_struct().
    +  Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file
    +  Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c
    +  Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().
    +
    +Version 1.0.6e [April 9, 2000]
    +  Added png_data_freer() function.
    +  In the code that checks for over-length tRNS chunks, added check of
    +    info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)
    +  Minor revisions of libpng.txt/libpng.3.
    +  Check for existing data and free it if the free_me flag is set, in png_set_*()
    +    and png_handle_*().
    +  Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED
    +    is defined.
    +  Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c
    +    and mentioned the purposes of the two macros in libpng.txt/libpng.3.
    +
    +Version 1.0.6f [April 14, 2000]
    +  Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.
    +  Add checks in png_set_text() for NULL members of the input text structure.
    +  Revised libpng.txt/libpng.3.
    +  Removed superfluous prototype for png_set_iTXt from png.h
    +  Removed "else" from pngread.c, after png_error(), and changed "0" to "length".
    +  Changed several png_errors about malformed ancillary chunks to png_warnings.
    +
    +Version 1.0.6g [April 24, 2000]
    +  Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.
    +  Relocated paragraph about png_set_background() in libpng.3/libpng.txt
    +    and other revisions (Matthias Benckmann)
    +  Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and
    +    png_ptr members to restore binary compatibility with libpng-1.0.5
    +    (breaks compatibility with libpng-1.0.6).
    +
    +Version 1.0.6h [April 24, 2000]
    +  Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds
    +    libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)
    +    This is a temporary change for test purposes.
    +
    +Version 1.0.6i [May 2, 2000]
    +  Rearranged some members at the end of png_info and png_struct, to put
    +    unknown_chunks_num and free_me within the original size of the png_structs
    +    and free_me, png_read_user_fn, and png_free_fn within the original png_info,
    +    because some old applications allocate the structs directly instead of
    +    using png_create_*().
    +  Added documentation of user memory functions in libpng.txt/libpng.3
    +  Modified png_read_png so that it will use user_allocated row_pointers
    +    if present, unless free_me directs that it be freed, and added description
    +    of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.
    +  Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version
    +    1.00) members of png_struct and png_info, to regain binary compatibility
    +    when you define this macro.  Capabilities lost in this event
    +    are user transforms (new in version 1.0.0),the user transform pointer
    +    (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,
    +    the high-level interface, and unknown chunks support (all new in 1.0.6).
    +    This was necessary because of old applications that allocate the structs
    +    directly as authors were instructed to do in libpng-0.88 and earlier,
    +    instead of using png_create_*().
    +  Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which
    +    can be used to detect codes that directly allocate the structs, and
    +    code to check these modes in png_read_init() and png_write_init() and
    +    generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED
    +    was not defined.
    +  Added makefile.intel and updated makefile.watcom (Pawel Mrochen)
    +
    +Version 1.0.6j [May 3, 2000]
    +  Overloaded png_read_init() and png_write_init() with macros that convert
    +    calls to png_read_init_2() or png_write_init_2() that check the version
    +    and structure sizes.
    +
    +Version 1.0.7beta11 [May 7, 2000]
    +  Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
    +    which are no longer used.
    +  Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
    +    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED
    +    is defined.
    +  Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
    +    overrun when old applications fill the info_ptr->text structure directly.
    +  Added PNGAPI macro, and added it to the definitions of all exported functions.
    +  Relocated version macro definitions ahead of the includes of zlib.h and
    +    pngconf.h in png.h.
    +
    +Version 1.0.7beta12 [May 12, 2000]
    +  Revised pngset.c to avoid a problem with expanding the png_debug macro.
    +  Deleted some extraneous defines from pngconf.h
    +  Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.
    +  Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.
    +  Added png_access_version_number() function.
    +  Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().
    +  Expanded libpng.3/libpng.txt information about png_data_freer().
    +
    +Version 1.0.7beta14 [May 17, 2000] (beta13 was not published)
    +  Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as
    +    warnings instead of errors, as pngrutil.c does.
    +  Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()
    +    will actually write IDATs.
    +  Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.
    +  Make png_free_data() ignore its final parameter except when freeing data
    +    that can have multiple instances (text, sPLT, unknowns).
    +  Fixed a new bug in png_set_rows().
    +  Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.
    +  Added png_set_invalid() function.
    +  Fixed incorrect illustrations of png_destroy_write_struct() in example.c.
    +
    +Version 1.0.7beta15 [May 30, 2000]
    +  Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce
    +    fewer error messages.
    +  Rearranged checks for Z_OK to check the most likely path first in pngpread.c
    +    and pngwutil.c.
    +  Added checks in pngtest.c for png_create_*() returning NULL, and mentioned
    +    in libpng.txt/libpng.3 the need for applications to check this.
    +  Changed names of png_default_*() functions in pngtest to pngtest_*().
    +  Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.
    +  Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c
    +  Set each pointer to NULL after freeing it in png_free_data().
    +  Worked around a problem in pngconf.h; AIX's strings.h defines an "index"
    +    macro that conflicts with libpng's png_color_16.index. (Dimitri
    +    Papadapoulos)
    +  Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux).
    +
    +Version 1.0.7beta16 [June 4, 2000]
    +  Revised the workaround of AIX string.h "index" bug.
    +  Added a check for overlength PLTE chunk in pngrutil.c.
    +  Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer
    +    indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.
    +  Added a warning in png_decompress_chunk() when it runs out of data, e.g.
    +    when it tries to read an erroneous PhotoShop iCCP chunk.
    +  Added PNG_USE_DLL macro.
    +  Revised the copyright/disclaimer/license notice.
    +  Added contrib/msvctest directory
    +
    +Version 1.0.7rc1 [June 9, 2000]
    +  Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA  (0x0400 not 0x0200)
    +  Added contrib/visupng directory (Willem van Schaik)
    +
    +Version 1.0.7beta18 [June 23, 2000]
    +  Revised PNGAPI definition, and pngvcrd.c to work with __GCC__
    +    and do not redefine PNGAPI if it is passed in via a compiler directive.
    +  Revised visupng/PngFile.c to remove returns from within the Try block.
    +  Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros.
    +  Updated contrib/visupng/cexcept.h to version 1.0.0.
    +  Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.
    +
    +Version 1.0.7rc2 [June 28, 2000]
    +  Updated license to include disclaimers required by UCITA.
    +  Fixed "DJBPP" typo in pnggccrd.c introduced in beta18.
    +
    +Version 1.0.7 [July 1, 2000]
    +  Revised the definition of "trans_values" in libpng.3/libpng.txt
    +
    +Version 1.0.8beta1 [July 8, 2000]
    +  Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.
    +  Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and
    +    pngwutil.c.
    +  Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.
    +  Removed unused "#include " from png.c
    +  Added WindowsCE support.
    +  Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.
    +
    +Version 1.0.8beta2 [July 10, 2000]
    +  Added project files to the wince directory and made further revisions
    +    of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.
    +
    +Version 1.0.8beta3 [July 11, 2000]
    +  Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()
    +    for indexed-color input files to avoid potential double-freeing trans array
    +    under some unusual conditions; problem was introduced in version 1.0.6f.
    +  Further revisions to pngtest.c and files in the wince subdirectory.
    +
    +Version 1.0.8beta4 [July 14, 2000]
    +  Added the files pngbar.png and pngbar.jpg to the distribution.
    +  Added makefile.cygwin, and cygwin support in pngconf.h
    +  Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)
    +
    +Version 1.0.8rc1 [July 16, 2000]
    +  Revised png_debug() macros and statements to eliminate compiler warnings.
    +
    +Version 1.0.8 [July 24, 2000]
    +  Added png_flush() in pngwrite.c, after png_write_IEND().
    +  Updated makefile.hpux to build a shared library.
    +
    +Version 1.0.9beta1 [November 10, 2000]
    +  Fixed typo in scripts/makefile.hpux
    +  Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
    +  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
    +  Changed "cdrom.com" in documentation to "libpng.org"
    +  Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
    +  Changed type of "params" from voidp to png_voidp in png_read|write_png().
    +  Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
    +  Revised the 3 instances of WRITEFILE in pngtest.c.
    +  Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory.
    +  Updated png.rc in dll/msvc project
    +  Revised makefile.dec to define and use LIBPATH and INCPATH
    +  Increased size of global png_libpng_ver[] array from 12 to 18 chars.
    +  Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
    +  Removed duplicate png_crc_finish() from png_handle_bKGD() function.
    +  Added a warning when application calls png_read_update_info() multiple times.
    +  Revised makefile.cygwin
    +  Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
    +  Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
    +
    +Version 1.0.9beta2 [November 19, 2000]
    +  Renamed the "dll" subdirectory "projects".
    +  Added borland project files to "projects" subdirectory.
    +  Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
    +  Add error message in png_set_compression_buffer_size() when malloc fails.
    +
    +Version 1.0.9beta3 [November 23, 2000]
    +  Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
    +  Removed the png_flush() in pngwrite.c that crashes some applications
    +    that don't set png_output_flush_fn.
    +  Added makefile.macosx and makefile.aix to scripts directory.
    +
    +Version 1.0.9beta4 [December 1, 2000]
    +  Change png_chunk_warning to png_warning in png_check_keyword().
    +  Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
    +
    +Version 1.0.9beta5 [December 15, 2000]
    +  Added support for filter method 64 (for PNG datastreams embedded in MNG).
    +
    +Version 1.0.9beta6 [December 18, 2000]
    +  Revised png_set_filter() to accept filter method 64 when appropriate.
    +  Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
    +    help prevent applications from using MNG features in PNG datastreams.
    +  Added png_permit_mng_features() function.
    +  Revised libpng.3/libpng.txt.  Changed "filter type" to "filter method".
    +
    +Version 1.0.9rc1 [December 23, 2000]
    +  Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c
    +  Fixed error handling of unknown compression type in png_decompress_chunk().
    +  In pngconf.h, define __cdecl when _MSC_VER is defined.
    +
    +Version 1.0.9beta7 [December 28, 2000]
    +  Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
    +  Revised memory management in png_set_hIST and png_handle_hIST in a backward
    +    compatible manner.  PLTE and tRNS were revised similarly.
    +  Revised the iCCP chunk reader to ignore trailing garbage.
    +
    +Version 1.0.9beta8 [January 12, 2001]
    +  Moved pngasmrd.h into pngconf.h.
    +  Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
    +
    +Version 1.0.9beta9 [January 15, 2001]
    +  Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to
    +    wince and msvc project module definition files.
    +  Minor revision of makefile.cygwin.
    +  Fixed bug with progressive reading of narrow interlaced images in pngpread.c
    +
    +Version 1.0.9beta10 [January 16, 2001]
    +  Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.
    +  Fixed "png_mmx_supported" typo in project definition files.
    +
    +Version 1.0.9beta11 [January 19, 2001]
    +  Updated makefile.sgi to make shared library.
    +  Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED
    +    by default, for the benefit of DLL forward compatibility.  These will
    +    be re-enabled in version 1.2.0.
    +
    +Version 1.0.9rc2 [January 22, 2001]
    +  Revised cygwin support.
    +
    +Version 1.0.9 [January 31, 2001]
    +  Added check of cygwin's ALL_STATIC in pngconf.h
    +  Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
    +
    +Version 1.0.10beta1 [March 14, 2001]
    +  Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc.
    +  Reformatted libpng.3 to eliminate bad line breaks.
    +  Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c
    +  Added prototype for png_mmx_support() near the top of pnggccrd.c
    +  Moved some error checking from png_handle_IHDR to png_set_IHDR.
    +  Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros.
    +  Revised png_mmx_support() function in pnggccrd.c
    +  Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c
    +  Fixed memory leak in contrib/visupng/PngFile.c
    +  Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version)
    +  Added warnings when retrieving or setting gamma=0.
    +  Increased the first part of msg buffer from 16 to 18 in png_chunk_warning().
    +
    +Version 1.0.10rc1 [March 23, 2001]
    +  Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy,
    +    and png_strlen.
    +  Revised png_mmx_supported() function in pnggccrd.c to return proper value.
    +  Fixed bug in progressive reading (pngpread.c) with small images (height < 8).
    +
    +Version 1.0.10 [March 30, 2001]
    +  Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin
    +  Added beos project files (Chris Herborth)
    +
    +Version 1.0.11beta1 [April 3, 2001]
    +  Added type casts on several png_malloc() calls (Dimitri Papadapoulos).
    +  Removed a no-longer needed AIX work-around from pngconf.h
    +  Changed several "//" single-line comments to C-style in pnggccrd.c
    +
    +Version 1.0.11beta2 [April 11, 2001]
    +  Removed PNGAPI from several functions whose prototypes did not have PNGAPI.
    +  Updated scripts/pngos2.def
    +
    +Version 1.0.11beta3 [April 14, 2001]
    +  Added checking the results of many instances of png_malloc() for NULL
    +
    +Version 1.0.11beta4 [April 20, 2001]
    +  Undid the changes from version 1.0.11beta3.  Added a check for NULL return
    +    from user's malloc_fn().
    +  Removed some useless type casts of the NULL pointer.
    +  Added makefile.netbsd
    +
    +Version 1.0.11 [April 27, 2001]
    +  Revised makefile.netbsd
    +
    +Version 1.0.12beta1 [May 14, 2001]
    +  Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot)
    +  Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h
    +  Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings.
    +  Eliminated the png_error about apps using png_read|write_init().  Instead,
    +    libpng will reallocate the png_struct and info_struct if they are too small.
    +    This retains future binary compatibility for old applications written for
    +    libpng-0.88 and earlier.
    +
    +Version 1.2.0beta1 [May 6, 2001]
    +  Bumped DLLNUM to 2.
    +  Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED
    +    by default.
    +  Added runtime selection of MMX features.
    +  Added png_set_strip_error_numbers function and related macros.
    +
    +Version 1.2.0beta2 [May 7, 2001]
    +  Finished merging 1.2.0beta1 with version 1.0.11
    +  Added a check for attempts to read or write PLTE in grayscale PNG datastreams.
    +
    +Version 1.2.0beta3 [May 17, 2001]
    +  Enabled user memory function by default.
    +  Modified png_create_struct so it passes user mem_ptr to user memory allocator.
    +  Increased png_mng_features flag from png_byte to png_uint_32.
    +  Bumped shared-library (so-number) and dll-number to 3.
    +
    +Version 1.2.0beta4 [June 23, 2001]
    +  Check for missing profile length field in iCCP chunk and free chunk_data
    +    in case of truncated iCCP chunk.
    +  Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc
    +  Bumped dll-number from 2 to 3 in makefile.cygwin
    +  Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly
    +    if user attempts to run it on an 8-bit display.
    +  Updated contrib/gregbook
    +  Use png_malloc instead of png_zalloc to allocate palette in pngset.c
    +  Updated makefile.ibmc
    +  Added some typecasts to eliminate gcc 3.0 warnings.  Changed prototypes
    +    of png_write_oFFS width and height from png_uint_32 to png_int_32.
    +  Updated example.c
    +  Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c
    +
    +Version 1.2.0beta5 [August 8, 2001]
    +  Revised contrib/gregbook
    +  Revised makefile.gcmmx
    +  Revised pnggccrd.c to conditionally compile some thread-unsafe code only
    +    when PNG_THREAD_UNSAFE_OK is defined.
    +  Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with
    +    value exceeding 2^bit_depth-1
    +  Revised makefile.sgi and makefile.sggcc
    +  Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c
    +  Removed restriction that do_invert_mono only operate on 1-bit opaque files
    +
    +Version 1.2.0 [September 1, 2001]
    +  Changed a png_warning() to png_debug() in pnggccrd.c
    +  Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC().
    +
    +Version 1.2.1beta1 [October 19, 2001]
    +  Revised makefile.std in contrib/pngminus
    +  Include background_1 in png_struct regardless of gamma support.
    +  Revised makefile.netbsd and makefile.macosx, added makefile.darwin.
    +  Revised example.c to provide more details about using row_callback().
    +
    +Version 1.2.1beta2 [October 25, 2001]
    +  Added type cast to each NULL appearing in a function call, except for
    +    WINCE functions.
    +  Added makefile.so9.
    +
    +Version 1.2.1beta3 [October 27, 2001]
    +  Removed type casts from all NULLs.
    +  Simplified png_create_struct_2().
    +
    +Version 1.2.1beta4 [November 7, 2001]
    +  Revised png_create_info_struct() and png_creat_struct_2().
    +  Added error message if png_write_info() was omitted.
    +  Type cast NULLs appearing in function calls when _NO_PROTO or
    +    PNG_TYPECAST_NULL is defined.
    +
    +Version 1.2.1rc1 [November 24, 2001]
    +  Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL
    +    is defined.
    +  Changed typecast of "size" argument to png_size_t in pngmem.c calls to
    +    the user malloc_fn, to agree with the prototype in png.h
    +  Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev)
    +  Updated makefile.sgi to recognize LIBPATH and INCPATH.
    +  Updated various makefiles so "make clean" does not remove previous major
    +    version of the shared library.
    +
    +Version 1.2.1rc2 [December 4, 2001]
    +  Always allocate 256-entry internal palette, hist, and trans arrays, to
    +    avoid out-of-bounds memory reference caused by invalid PNG datastreams.
    +  Added a check for prefix_length > data_length in iCCP chunk handler.
    +
    +Version 1.2.1 [December 7, 2001]
    +  None.
    +
    +Version 1.2.2beta1 [February 22, 2002]
    +  Fixed a bug with reading the length of iCCP profiles (Larry Reeves).
    +  Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate
    +    libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h
    +  Revised makefile.darwin to remove "-undefined suppress" option.
    +  Added checks for gamma and chromaticity values over 21474.83, which exceed
    +    the limit for PNG unsigned 32-bit integers when encoded.
    +  Revised calls to png_create_read_struct() and png_create_write_struct()
    +    for simpler debugging.
    +  Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)
    +
    +Version 1.2.2beta2 [February 23, 2002]
    +  Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.
    +  Check for invalid image dimensions in png_get_IHDR.
    +  Added missing "fi;" in the install target of the SGI makefiles.
    +  Added install-static to all makefiles that make shared libraries.
    +  Always do gamma compensation when image is partially transparent.
    +
    +Version 1.2.2beta3 [March 7, 2002]
    +  Compute background.gray and background_1.gray even when color_type is RGB
    +    in case image gets reduced to gray later.
    +  Modified shared-library makefiles to install pkgconfig/libpngNN.pc.
    +  Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown
    +  Removed unused png_write_destroy_info prototype from png.h
    +  Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case
    +  Added install-shared target to all makefiles that make shared libraries.
    +  Stopped a double free of palette, hist, and trans when not using free_me.
    +  Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64.
    +
    +Version 1.2.2beta4 [March 8, 2002]
    +  Compute background.gray and background_1.gray even when color_type is RGB
    +    in case image gets reduced to gray later (Jason Summers).
    +  Relocated a misplaced /bin/rm in the "install-shared" makefile targets
    +  Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library.
    +
    +Version 1.2.2beta5 [March 26, 2002]
    +  Added missing PNGAPI to several function definitions.
    +  Check for invalid bit_depth or color_type in png_get_IHDR(), and
    +    check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen).
    +  Revised iTXt support to accept NULL for lang and lang_key.
    +  Compute gamma for color components of background even when color_type is gray.
    +  Changed "()" to "{}" in scripts/libpng.pc.in.
    +  Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN
    +  Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so
    +
    +Version 1.2.2beta6 [March 31, 2002]
    +
    +Version 1.0.13beta1 [March 31, 2002]
    +  Prevent png_zalloc() from trying to memset memory that it failed to acquire.
    +  Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate).
    +  Ensure that the right function (user or default) is used to free the
    +    png_struct after an error in png_create_read_struct_2().
    +
    +Version 1.2.2rc1 [April 7, 2002]
    +
    +Version 1.0.13rc1 [April 7, 2002]
    +  Save the ebx register in pnggccrd.c (Sami Farin)
    +  Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner).
    +  Updated makefiles to put headers in include/libpng and remove old include/*.h.
    +
    +Version 1.2.2 [April 15, 2002]
    +
    +Version 1.0.13 [April 15, 2002]
    +  Revised description of png_set_filter() in libpng.3/libpng.txt.
    +  Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd
    +
    +Version 1.0.13patch01 [April 17, 2002]
    +
    +Version 1.2.2patch01 [April 17, 2002]
    +  Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and
    +    makefile.sggcc
    +  Fixed VER -> PNGVER typo in makefile.macosx and added install-static to
    +    install
    +  Added install: target to makefile.32sunu and makefile.64sunu
    +
    +Version 1.0.13patch03 [April 18, 2002]
    +
    +Version 1.2.2patch03 [April 18, 2002]
    +  Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng
    +  subdirectory to libpngNN subdirectory without the full pathname.
    +  Moved generation of libpng.pc from "install" to "all" in 15 makefiles.
    +
    +Version 1.2.3rc1 [April 28, 2002]
    +  Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos).
    +  Added $(DESTDIR) feature to 24 makefiles (Tim Mooney)
    +  Fixed bug with $prefix, should be $(prefix) in makefile.hpux.
    +  Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin
    +  Added a link from libpngNN.pc to libpng.pc in 15 makefiles.
    +  Added links from include/libpngNN/*.h to include/*.h in 24 makefiles.
    +  Revised makefile.darwin to make relative links without full pathname.
    +  Added setjmp() at the end of png_create_*_struct_2() in case user forgets
    +    to put one in their application.
    +  Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and
    +    removed them from module definition files.
    +
    +Version 1.2.3rc2 [May 1, 2002]
    +  Fixed bug in reporting number of channels in pngget.c and pngset.c,
    +    that was introduced in version 1.2.2beta5.
    +  Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(),
    +    png_default_flush(), and png_push_fill_buffer() and included them in
    +    module definition files.
    +  Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles.
    +
    +Version 1.2.3rc3 [May 1, 2002]
    +  Revised prototype for png_default_flush()
    +  Remove old libpng.pc and libpngNN.pc before installing new ones.
    +
    +Version 1.2.3rc4 [May 2, 2002]
    +  Typos in *.def files (png_default_read|write -> png_default_read|write_data)
    +  In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc
    +  Added libpng-config and libpngNN-config and modified makefiles to install
    +    them.
    +  Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles
    +  Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp
    +
    +Version 1.2.3rc5 [May 11, 2002]
    +  Changed "error" and "message" in prototypes to "error_message" and
    +    "warning_message" to avoid namespace conflict.
    +  Revised 15 makefiles to build libpng-config from libpng-config-*.in
    +  Once more restored png_zalloc and png_zfree to regular nonexported form.
    +  Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer
    +    to nonexported form, but with PNGAPI, and removed them from module def
    +    files.
    +
    +Version 1.2.3rc6 [May 14, 2002]
    +  Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c
    +  Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp.
    +  Removed leftover libpng-config "sed" script from four makefiles.
    +  Revised libpng-config creating script in 16 makefiles.
    +
    +Version 1.2.3 [May 22, 2002]
    +  Revised libpng-config target in makefile.cygwin.
    +  Removed description of png_set_mem_fn() from documentation.
    +  Revised makefile.freebsd.
    +  Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR).
    +  Revised projects/msvc/README.txt
    +  Changed -lpng to -lpngNN in LDFLAGS in several makefiles.
    +
    +Version 1.2.4beta1 [May 24, 2002]
    +  Added libpng.pc and libpng-config to "all:" target in 16 makefiles.
    +  Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH)
    +  Added missing "\" before closing double quote in makefile.gcmmx.
    +  Plugged various memory leaks; added png_malloc_warn() and png_set_text_2()
    +    functions.
    +
    +Version 1.2.4beta2 [June 25, 2002]
    +  Plugged memory leak of png_ptr->current_text (Matt Holgate).
    +  Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison)
    +  Added -soname to the loader flags in makefile.dec, makefile.sgi, and
    +    makefile.sggcc.
    +  Added "test-installed" target to makefile.linux, makefile.gcmmx,
    +    makefile.sgi, and makefile.sggcc.
    +
    +Version 1.2.4beta3 [June 28, 2002]
    +  Plugged memory leak of row_buf in pngtest.c when there is a png_error().
    +  Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.
    +  Added "test-installed" target to makefile.32sunu, makefile.64sunu,
    +    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx,
    +    makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.
    +
    +Version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]
    +  Added "test-installed" target to makefile.cygwin and makefile.sco.
    +  Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.
    +
    +Version 1.2.4 and 1.0.14 [July 8, 2002]
    +  Changed png_warning() to png_error() when width is too large to process.
    +
    +Version 1.2.4patch01 [July 20, 2002]
    +  Revised makefile.cygwin to use DLL number 12 instead of 13.
    +
    +Version 1.2.5beta1 [August 6, 2002]
    +  Added code to contrib/gregbook/readpng2.c to ignore unused chunks.
    +  Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)
    +  Removed some stray *.o files from contrib/gregbook.
    +  Changed png_error() to png_warning() about "Too much data" in pngpread.c
    +    and about "Extra compressed data" in pngrutil.c.
    +  Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().
    +  Updated makefile.hpgcc
    +  Updated png.c and pnggccrd.c handling of return from png_mmx_support()
    +
    +Version 1.2.5beta2 [August 15, 2002]
    +  Only issue png_warning() about "Too much data" in pngpread.c when avail_in
    +    is nonzero.
    +  Updated makefiles to install a separate libpng.so.3 with its own rpath.
    +
    +Version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002]
    +  Revised makefiles to not remove previous minor versions of shared libraries.
    +
    +Version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002]
    +  Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared
    +    library loader directive.
    +  Added missing "$OBJSDLL" line to makefile.gcmmx.
    +  Added missing "; fi" to makefile.32sunu.
    +
    +Version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002]
    +  Revised libpng-config script.
    +
    +Version 1.2.5 and 1.0.15 [October 3, 2002]
    +  Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux,
    +    and makefile.aix.
    +  Relocated two misplaced PNGAPI lines in pngtest.c
    +
    +Version 1.2.6beta1 [October 22, 2002]
    +  Commented out warning about uninitialized mmx_support in pnggccrd.c.
    +  Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h.
    +  Relocated two more misplaced PNGAPI lines in pngtest.c
    +  Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams,
    +    introduced in version 1.0.2.
    +  Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu.
    +
    +Version 1.2.6beta2 [November 1, 2002]
    +  Added libpng-config "--ldopts" output.
    +  Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)"
    +    in makefiles.
    +
    +Version 1.2.6beta3 [July 18, 2004]
    +  Reverted makefile changes from version 1.2.6beta2 and some of the changes
    +    from version 1.2.6beta1; these will be postponed until version 1.2.7.
    +    Version 1.2.6 is going to be a simple bugfix release.
    +  Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile.
    +  Fixed potential overrun in pngerror.c by using strncpy instead of memcpy.
    +  Added "#!/bin/sh" at the top of configure, for recognition of the
    +    'x' flag under Cygwin (Cosmin).
    +  Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin).
    +  Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin).
    +  Fixed the special memory handler for Borland C under DOS, in pngmem.c
    +    (Cosmin).
    +  Removed some spurious assignments in pngrutil.c (Cosmin).
    +  Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings
    +    on 16-bit platforms (Cosmin).
    +  Enclosed shift op expressions in parentheses, to silence warnings (Cosmin).
    +  Used proper type png_fixed_point, to avoid problems on 16-bit platforms,
    +    in png_handle_sRGB() (Cosmin).
    +  Added compression_type to png_struct, and optimized the window size
    +    inside the deflate stream (Cosmin).
    +  Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin).
    +  Fixed handling of unknown chunks that come after IDAT (Cosmin).
    +  Allowed png_error() and png_warning() to work even if png_ptr == NULL
    +    (Cosmin).
    +  Replaced row_info->rowbytes with row_bytes in png_write_find_filter()
    +    (Cosmin).
    +  Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre).
    +  Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded
    +    values in png.c (Simon-Pierre, Cosmin).
    +  Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre).
    +  Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc
    +    (Simon-Pierre).
    +  Moved the definition of PNG_HEADER_VERSION_STRING near the definitions
    +    of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin).
    +  Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin).
    +  Updated scripts/makefile.vc(a)win32 (Cosmin).
    +  Updated the MSVC project (Simon-Pierre, Cosmin).
    +  Updated the Borland C++ Builder project (Cosmin).
    +  Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin).
    +  Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin).
    +  Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin).
    +  Added extra guard around inclusion of Turbo C memory headers, in pngconf.h
    +    (Cosmin).
    +  Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to
    +    projects/cbuilder5/ (Cosmin).
    +  Moved projects/visualc6/png32ms.def to scripts/pngw32.def,
    +    and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin).
    +  Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin).
    +  Changed line endings to DOS style in cbuilder5 and visualc6 files, even
    +    in the tar.* distributions (Cosmin).
    +  Updated contrib/visupng/VisualPng.dsp (Cosmin).
    +  Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin).
    +  Added a separate distribution with "configure" and supporting files (Junichi).
    +
    +Version 1.2.6beta4 [July 28, 2004]
    +  Added user ability to change png_size_t via a PNG_SIZE_T macro.
    +  Added png_sizeof() and png_convert_size() functions.
    +  Added PNG_SIZE_MAX (maximum value of a png_size_t variable.
    +  Added check in png_malloc_default() for (size_t)size != (png_uint_32)size
    +    which would indicate an overflow.
    +  Changed sPLT failure action from png_error to png_warning and abandon chunk.
    +  Changed sCAL and iCCP failures from png_error to png_warning and abandon.
    +  Added png_get_uint_31(png_ptr, buf) function.
    +  Added PNG_UINT_32_MAX macro.
    +  Renamed PNG_MAX_UINT to PNG_UINT_31_MAX.
    +  Made png_zalloc() issue a png_warning and return NULL on potential
    +    overflow.
    +  Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x
    +  Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4.
    +  Revised Borland portion of png_malloc() to return NULL or issue
    +    png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK.
    +  Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove
    +    sequential read support.
    +  Added some "#if PNG_WRITE_SUPPORTED" blocks.
    +  Added #ifdef to remove some redundancy in png_malloc_default().
    +  Use png_malloc instead of png_zalloc to allocate the palette.
    +
    +Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]
    +  Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS().
    +  Fixed NULL dereference vulnerability (CVE-2004-0598) in png_handle_iCCP().
    +  Fixed integer overflow vulnerability (CVE-2004-0599) in png_read_png().
    +  Fixed some harmless bugs in png_handle_sBIT, etc, that would cause
    +    duplicate chunk types to go undetected.
    +  Fixed some timestamps in the -config version
    +  Rearranged order of processing of color types in png_handle_tRNS().
    +  Added ROWBYTES macro to calculate rowbytes without integer overflow.
    +  Updated makefile.darwin and removed makefile.macosx from scripts directory.
    +  Imposed default one million column, one-million row limits on the image
    +    dimensions, and added png_set_user_limits() function to override them.
    +  Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro.
    +  Fixed wrong cast of returns from png_get_user_width|height_max().
    +  Changed some "keep the compiler happy" from empty statements to returns,
    +  Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution
    +
    +Version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004]
    +  Revised makefile.darwin and makefile.solaris.  Removed makefile.macosx.
    +  Revised pngtest's png_debug_malloc() to use png_malloc() instead of
    +    png_malloc_default() which is not supposed to be exported.
    +  Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in
    +    pngpread.c.  Bug was introduced in 1.2.6rc1.
    +  Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1.
    +  Fixed old bug in RGB to Gray transformation.
    +  Fixed problem with 64-bit compilers by casting arguments to abs()
    +    to png_int_32.
    +  Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9).
    +  Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin)
    +  Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles.
    +  Added code to update the row_info->colortype in png_do_read_filler() (MSB).
    +
    +Version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004]
    +  Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid
    +    trouble with some 64-bit compilers.  Created PNG_OUT_OF_RANGE() macro.
    +  Revised documentation of png_set_keep_unknown_chunks().
    +  Check handle_as_unknown status in pngpread.c, as in pngread.c previously.
    +  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h
    +  Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c
    +
    +Version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004]
    +  Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of
    +    "pinfo" was out of place).
    +
    +Version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004]
    +  Moved  "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED
    +    section of png.h where they were inadvertently placed in version rc3.
    +
    +Version 1.2.6 and 1.0.16 [August 15, 2004]
    +  Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1.
    +
    +Version 1.2.7beta1 [August 26, 2004]
    +  Removed unused pngasmrd.h file.
    +  Removed references to uu.net for archived files.  Added references to
    +    PNG Spec (second edition) and the PNG ISO/IEC Standard.
    +  Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR.
    +  Fixed bug with "optimized window size" in the IDAT datastream, that
    +    causes libpng to write PNG files with incorrect zlib header bytes.
    +
    +Version 1.2.7beta2 [August 28, 2004]
    +  Fixed bug with sCAL chunk and big-endian machines (David Munro).
    +  Undid new code added in 1.2.6rc2 to update the color_type in
    +    png_set_filler().
    +  Added png_set_add_alpha() that updates color type.
    +
    +Version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004]
    +  Revised png_set_strip_filler() to not remove alpha if color_type has alpha.
    +
    +Version 1.2.7 and 1.0.17 [September 12, 2004]
    +  Added makefile.hp64
    +  Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin
    +
    +Version 1.2.8beta1 [November 1, 2004]
    +  Fixed bug in png_text_compress() that would fail to complete a large block.
    +  Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during
    +    strip alpha operation in png_do_strip_filler().
    +  Added PNG_1_2_X definition in pngconf.h
    +  Use #ifdef to comment out png_info_init in png.c and png_read_init in
    +    pngread.c (as of 1.3.0)
    +
    +Version 1.2.8beta2 [November 2, 2004]
    +  Reduce color_type to a nonalpha type after strip alpha operation in
    +    png_do_strip_filler().
    +
    +Version 1.2.8beta3 [November 3, 2004]
    +  Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM
    +
    +Version 1.2.8beta4 [November 12, 2004]
    +  Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin).
    +  Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin).
    +  Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection
    +    of data type in deflate (Cosmin).
    +  Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of
    +    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.
    +
    +Version 1.2.8beta5 [November 20, 2004]
    +  Use png_ptr->flags instead of png_ptr->transformations to pass
    +    PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI
    +    compatibility.
    +  Revised handling of SPECIALBUILD, PRIVATEBUILD,
    +    PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING.
    +
    +Version 1.2.8rc1 [November 24, 2004]
    +  Moved handling of BUILD macros from pngconf.h to png.h
    +  Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently
    +    omitted from beta5.
    +  Revised scripts/pngw32.rc
    +  Despammed mailing addresses by masking "@" with "at".
    +  Inadvertently installed a supposedly faster test version of pngrutil.c
    +
    +Version 1.2.8rc2 [November 26, 2004]
    +  Added two missing "\" in png.h
    +  Change tests in pngread.c and pngpread.c to
    +    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
    +       png_do_read_transformations(png_ptr);
    +
    +Version 1.2.8rc3 [November 28, 2004]
    +  Reverted pngrutil.c to version libpng-1.2.8beta5.
    +  Added scripts/makefile.elf with supporting code in pngconf.h for symbol
    +    versioning (John Bowler).
    +
    +Version 1.2.8rc4 [November 29, 2004]
    +  Added projects/visualc7 (Simon-pierre).
    +
    +Version 1.2.8rc5 [November 29, 2004]
    +  Fixed new typo in scripts/pngw32.rc
    +
    +Version 1.2.8 [December 3, 2004]
    +  Removed projects/visualc7, added projects/visualc71.
    +
    +Version 1.2.9beta1 [February 21, 2006]
    +  Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints
    +  Revised man page and libpng.txt to make it clear that one should not call
    +    png_read_end or png_write_end after png_read_png or png_write_png.
    +  Updated references to png-mng-implement mailing list.
    +  Fixed an incorrect typecast in pngrutil.c
    +  Added PNG_NO_READ_SUPPORTED conditional for making a write-only library.
    +  Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional.
    +  Optimized alpha-inversion loops in pngwtran.c
    +  Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c
    +  Make sure num_trans is <= 256 before copying data in png_set_tRNS().
    +  Make sure num_palette is <= 256 before copying data in png_set_PLTE().
    +  Interchanged order of write_swap_alpha and write_invert_alpha transforms.
    +  Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin).
    +  Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin).
    +  Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin).
    +  Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16,
    +    png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin).
    +  Added type cast (png_byte) in png_write_sCAL() (Cosmin).
    +  Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin).
    +  Default iTXt support was inadvertently enabled.
    +
    +Version 1.2.9beta2 [February 21, 2006]
    +  Check for png_rgb_to_gray and png_gray_to_rgb read transformations before
    +    checking for png_read_dither in pngrtran.c
    +  Revised checking of chromaticity limits to accommodate extended RGB
    +    colorspace (John Denker).
    +  Changed line endings in some of the project files to CRLF, even in the
    +    "Unix" tar distributions (Cosmin).
    +  Made png_get_int_32 and png_save_int_32 always available (Cosmin).
    +  Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def
    +    with the newly exported functions.
    +  Eliminated distributions without the "configure" script.
    +  Updated INSTALL instructions.
    +
    +Version 1.2.9beta3 [February 24, 2006]
    +  Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp
    +  Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler)
    +  Removed reference to pngasmrd.h from Makefile.am
    +  Renamed CHANGES to ChangeLog.
    +  Renamed LICENSE to COPYING.
    +  Renamed ANNOUNCE to NEWS.
    +  Created AUTHORS file.
    +
    +Version 1.2.9beta4 [March 3, 2006]
    +  Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac
    +  Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING.
    +  Removed newline from the end of some error and warning messages.
    +  Removed test for sqrt() from configure.ac and configure.
    +  Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix).
    +  Disabled default iTXt support that was inadvertently enabled in
    +    libpng-1.2.9beta1.
    +  Added "OS2" to list of systems that don't need underscores, in pnggccrd.c
    +  Removed libpng version and date from *.c files.
    +
    +Version 1.2.9beta5 [March 4, 2006]
    +  Removed trailing blanks from source files.
    +  Put version and date of latest change in each source file, and changed
    +    copyright year accordingly.
    +  More cleanup of configure.ac, Makefile.am, and associated scripts.
    +  Restored scripts/makefile.elf which was inadvertently deleted.
    +
    +Version 1.2.9beta6 [March 6, 2006]
    +  Fixed typo (RELEASE) in configuration files.
    +
    +Version 1.2.9beta7 [March 7, 2006]
    +  Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am
    +  Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s()
    +    in png.h.
    +  Updated makefile.elf as suggested by debian.
    +  Made cosmetic changes to some makefiles, adding LN_SF and other macros.
    +  Made some makefiles accept "exec_prefix".
    +
    +Version 1.2.9beta8 [March 9, 2006]
    +  Fixed some "#if defined (..." which should be "#if defined(..."
    +    Bug introduced in libpng-1.2.8.
    +  Fixed inconsistency in definition of png_default_read_data()
    +  Restored blank that was lost from makefile.sggcc "clean" target in beta7.
    +  Revised calculation of "current" and "major" for irix in ltmain.sh
    +  Changed "mkdir" to "MKDIR_P" in some makefiles.
    +  Separated PNG_EXPAND and PNG_EXPAND_tRNS.
    +  Added png_set_expand_gray_1_2_4_to_8() and deprecated
    +    png_set_gray_1_2_4_to_8() which also expands tRNS to alpha.
    +
    +Version 1.2.9beta9 [March 10, 2006]
    +  Include "config.h" in pngconf.h when available.
    +  Added some checks for NULL png_ptr or NULL info_ptr (timeless)
    +
    +Version 1.2.9beta10 [March 20, 2006]
    +  Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin)
    +  Made pnggccrd.c PIC-compliant (Christian Aichinger).
    +  Added makefile.mingw (Wolfgang Glas).
    +  Revised pngconf.h MMX checking.
    +
    +Version 1.2.9beta11 [March 22, 2006]
    +  Fixed out-of-order declaration in pngwrite.c that was introduced in beta9
    +  Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros.
    +
    +Version 1.2.9rc1 [March 31, 2006]
    +  Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin).
    +  Removed nonsensical assertion check from pngtest.c (Cosmin).
    +
    +Version 1.2.9 [April 14, 2006]
    +  Revised makefile.beos and added "none" selector in ltmain.sh
    +
    +Version 1.2.10beta1 [April 15, 2006]
    +  Renamed "config.h" to "png_conf.h" and revised Makefile.am to add
    +    -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h
    +    to include png_conf.h only when PNG_BUILDING_LIBPNG is defined.
    +
    +Version 1.2.10beta2 [April 15, 2006]
    +  Manually updated Makefile.in and configure.  Changed png_conf.h.in
    +    back to config.h.
    +
    +Version 1.2.10beta3 [April 15, 2006]
    +  Change png_conf.h back to config.h in pngconf.h.
    +
    +Version 1.2.10beta4 [April 16, 2006]
    +  Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*.
    +
    +Version 1.2.10beta5 [April 16, 2006]
    +  Added a configure check for compiling assembler code in pnggccrd.c
    +
    +Version 1.2.10beta6 [April 17, 2006]
    +  Revised the configure check for pnggccrd.c
    +  Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@
    +  Added @LIBPNG_DEFINES@ to arguments when building libpng.sym
    +
    +Version 1.2.10beta7 [April 18, 2006]
    +  Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles.
    +
    +Version 1.2.10rc1 [April 19, 2006]
    +  Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD
    +  Fixed "LN_FS" typo in makefile.sco and makefile.solaris.
    +
    +Version 1.2.10rc2 [April 20, 2006]
    +  Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE
    +   in configure.ac and configure
    +  Made the configure warning about versioned symbols less arrogant.
    +
    +Version 1.2.10rc3 [April 21, 2006]
    +  Added a note in libpng.txt that png_set_sig_bytes(8) can be used when
    +    writing an embedded PNG without the 8-byte signature.
    +  Revised makefiles and configure to avoid making links to libpng.so.*
    +
    +Version 1.2.10 [April 23, 2006]
    +  Reverted configure to "rc2" state.
    +
    +Version 1.2.11beta1 [May 31, 2006]
    +  scripts/libpng.pc.in contained "configure" style version info and would
    +    not work with makefiles.
    +  The shared-library makefiles were linking to libpng.so.0 instead of
    +    libpng.so.3 compatibility as the library.
    +
    +Version 1.2.11beta2 [June 2, 2006]
    +  Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid
    +    buffer overflow.
    +  Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb)
    +
    +Version 1.2.11beta3 [June 5, 2006]
    +  Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin).
    +  Removed the accidental leftover Makefile.in~ (Cosmin).
    +  Avoided potential buffer overflow and optimized buffer in
    +    png_write_sCAL(), png_write_sCAL_s() (Cosmin).
    +  Removed the include directories and libraries from CFLAGS and LDFLAGS
    +    in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin).
    +
    +Version 1.2.11beta4 [June 6, 2006]
    +  Allow zero-length IDAT chunks after the entire zlib datastream, but not
    +    after another intervening chunk type.
    +
    +Version 1.0.19rc1, 1.2.11rc1 [June 13, 2006]
    +  Deleted extraneous square brackets from [config.h] in configure.ac
    +
    +Version 1.0.19rc2, 1.2.11rc2 [June 14, 2006]
    +  Added prototypes for PNG_INCH_CONVERSIONS functions to png.h
    +  Revised INSTALL and autogen.sh
    +  Fixed typo in several makefiles (-W1 should be -Wl)
    +  Added typedef for png_int_32 and png_uint_32 on 64-bit systems.
    +
    +Version 1.0.19rc3, 1.2.11rc3 [June 15, 2006]
    +  Removed the new typedefs for 64-bit systems (delay until version 1.4.0)
    +  Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid
    +    reading out of bounds.
    +
    +Version 1.0.19rc4, 1.2.11rc4 [June 15, 2006]
    +  Really removed the new typedefs for 64-bit systems.
    +
    +Version 1.0.19rc5, 1.2.11rc5 [June 22, 2006]
    +  Removed png_sig_bytes entry from scripts/pngw32.def
    +
    +Version 1.0.19, 1.2.11 [June 26, 2006]
    +  None.
    +
    +Version 1.0.20, 1.2.12 [June 27, 2006]
    +  Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid
    +    buffer overflow.
    +
    +Version 1.2.13beta1 [October 2, 2006]
    +  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 (CVE-2006-7244)
    +
    +Version 1.0.21, 1.2.13 [November 14, 2006]
    +  Fix potential buffer overflow in sPLT chunk handler.
    +  Fix Makefile.am to not try to link to noexistent files.
    +  Check all exported functions for NULL png_ptr.
    +
    +Version 1.2.14beta1 [November 17, 2006]
    +  Relocated three misplaced tests for NULL png_ptr.
    +  Built Makefile.in with automake-1.9.6 instead of 1.9.2.
    +  Build configure with autoconf-2.60 instead of 2.59
    +
    +Version 1.2.14beta2 [November 17, 2006]
    +  Added some typecasts in png_zalloc().
    +
    +Version 1.2.14rc1 [November 20, 2006]
    +  Changed "strtod" to "png_strtod" in pngrutil.c
    +
    +Version 1.0.22, 1.2.14    [November 27, 2006]
    +  Added missing "$(srcdir)" in Makefile.am and Makefile.in
    +
    +Version 1.2.15beta1 [December 3, 2006]
    +  Generated configure with autoconf-2.61 instead of 2.60
    +  Revised configure.ac to update libpng.pc and libpng-config.
    +
    +Version 1.2.15beta2 [December 3, 2006]
    +  Always export MMX asm functions, just stubs if not building pnggccrd.c
    +
    +Version 1.2.15beta3 [December 4, 2006]
    +  Add "png_bytep" typecast to profile while calculating length in pngwutil.c
    +
    +Version 1.2.15beta4 [December 7, 2006]
    +  Added scripts/CMakeLists.txt
    +  Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta
    +
    +Version 1.2.15beta5 [December 7, 2006]
    +  Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c
    +  Revised scripts/CMakeLists.txt
    +
    +Version 1.2.15beta6 [December 13, 2006]
    +  Revised scripts/CMakeLists.txt and configure.ac
    +
    +Version 1.2.15rc1 [December 18, 2006]
    +  Revised scripts/CMakeLists.txt
    +
    +Version 1.2.15rc2 [December 21, 2006]
    +  Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers.
    +  Added scripts/makefile.nommx
    +
    +Version 1.2.15rc3 [December 25, 2006]
    +  Fixed shared library numbering error that was introduced in 1.2.15beta6.
    +
    +Version 1.2.15rc4 [December 27, 2006]
    +  Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set.
    +
    +Version 1.2.15rc5 [December 31, 2006]
    +  Revised handling of rgb_to_gray.
    +
    +Version 1.2.15 [January 5, 2007]
    +  Added some (unsigned long) typecasts in pngtest.c to avoid printing errors.
    +
    +Version 1.2.16beta1 [January 6, 2007]
    +  Fix bugs in makefile.nommx
    +
    +Version 1.2.16beta2 [January 16, 2007]
    +  Revised scripts/CMakeLists.txt
    +
    +Version 1.2.16 [January 31, 2007]
    +  No changes.
    +
    +Version 1.2.17beta1 [March 6, 2007]
    +  Revised scripts/CMakeLists.txt to install both shared and static libraries.
    +  Deleted a redundant line from pngset.c.
    +
    +Version 1.2.17beta2 [April 26, 2007]
    +  Relocated misplaced test for png_ptr == NULL in pngpread.c
    +  Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN
    +    flags.
    +  Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_*
    +  Added pngerror() when write_IHDR fails in deflateInit2().
    +  Added "const" to some array declarations.
    +  Mention examples of libpng usage in the libpng*.txt and libpng.3 documents.
    +
    +Version 1.2.17rc1 [May 4, 2007]
    +  No changes.
    +
    +Version 1.2.17rc2 [May 8, 2007]
    +  Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications
    +    calling set_unknown_chunk_location() need them.
    +  Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in
    +    png_set_expand_gray_1_2_4_to_8().
    +  Added png_ptr->unknown_chunk to hold working unknown chunk data, so it
    +    can be free'ed in case of error.  Revised unknown chunk handling in
    +    pngrutil.c and pngpread.c to use this structure.
    +
    +Version 1.2.17rc3 [May 8, 2007]
    +  Revised symbol-handling in configure script.
    +
    +Version 1.2.17rc4 [May 10, 2007]
    +  Revised unknown chunk handling to avoid storing unknown critical chunks.
    +
    +Version 1.0.25 [May 15, 2007]
    +Version 1.2.17 [May 15, 2007]
    +  Added "png_ptr->num_trans=0" before error return in png_handle_tRNS,
    +    to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664)
    +
    +Version 1.0.26 [May 15, 2007]
    +Version 1.2.18 [May 15, 2007]
    +  Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script
    +
    +Version 1.2.19beta1 [May 18, 2007]
    +  Changed "const static" to "static PNG_CONST" everywhere, mostly undoing
    +    change of libpng-1.2.17beta2.  Changed other "const" to "PNG_CONST"
    +  Changed some handling of unused parameters, to avoid compiler warnings.
    +    "if (unused == NULL) return;" becomes "unused = unused".
    +
    +Version 1.2.19beta2 [May 18, 2007]
    +  Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier)
    +
    +Version 1.2.19beta3 [May 19, 2007]
    +  Add some "png_byte" typecasts in png_check_keyword() and write new_key
    +  instead of key in zTXt chunk (Kevin Ryde).
    +
    +Version 1.2.19beta4 [May 21, 2007]
    +  Add png_snprintf() function and use it in place of sprint() for improved
    +    defense against buffer overflows.
    +
    +Version 1.2.19beta5 [May 21, 2007]
    +  Fixed png_handle_tRNS() to only use the valid bits of tRNS value.
    +  Changed handling of more unused parameters, to avoid compiler warnings.
    +  Removed some PNG_CONST in pngwutil.c to avoid compiler warnings.
    +
    +Version 1.2.19beta6 [May 22, 2007]
    +  Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c
    +  Added a special "_MSC_VER" case that defines png_snprintf to _snprintf
    +
    +Version 1.2.19beta7 [May 22, 2007]
    +  Squelched png_squelch_warnings() in pnggccrd.c and added
    +    an #ifdef PNG_MMX_CODE_SUPPORTED block around the declarations that caused
    +    the warnings that png_squelch_warnings was squelching.
    +
    +Version 1.2.19beta8 [May 22, 2007]
    +  Removed __MMX__ from test in pngconf.h.
    +
    +Version 1.2.19beta9 [May 23, 2007]
    +  Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro.
    +  Revised png_squelch_warnings() so it might work.
    +  Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86.
    +
    +Version 1.2.19beta10 [May 24, 2007]
    +  Resquelched png_squelch_warnings(), use "__attribute__((used))" instead.
    +
    +Version 1.4.0beta1 [April 20, 2006]
    +  Enabled iTXt support (changes png_struct, thus requires so-number change).
    +  Cleaned up PNG_ASSEMBLER_CODE_SUPPORTED vs PNG_MMX_CODE_SUPPORTED
    +  Eliminated PNG_1_0_X and PNG_1_2_X macros.
    +  Removed deprecated functions png_read_init, png_write_init, png_info_init,
    +    png_permit_empty_plte, png_set_gray_1_2_4_to_8, png_check_sig, and
    +    removed the deprecated macro PNG_MAX_UINT.
    +  Moved "PNG_INTERNAL" parts of png.h and pngconf.h into pngintrn.h
    +  Removed many WIN32_WCE #ifdefs (Cosmin).
    +  Reduced dependency on C-runtime library when on Windows (Simon-Pierre)
    +  Replaced sprintf() with png_sprintf() (Simon-Pierre)
    +
    +Version 1.4.0beta2 [April 20, 2006]
    +  Revised makefiles and configure to avoid making links to libpng.so.*
    +  Moved some leftover MMX-related defines from pngconf.h to pngintrn.h
    +  Updated scripts/pngos2.def, pngw32.def, and projects/wince/png32ce.def
    +
    +Version 1.4.0beta3 [May 10, 2006]
    +  Updated scripts/pngw32.def to comment out MMX functions.
    +  Added PNG_NO_GET_INT_32 and PNG_NO_SAVE_INT_32 macros.
    +  Scripts/libpng.pc.in contained "configure" style version info and would
    +    not work with makefiles.
    +  Revised pngconf.h and added pngconf.h.in, so makefiles and configure can
    +    pass defines to libpng and applications.
    +
    +Version 1.4.0beta4 [May 11, 2006]
    +  Revised configure.ac, Makefile.am, and many of the makefiles to write
    +    their defines in pngconf.h.
    +
    +Version 1.4.0beta5 [May 15, 2006]
    +  Added a missing semicolon in Makefile.am and Makefile.in
    +  Deleted extraneous square brackets from configure.ac
    +
    +Version 1.4.0beta6 [June 2, 2006]
    +  Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid
    +    buffer overflow.
    +  Changed sonum from 0 to 1.
    +  Removed unused prototype for png_check_sig() from png.h
    +
    +Version 1.4.0beta7 [June 16, 2006]
    +  Exported png_write_sig (Cosmin).
    +  Optimized buffer in png_handle_cHRM() (Cosmin).
    +  Set pHYs = 2835 x 2835 pixels per meter, and added
    +    sCAL = 0.352778e-3 x 0.352778e-3 meters, in pngtest.png (Cosmin).
    +  Added png_set_benign_errors(), png_benign_error(), png_chunk_benign_error().
    +  Added typedef for png_int_32 and png_uint_32 on 64-bit systems.
    +  Added "(unsigned long)" typecast on png_uint_32 variables in printf lists.
    +
    +Version 1.4.0beta8 [June 22, 2006]
    +  Added demonstration of user chunk support in pngtest.c, to support the
    +    public sTER chunk and a private vpAg chunk.
    +
    +Version 1.4.0beta9 [July 3, 2006]
    +  Removed ordinals from scripts/pngw32.def and removed png_info_int and
    +    png_set_gray_1_2_4_to_8 entries.
    +  Inline call of png_get_uint_32() in png_get_uint_31().
    +  Use png_get_uint_31() to get vpAg width and height in pngtest.c
    +  Removed WINCE and Netware projects.
    +  Removed standalone Y2KINFO file.
    +
    +Version 1.4.0beta10 [July 12, 2006]
    +  Eliminated automatic copy of pngconf.h to pngconf.h.in from configure and
    +    some makefiles, because it was not working reliably.  Instead, distribute
    +    pngconf.h.in along with pngconf.h and cause configure and some of the
    +    makefiles to update pngconf.h from pngconf.h.in.
    +  Added pngconf.h to DEPENDENCIES in Makefile.am
    +
    +Version 1.4.0beta11 [August 19, 2006]
    +  Removed AC_FUNC_MALLOC from configure.ac.
    +  Added a warning when writing iCCP profile with mismatched profile length.
    +  Patched pnggccrd.c to assemble on x86_64 platforms.
    +  Moved chunk header reading into a separate function png_read_chunk_header()
    +    in pngrutil.c.  The chunk header (len+sig) is now serialized in a single
    +    operation (Cosmin).
    +  Implemented support for I/O states. Added png_ptr member io_state, and
    +    functions png_get_io_chunk_name() and png_get_io_state() in pngget.c
    +    (Cosmin).
    +  Added png_get_io_chunk_name and png_get_io_state to scripts/*.def (Cosmin).
    +  Renamed scripts/pngw32.* to scripts/pngwin.* (Cosmin).
    +  Removed the include directories and libraries from CFLAGS and LDFLAGS
    +    in scripts/makefile.gcc (Cosmin).
    +  Used png_save_uint_32() to set vpAg width and height in pngtest.c (Cosmin).
    +  Cast to proper type when getting/setting vpAg units in pngtest.c (Cosmin).
    +  Added pngintrn.h to the Visual C++ projects (Cosmin).
    +  Removed scripts/list (Cosmin).
    +  Updated copyright year in scripts/pngwin.def (Cosmin).
    +  Removed PNG_TYPECAST_NULL and used standard NULL consistently (Cosmin).
    +  Disallowed the user to redefine png_size_t, and enforced a consistent use
    +    of png_size_t across libpng (Cosmin).
    +  Changed the type of png_ptr->rowbytes, PNG_ROWBYTES() and friends
    +    to png_size_t (Cosmin).
    +  Removed png_convert_size() and replaced png_sizeof with sizeof (Cosmin).
    +  Removed some unnecessary type casts (Cosmin).
    +  Changed prototype of png_get_compression_buffer_size() and
    +    png_set_compression_buffer_size() to work with png_size_t instead of
    +    png_uint_32 (Cosmin).
    +  Removed png_memcpy_check() and png_memset_check() (Cosmin).
    +  Fixed a typo (png_byte --> png_bytep) in libpng.3 and libpng.txt (Cosmin).
    +  Clarified that png_zalloc() does not clear the allocated memory,
    +    and png_zalloc() and png_zfree() cannot be PNGAPI (Cosmin).
    +  Renamed png_mem_size_t to png_alloc_size_t, fixed its definition in
    +    pngconf.h, and used it in all memory allocation functions (Cosmin).
    +  Renamed pngintrn.h to pngpriv.h, added a comment at the top of the file
    +    mentioning that the symbols declared in that file are private, and
    +    updated the scripts and the Visual C++ projects accordingly (Cosmin).
    +  Removed circular references between pngconf.h and pngconf.h.in in
    +    scripts/makefile.vc*win32 (Cosmin).
    +  Removing trailing '.' from the warning and error messages (Cosmin).
    +  Added pngdefs.h that is built by makefile or configure, instead of
    +    pngconf.h.in (Glenn).
    +  Detect and fix attempt to write wrong iCCP profile length.
    +
    +Version 1.4.0beta12 [October 19, 2006]
    +  Changed "logical" to "bitwise" in the documentation.
    +  Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h
    +  Add a typecast to stifle compiler warning in pngrutil.c
    +
    +Version 1.4.0beta13 [November 10, 2006]
    +  Fix potential buffer overflow in sPLT chunk handler.
    +  Fix Makefile.am to not try to link to noexistent files.
    +
    +Version 1.4.0beta14 [November 15, 2006]
    +  Check all exported functions for NULL png_ptr.
    +
    +Version 1.4.0beta15 [November 17, 2006]
    +  Relocated two misplaced tests for NULL png_ptr.
    +  Built Makefile.in with automake-1.9.6 instead of 1.9.2.
    +  Build configure with autoconf-2.60 instead of 2.59
    +  Add "install: all" in Makefile.am so "configure; make install" will work.
    +
    +Version 1.4.0beta16 [November 17, 2006]
    +  Added a typecast in png_zalloc().
    +
    +Version 1.4.0beta17 [December 4, 2006]
    +  Changed "new_key[79] = '\0';" to "(*new_key)[79] = '\0';" in pngwutil.c
    +  Add "png_bytep" typecast to profile while calculating length in pngwutil.c
    +
    +Version 1.4.0beta18 [December 7, 2006]
    +  Added scripts/CMakeLists.txt
    +
    +Version 1.4.0beta19 [May 16, 2007]
    +  Revised scripts/CMakeLists.txt
    +  Rebuilt configure and Makefile.in with newer tools.
    +  Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers.
    +  Added scripts/makefile.nommx
    +
    +Version 1.4.0beta20 [July 9, 2008]
    +  Moved several PNG_HAVE_* macros from pngpriv.h to png.h because applications
    +    calling set_unknown_chunk_location() need them.
    +  Moved several macro definitions from pngpriv.h to pngconf.h
    +  Merge with changes to the 1.2.X branch, as of 1.2.30beta04.
    +  Deleted all use of the MMX assembler code and Intel-licensed optimizations.
    +  Revised makefile.mingw
    +
    +Version 1.4.0beta21 [July 21, 2008]
    +  Moved local array "chunkdata" from pngrutil.c to the png_struct, so
    +    it will be freed by png_read_destroy() in case of a read error (Kurt
    +    Christensen).
    +
    +Version 1.4.0beta22 [July 21, 2008]
    +  Change "purpose" and "buffer" to png_ptr->chunkdata to avoid memory leaking.
    +
    +Version 1.4.0beta23 [July 22, 2008]
    +  Change "chunkdata = NULL" to "png_ptr->chunkdata = NULL" several places in
    +    png_decompress_chunk().
    +
    +Version 1.4.0beta24 [July 25, 2008]
    +  Change all remaining "chunkdata" to "png_ptr->chunkdata" in
    +    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.
    +  Define PNG_NO_ERROR_NUMBERS by default in pngconf.h
    +
    +Version 1.4.0beta25 [July 30, 2008]
    +  Added a call to png_check_chunk_name() in pngpread.c
    +  Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte.
    +  Added png_push_have_buffer() function to pngpread.c
    +  Eliminated PNG_BIG_ENDIAN_SUPPORTED and associated png_get_* macros.
    +  Made inline expansion of png_get_*() optional with PNG_USE_READ_MACROS.
    +  Eliminated all PNG_USELESS_TESTS and PNG_CORRECT_PALETTE_SUPPORTED code.
    +  Synced contrib directory and configure files with libpng-1.2.30beta06.
    +  Eliminated no-longer-used pngdefs.h (but it's still built in the makefiles)
    +  Relocated a misplaced "#endif /* PNG_NO_WRITE_FILTER */" in pngwutil.c
    +
    +Version 1.4.0beta26 [August 4, 2008]
    +  Removed png_push_have_buffer() function in pngpread.c.  It increased the
    +    compiled library size slightly.
    +  Changed "-Wall" to "-W -Wall" in the CFLAGS in all makefiles (Cosmin Truta)
    +  Declared png_ptr "volatile" in pngread.c and pngwrite.c to avoid warnings.
    +  Updated contrib/visupng/cexcept.h to version 2.0.1
    +  Added PNG_LITERAL_CHARACTER macros for #, [, and ].
    +
    +Version 1.4.0beta27 [August 5, 2008]
    +  Revised usage of PNG_LITERAL_SHARP in pngerror.c.
    +  Moved newline character from individual png_debug messages into the
    +    png_debug macros.
    +  Allow user to #define their own png_debug, png_debug1, and png_debug2.
    +
    +Version 1.4.0beta28 [August 5, 2008]
    +  Revised usage of PNG_LITERAL_SHARP in pngerror.c.
    +  Added PNG_STRING_NEWLINE macro
    +
    +Version 1.4.0beta29 [August 9, 2008]
    +  Revised usage of PNG_STRING_NEWLINE to work on non-ISO compilers.
    +  Added PNG_STRING_COPYRIGHT macro.
    +  Added non-ISO versions of png_debug macros.
    +
    +Version 1.4.0beta30 [August 14, 2008]
    +  Added premultiplied alpha feature (Volker Wiendl).
    +
    +Version 1.4.0beta31 [August 18, 2008]
    +  Moved png_set_premultiply_alpha from pngtrans.c to pngrtran.c
    +  Removed extra crc check at the end of png_handle_cHRM().  Bug introduced
    +    in libpng-1.4.0beta20.
    +
    +Version 1.4.0beta32 [August 19, 2008]
    +  Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call.
    +  Revised PNG_NO_STDIO version of png_write_flush()
    +
    +Version 1.4.0beta33 [August 20, 2008]
    +  Added png_get|set_chunk_cache_max() to limit the total number of sPLT,
    +    text, and unknown chunks that can be stored.
    +
    +Version 1.4.0beta34 [September 6, 2008]
    +  Shortened tIME_string to 29 bytes in pngtest.c
    +  Fixed off-by-one error introduced in png_push_read_zTXt() function in
    +    libpng-1.2.30beta04/pngpread.c (Harald van Dijk)
    +
    +Version 1.4.0beta35 [October 6, 2008]
    +  Changed "trans_values" to "trans_color".
    +  Changed so-number from 0 to 14.  Some OS do not like 0.
    +  Revised makefile.darwin to fix shared library numbering.
    +  Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8()
    +    in example.c (debian bug report)
    +
    +Version 1.4.0beta36 [October 25, 2008]
    +  Sync with tEXt vulnerability fix in libpng-1.2.33rc02.
    +
    +Version 1.4.0beta37 [November 13, 2008]
    +  Added png_check_cHRM in png.c and moved checking from pngget.c, pngrutil.c,
    +    and pngwrite.c
    +
    +Version 1.4.0beta38 [November 22, 2008]
    +  Added check for zero-area RGB cHRM triangle in png_check_cHRM() and
    +    png_check_cHRM_fixed().
    +
    +Version 1.4.0beta39 [November 23, 2008]
    +  Revised png_warning() to write its message on standard output by default
    +    when warning_fn is NULL.
    +
    +Version 1.4.0beta40 [November 24, 2008]
    +  Eliminated png_check_cHRM().  Instead, always use png_check_cHRM_fixed().
    +  In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant
    +    check for all-zero coordinates that is detected by the triangle check.
    +
    +Version 1.4.0beta41 [November 26, 2008]
    +  Fixed string vs pointer-to-string error in png_check_keyword().
    +  Rearranged test expressions in png_check_cHRM_fixed() to avoid internal
    +    overflows.
    +  Added PNG_NO_CHECK_cHRM conditional.
    +
    +Version 1.4.0beta42, 43 [December 1, 2008]
    +  Merge png_debug with version 1.2.34beta04.
    +
    +Version 1.4.0beta44 [December 6, 2008]
    +  Removed redundant check for key==NULL before calling png_check_keyword()
    +    to ensure that new_key gets initialized and removed extra warning
    +    (Merge with version 1.2.34beta05 -- Arvan Pritchard).
    +
    +Version 1.4.0beta45 [December 9, 2008]
    +  In png_write_png(), respect the placement of the filler bytes in an earlier
    +    call to png_set_filler() (Jim Barry).
    +
    +Version 1.4.0beta46 [December 10, 2008]
    +  Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and
    +    PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated
    +    PNG_TRANSFORM_STRIP_FILLER (Jim Barry).
    +
    +Version 1.4.0beta47 [December 15, 2008]
    +  Support for dithering was disabled by default, because it has never
    +    been well tested and doesn't work very well.  The code has not
    +    been removed, however, and can be enabled by building libpng with
    +    PNG_READ_DITHER_SUPPORTED defined.
    +
    +Version 1.4.0beta48 [February 14, 2009]
    +  Added new exported function png_calloc().
    +  Combined several instances of png_malloc(); png_memset() into png_calloc().
    +  Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24
    +    but was never defined.
    +
    +Version 1.4.0beta49 [February 28, 2009]
    +  Added png_fileno() macro to pngconf.h, used in pngwio.c
    +  Corrected order of #ifdef's in png_debug definition in png.h
    +  Fixed bug introduced in libpng-1.4.0beta48 with the memset arguments
    +    for pcal_params.
    +  Fixed order of #ifdef directives in the png_debug defines in png.h
    +    (bug introduced in libpng-1.2.34/1.4.0beta29).
    +  Revised comments in png_set_read_fn() and png_set_write_fn().
    +
    +Version 1.4.0beta50 [March 18, 2009]
    +  Use png_calloc() instead of png_malloc() to allocate big_row_buf when
    +    reading an interlaced file, to avoid a possible UMR.
    +  Undid revision of PNG_NO_STDIO version of png_write_flush().  Users
    +    having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined
    +    or supply their own flush_fn() replacement.
    +  Revised libpng*.txt and png.h documentation about use of png_write_flush()
    +    and png_set_write_fn().
    +  Removed fflush() from pngtest.c.
    +  Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h
    +
    +Version 1.4.0beta51 [March 21, 2009]
    +  Removed new png_fileno() macro from pngconf.h .
    +
    +Version 1.4.0beta52 [March 27, 2009]
    +  Relocated png_do_chop() ahead of building gamma tables in pngrtran.c
    +    This avoids building 16-bit gamma tables unnecessarily.
    +  Removed fflush() from pngtest.c.
    +  Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h
    +  Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt
    +
    +Version 1.4.0beta53 [April 1, 2009]
    +  Removed some remaining MMX macros from pngpriv.h
    +  Fixed potential memory leak of "new_name" in png_write_iCCP() (Ralph Giles)
    +
    +Version 1.4.0beta54 [April 13, 2009]
    +  Added "ifndef PNG_SKIP_SETJMP_CHECK" block in pngconf.h to allow
    +    application code writers to bypass the check for multiple inclusion
    +    of setjmp.h when they know that it is safe to ignore the situation.
    +  Eliminated internal use of setjmp() in pngread.c and pngwrite.c
    +  Reordered ancillary chunks in pngtest.png to be the same as what
    +    pngtest now produces, and made some cosmetic changes to pngtest output.
    +  Eliminated deprecated png_read_init_3() and png_write_init_3() functions.
    +
    +Version 1.4.0beta55 [April 15, 2009]
    +  Simplified error handling in pngread.c and pngwrite.c by putting
    +    the new png_read_cleanup() and png_write_cleanup() functions inline.
    +
    +Version 1.4.0beta56 [April 25, 2009]
    +  Renamed "user_chunk_data" to "my_user_chunk_data" in pngtest.c to suppress
    +    "shadowed declaration" warning from gcc-4.3.3.
    +  Renamed "gamma" to "png_gamma" in pngset.c to avoid "shadowed declaration"
    +    warning about a global "gamma" variable in math.h on some platforms.
    +
    +Version 1.4.0beta57 [May 2, 2009]
    +  Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24
    +    but was never defined (again).
    +  Rebuilt configure scripts with autoconf-2.63 instead of 2.62
    +  Removed pngprefs.h and MMX from makefiles
    +
    +Version 1.4.0beta58 [May 14, 2009]
    +  Changed pngw32.def to pngwin.def in makefile.mingw (typo was introduced
    +    in beta57).
    +  Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri)
    +
    +Version 1.4.0beta59 [May 15, 2009]
    +  Reformated sources in libpng style (3-space intentation, comment format)
    +  Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG)
    +  Added sections about the git repository and our coding style to the
    +    documentation
    +  Relocated misplaced #endif in pngwrite.c, sCAL chunk handler.
    +
    +Version 1.4.0beta60 [May 19, 2009]
    +  Conditionally compile png_read_finish_row() which is not used by
    +    progressive readers.
    +  Added contrib/pngminim/preader to demonstrate building minimal progressive
    +    decoder, based on contrib/gregbook with embedded libpng and zlib.
    +
    +Version 1.4.0beta61 [May 20, 2009]
    +  In contrib/pngminim/*, renamed "makefile.std" to "makefile", since there
    +    is only one makefile in those directories, and revised the README files
    +    accordingly.
    +  More reformatting of comments, mostly to capitalize sentences.
    +
    +Version 1.4.0beta62 [June 2, 2009]
    +  Added "#define PNG_NO_WRITE_SWAP" to contrib/pngminim/encoder/pngusr.h
    +    and "define PNG_NO_READ_SWAP" to decoder/pngusr.h and preader/pngusr.h
    +  Reformatted several remaining "else statement" into two lines.
    +  Added a section to the libpng documentation about using png_get_io_ptr()
    +    in configure scripts to detect the presence of libpng.
    +
    +Version 1.4.0beta63 [June 15, 2009]
    +  Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR()
    +    multiple times and to specify the sample order in the tRNS chunk,
    +    because the ISO PNG specification has a typo in the tRNS table.
    +  Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to
    +    PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism
    +    available for ignoring known chunks even when not saving unknown chunks.
    +  Adopted preference for consistent use of "#ifdef" and "#ifndef" versus
    +    "#if defined()" and "if !defined()" where possible.
    +
    +Version 1.4.0beta64 [June 24, 2009]
    +  Eliminated PNG_LEGACY_SUPPORTED code.
    +  Moved the various unknown chunk macro definitions outside of the
    +    PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks.
    +
    +Version 1.4.0beta65 [June 26, 2009]
    +  Added a reference to the libpng license in each file.
    +
    +Version 1.4.0beta66 [June 27, 2009]
    +  Refer to the libpng license instead of the libpng license in each file.
    +
    +Version 1.4.0beta67 [July 6, 2009]
    +  Relocated INVERT_ALPHA within png_read_png() and png_write_png().
    +  Added high-level API transform PNG_TRANSFORM_GRAY_TO_RGB.
    +  Added an "xcode" project to the projects directory (Alam Arias).
    +
    +Version 1.4.0beta68 [July 19, 2009]
    +  Avoid some tests in filter selection in pngwutil.c
    +
    +Version 1.4.0beta69 [July 25, 2009]
    +  Simplified the new filter-selection test.  This runs faster in the
    +    common "PNG_ALL_FILTERS" and PNG_FILTER_NONE cases.
    +  Removed extraneous declaration from the new call to png_read_gray_to_rgb()
    +    (bug introduced in libpng-1.4.0beta67).
    +  Fixed up xcode project (Alam Arias)
    +  Added a prototype for png_64bit_product() in png.c
    +
    +Version 1.4.0beta70 [July 27, 2009]
    +  Avoid a possible NULL dereference in debug build, in png_set_text_2().
    +    (bug introduced in libpng-0.95, discovered by Evan Rouault)
    +
    +Version 1.4.0beta71 [July 29, 2009]
    +  Rebuilt configure scripts with autoconf-2.64.
    +
    +Version 1.4.0beta72 [August 1, 2009]
    +  Replaced *.tar.lzma with *.tar.xz in distribution.  Get the xz codec
    +    from .
    +
    +Version 1.4.0beta73 [August 1, 2009]
    +  Reject attempt to write iCCP chunk with negative embedded profile length
    +    (JD Chen) (CVE-2009-5063).
    +
    +Version 1.4.0beta74 [August 8, 2009]
    +  Changed png_ptr and info_ptr member "trans" to "trans_alpha".
    +
    +Version 1.4.0beta75 [August 21, 2009]
    +  Removed an extra png_debug() recently added to png_write_find_filter().
    +  Fixed incorrect #ifdef in pngset.c regarding unknown chunk support.
    +
    +Version 1.4.0beta76 [August 22, 2009]
    +  Moved an incorrectly located test in png_read_row() in pngread.c
    +
    +Version 1.4.0beta77 [August 27, 2009]
    +  Removed lpXYZ.tar.bz2 (with CRLF), KNOWNBUG, libpng-x.y.z-KNOWNBUG.txt,
    +    and the "noconfig" files from the distribution.
    +  Moved CMakeLists.txt from scripts into the main libpng directory.
    +  Various bugfixes and improvements to CMakeLists.txt (Philip Lowman)
    +
    +Version 1.4.0beta78 [August 31, 2009]
    +  Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h
    +  Eliminated PNG_NO_FREE_ME and PNG_FREE_ME_SUPPORTED macros.
    +  Use png_malloc plus a loop instead of png_calloc() to initialize
    +    row_pointers in png_read_png().
    +
    +Version 1.4.0beta79 [September 1, 2009]
    +  Eliminated PNG_GLOBAL_ARRAYS and PNG_LOCAL_ARRAYS; always use local arrays.
    +  Eliminated PNG_CALLOC_SUPPORTED macro and always provide png_calloc().
    +
    +Version 1.4.0beta80 [September 17, 2009]
    +  Removed scripts/libpng.icc
    +  Changed typecast of filler from png_byte to png_uint_16 in png_set_filler().
    +    (Dennis Gustafsson)
    +  Fixed typo introduced in beta78 in pngtest.c ("#if def " should be "#ifdef ")
    +
    +Version 1.4.0beta81 [September 23, 2009]
    +  Eliminated unused PNG_FLAG_FREE_* defines from pngpriv.h
    +  Expanded TAB characters in pngrtran.c
    +  Removed PNG_CONST from all "PNG_CONST PNG_CHNK" declarations to avoid
    +    compiler complaints about doubly declaring things "const".
    +  Changed all "#if [!]defined(X)" to "if[n]def X" where possible.
    +  Eliminated unused png_ptr->row_buf_size
    +
    +Version 1.4.0beta82 [September 25, 2009]
    +  Moved redundant IHDR checking into new png_check_IHDR() in png.c
    +    and report all errors found in the IHDR data.
    +  Eliminated useless call to png_check_cHRM() from pngset.c
    +
    +Version 1.4.0beta83 [September 25, 2009]
    +  Revised png_check_IHDR() to eliminate bogus complaint about filter_type.
    +
    +Version 1.4.0beta84 [September 30, 2009]
    +  Fixed some inconsistent indentation in pngconf.h
    +  Revised png_check_IHDR() to add a test for width variable less than 32-bit.
    +
    +Version 1.4.0beta85 [October 1, 2009]
    +  Revised png_check_IHDR() again, to check info_ptr members instead of
    +    the contents of the returned parameters.
    +
    +Version 1.4.0beta86 [October 9, 2009]
    +  Updated the "xcode" project (Alam Arias).
    +  Eliminated a shadowed declaration of "pp" in png_handle_sPLT().
    +
    +Version 1.4.0rc01 [October 19, 2009]
    +  Trivial cosmetic changes.
    +
    +Version 1.4.0beta87 [October 30, 2009]
    +  Moved version 1.4.0 back into beta.
    +
    +Version 1.4.0beta88 [October 30, 2009]
    +  Revised libpng*.txt section about differences between 1.2.x and 1.4.0
    +    because most of the new features have now been ported back to 1.2.41
    +
    +Version 1.4.0beta89 [November 1, 2009]
    +  More bugfixes and improvements to CMakeLists.txt (Philip Lowman)
    +  Removed a harmless extra png_set_invert_alpha() from pngwrite.c
    +  Apply png_user_chunk_cache_max within png_decompress_chunk().
    +  Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate.
    +
    +Version 1.4.0beta90 [November 2, 2009]
    +  Removed all remaining WIN32_WCE #ifdefs except those involving the
    +    time.h "tm" structure
    +
    +Version 1.4.0beta91 [November 3, 2009]
    +  Updated scripts/pngw32.def and projects/wince/png32ce.def
    +  Copied projects/wince/png32ce.def to the scripts directory.
    +  Added scripts/makefile.wce
    +  Patched ltmain.sh for wince support.
    +  Added PNG_CONVERT_tIME_SUPPORTED macro.
    +
    +Version 1.4.0beta92 [November 4, 2009]
    +  Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED
    +  Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED
    +  Revised libpng*.txt to describe differences from 1.2.40 to 1.4.0 (instead
    +    of differences from 1.2.41 to 1.4.0)
    +
    +Version 1.4.0beta93 [November 7, 2009]
    +  Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and
    +    PNG_ALLOCATED macros to detect deprecated direct access to the
    +    png_struct or info_struct members and other deprecated usage in
    +    applications (John Bowler).
    +  Updated scripts/makefile* to add "-DPNG_CONFIGURE_LIBPNG" to CFLAGS,
    +    to prevent warnings about direct access to png structs by libpng
    +    functions while building libpng.  They need to be tested, especially
    +    those using compilers other than gcc.
    +  Updated projects/visualc6 and visualc71 with "/d PNG_CONFIGURE_LIBPNG".
    +    They should work but still need to be updated to remove
    +    references to pnggccrd.c or pngvcrd.c and ASM building.
    +  Added README.txt to the beos, cbuilder5, netware, and xcode projects warning
    +    that they need to be updated, to remove references to pnggccrd.c and
    +    pngvcrd.c and to depend on pngpriv.h
    +  Removed three direct references to read_info_ptr members in pngtest.c
    +    that were detected by the new PNG_DEPSTRUCT macro.
    +  Moved the png_debug macro definitions and the png_read_destroy(),
    +    png_write_destroy() and png_far_to_near() prototypes from png.h
    +    to pngpriv.h (John Bowler)
    +  Moved the synopsis lines for png_read_destroy(), png_write_destroy()
    +    png_debug(), png_debug1(), and png_debug2() from libpng.3 to libpngpf.3.
    +
    +Version 1.4.0beta94 [November 9, 2009]
    +  Removed the obsolete, unused pnggccrd.c and pngvcrd.c files.
    +  Updated CMakeLists.txt to add "-DPNG_CONFIGURE_LIBPNG" to the definitions.
    +  Removed dependency of pngtest.o on pngpriv.h in the makefiles.
    +  Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined.
    +
    +Version 1.4.0beta95 [November 10, 2009]
    +  Changed png_check_sig() to !png_sig_cmp() in contrib programs.
    +  Added -DPNG_CONFIGURE_LIBPNG to contrib/pngminm/*/makefile
    +  Changed png_check_sig() to !png_sig_cmp() in contrib programs.
    +  Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c
    +  Changed pngminim/*/gather.sh to stop trying to remove pnggccrd.c and pngvcrd.c
    +  Added dependency on pngpriv.h in contrib/pngminim/*/makefile
    +
    +Version 1.4.0beta96 [November 12, 2009]
    +  Renamed scripts/makefile.wce to scripts/makefile.cegcc
    +  Revised Makefile.am to use libpng.sys while building libpng.so
    +    so that only PNG_EXPORT functions are exported.
    +  Removed the deprecated png_check_sig() function/macro.
    +  Removed recently removed function names from scripts/*.def
    +  Revised pngtest.png to put chunks in the same order written by pngtest
    +    (evidently the same change made in libpng-1.0beta54 was lost).
    +  Added PNG_PRIVATE macro definition in pngconf.h for possible future use.
    +
    +Version 1.4.0beta97 [November 13, 2009]
    +  Restored pngtest.png to the libpng-1.4.0beta7 version.
    +  Removed projects/beos and netware.txt; no one seems to be supporting them.
    +  Revised Makefile.in
    +
    +Version 1.4.0beta98 [November 13, 2009]
    +  Added the "xcode" project to zip distributions,
    +  Fixed a typo in scripts/pngwin.def introduced in beta97.
    +
    +Version 1.4.0beta99 [November 14, 2009]
    +  Moved libpng-config.in and libpng.pc-configure.in out of the scripts
    +    directory, to libpng-config.in and libpng-pc.in, respectively, and
    +    modified Makefile.am and configure.ac accordingly.  Now "configure"
    +    needs nothing from the "scripts" directory.
    +  Avoid redefining PNG_CONST in pngconf.h
    +
    +Version 1.4.0beta100 [November 14, 2009]
    +  Removed ASM builds from projects/visualc6 and projects/visualc71
    +  Removed scripts/makefile.nommx and makefile.vcawin32
    +  Revised CMakeLists.txt to account for new location of libpng-config.in
    +    and libpng-pc.in
    +  Updated INSTALL to reflect removal and relocation of files.
    +
    +Version 1.4.0beta101 [November 14, 2009]
    +  Restored the binary files (*.jpg, *.png, some project files) that were
    +    accidentally deleted from the zip and 7z distributions when the xcode
    +    project was added.
    +
    +Version 1.4.0beta102 [November 18, 2009]
    +  Added libpng-config.in and libpng-pc.in to the zip and 7z distributions.
    +  Fixed a typo in projects/visualc6/pngtest.dsp, introduced in beta100.
    +  Moved descriptions of makefiles and other scripts out of INSTALL into
    +    scripts/README.txt
    +  Updated the copyright year in scripts/pngwin.rc from 2006 to 2009.
    +
    +Version 1.4.0beta103 [November 21, 2009]
    +  Removed obsolete comments about ASM from projects/visualc71/README_zlib.txt
    +  Align row_buf on 16-byte boundary in memory.
    +  Restored the PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED guard around the call
    +    to png_flush() after png_write_IEND().  See 1.4.0beta32, 1.4.0beta50
    +    changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES.  Someone
    +    needs this feature.
    +  Make the 'png_jmpbuf' macro expand to a call that records the correct
    +    longjmp function as well as returning a pointer to the setjmp
    +    jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'.
    +    (John Bowler)
    +
    +Version 1.4.0beta104 [November 22, 2009]
    +  Removed png_longjmp_ptr from scripts/*.def and libpng.3
    +  Rebuilt configure scripts with autoconf-2.65
    +
    +Version 1.4.0beta105 [November 25, 2009]
    +  Use fast integer PNG_DIVIDE_BY_255() or PNG_DIVIDE_BY_65535()
    +    to accomplish alpha premultiplication when
    +    PNG_READ_COMPOSITE_NODIV_SUPPORTED is defined.
    +  Changed "/255" to "/255.0" in background calculations to make it clear
    +    that the 255 is used as a double.
    +
    +Version 1.4.0beta106 [November 27, 2009]
    +  Removed premultiplied alpha feature.
    +
    +Version 1.4.0beta107 [December 4, 2009]
    +  Updated README
    +  Added "#define PNG_NO_PEDANTIC_WARNINGS" in the libpng source files.
    +  Removed "-DPNG_CONFIGURE_LIBPNG" from the makefiles and projects.
    +  Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco
    +    to put png.h and pngconf.h in $prefix/include, like the other scripts,
    +    instead of in $prefix/include/libpng.  Also revised makefile.sco
    +    to put them in $prefix/include/libpng15 instead of in
    +    $prefix/include/libpng/libpng15.
    +
    +Version 1.4.0beta108 [December 11, 2009]
    +  Removed leftover "-DPNG_CONFIGURE_LIBPNG" from contrib/pngminim/*/makefile
    +  Relocated png_do_chop() to its original position in pngrtran.c; the
    +    change in version 1.2.41beta08 caused transparency to be handled wrong
    +    in some 16-bit datastreams (Yusaku Sugai).
    +
    +Version 1.4.0beta109 [December 13, 2009]
    +  Added "bit_depth" parameter to the private png_build_gamma_table() function.
    +  Pass bit_depth=8 to png_build_gamma_table() when bit_depth is 16 but the
    +    PNG_16_TO_8 transform has been set, to avoid unnecessary build of 16-bit
    +    tables.
    +
    +Version 1.4.0rc02 [December 20, 2009]
    +  Declared png_cleanup_needed "volatile" in pngread.c and pngwrite.c
    +
    +Version 1.4.0rc03 [December 22, 2009]
    +  Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt
    +    (revising the change in 1.4.0beta99)
    +
    +Version 1.4.0rc04 [December 25, 2009]
    +  Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +    in pngset.c to be consistent with other changes in version 1.2.38.
    +
    +Version 1.4.0rc05 [December 25, 2009]
    +  Changed "libpng-pc.in" to "libpng.pc.in" in configure.ac, configure, and
    +    Makefile.in to be consistent with changes in libpng-1.4.0rc03
    +
    +Version 1.4.0rc06 [December 29, 2009]
    +  Reverted the gamma_table changes from libpng-1.4.0beta109.
    +  Fixed some indentation errors.
    +
    +Version 1.4.0rc07 [January 1, 2010]
    +  Revised libpng*.txt and libpng.3 about 1.2.x->1.4.x differences.
    +  Use png_calloc() instead of png_malloc(); png_memset() in pngrutil.c
    +  Update copyright year to 2010.
    +
    +Version 1.4.0rc08 [January 2, 2010]
    +  Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr
    +    in pngtest.c
    +
    +Version 1.4.0 [January 3, 2010]
    +  No changes.
    +
    +Version 1.4.1beta01 [January 8, 2010]
    +  Updated CMakeLists.txt for consistent indentation and to avoid an
    +    unclosed if-statement warning (Philip Lowman).
    +  Revised Makefile.am and Makefile.in to remove references to Y2KINFO,
    +    KNOWNBUG, and libpng.la (Robert Schwebel).
    +  Revised the makefiles to install the same files and symbolic
    +    links as configure, except for libpng.la and libpng14.la.
    +  Make png_set|get_compression_buffer_size() available even when
    +    PNG_WRITE_SUPPORTED is not enabled.
    +  Revised Makefile.am and Makefile.in to simplify their maintenance.
    +  Revised scripts/makefile.linux to install a link to libpng14.so.14.1
    +
    +Version 1.4.1beta02 [January 9, 2010]
    +  Revised the rest of the makefiles to install a link to libpng14.so.14.1
    +
    +Version 1.4.1beta03 [January 10, 2010]
    +  Removed png_set_premultiply_alpha() from scripts/*.def
    +
    +Version 1.4.1rc01 [January 16, 2010]
    +  No changes.
    +
    +Version 1.4.1beta04 [January 23, 2010]
    +  Revised png_decompress_chunk() to improve speed and memory usage when
    +    decoding large chunks.
    +  Added png_set|get_chunk_malloc_max() functions.
    +
    +Version 1.4.1beta05 [January 26, 2010]
    +  Relocated "int k" declaration in pngtest.c to minimize its scope.
    +
    +Version 1.4.1beta06 [January 28, 2010]
    +  Revised png_decompress_chunk() to use a two-pass method suggested by
    +    John Bowler.
    +
    +Version 1.4.1beta07 [February 6, 2010]
    +  Folded some long lines in the source files.
    +  Added defineable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX,
    +    and a PNG_USER_LIMITS_SUPPORTED flag.
    +  Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as
    +    png_ptr->png_user_chunk_malloc_max.
    +  Revised png_push_save_buffer() to do fewer but larger png_malloc() calls.
    +
    +Version 1.4.1beta08 [February 6, 2010]
    +  Minor cleanup and updating of dates and copyright year.
    +
    +Version 1.5.0beta01 [February 7, 2010]
    +  Moved declaration of png_struct into private pngstruct.h and png_info
    +    into pnginfo.h
    +
    +Version 1.4.1beta09 and 1.5.0beta02 [February 7, 2010]
    +  Reverted to original png_push_save_buffer() code.
    +
    +Version 1.4.1beta10 and 1.5.0beta03 [February 8, 2010]
    +  Return allocated "old_buffer" in png_push_save_buffer() before
    +    calling png_error(), to avoid a potential memory leak.
    +  Updated configure script to use SO number 15.
    +
    +Version 1.5.0beta04 [February 9, 2010]
    +  Removed malformed "incomplete struct declaration" of png_info from png.h
    +
    +Version 1.5.0beta05 [February 12, 2010]
    +  Removed PNG_DEPSTRUCT markup in pngstruct.h and pnginfo.h, and undid the
    +    linewrapping that it entailed.
    +  Revised comments in pngstruct.h and pnginfo.h and added pointers to
    +    the libpng license.
    +  Changed PNG_INTERNAL to PNG_EXPOSE_INTERNAL_STRUCTURES
    +  Removed the cbuilder5 project, which has not been updated to 1.4.0.
    +
    +Version 1.4.1beta12 and 1.5.0beta06 [February 14, 2010]
    +  Fixed type declaration of png_get_chunk_malloc_max() in pngget.c (Daisuke
    +    Nishikawa)
    +
    +Version 1.5.0beta07 [omitted]
    +
    +Version 1.5.0beta08 [February 19, 2010]
    +  Changed #ifdef PNG_NO_STDIO_SUPPORTED to #ifdef PNG_NO_CONSOLE_IO_SUPPORTED
    +    wherever png_snprintf() is used to construct error and warning messages.
    +  Noted in scripts/makefile.mingw that it expects to be run under MSYS.
    +  Removed obsolete unused MMX-querying support from contrib/gregbook
    +  Added exported png_longjmp() function.
    +  Removed the AIX redefinition of jmpbuf in png.h
    +  Added -D_ALLSOURCE in configure.ac, makefile.aix, and CMakeLists.txt
    +    when building on AIX.
    +
    +Version 1.5.0beta09 [February 19, 2010]
    +  Removed -D_ALLSOURCE from configure.ac, makefile.aix, and CMakeLists.txt.
    +  Changed the name of png_ptr->jmpbuf to png_ptr->png_jmpbuf in pngstruct.h
    +
    +Version 1.5.0beta10 [February 25, 2010]
    +  Removed unused gzio.c from contrib/pngminim gather and makefile scripts
    +  Removed replacement error handlers from contrib/gregbook.  Because of
    +    the new png_longjmp() function they are no longer needed.
    +
    +Version 1.5.0beta11 [March 6, 2010]
    +  Removed checking for already-included setjmp.h from pngconf.h
    +  Fixed inconsistent indentations and made numerous cosmetic changes.
    +  Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5
    +
    +Version 1.5.0beta12 [March 9, 2010]
    +  Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from
    +    the source files, along with "#define PNG_EXPOSE_INTERNAL_STRUCTURES"
    +    and "#define PNG_NO_PEDANTIC_WARNINGS" (John Bowler).
    +  Created new pngdebug.h and moved debug definitions there.
    +
    +Version 1.5.0beta13 [March 10, 2010]
    +  Protect pngstruct.h, pnginfo.h, and pngdebug.h from being included twice.
    +  Revise the "#ifdef" blocks in png_inflate() so it will compile when neither
    +    PNG_USER_CHUNK_MALLOC_MAX nor PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
    +    is defined.
    +  Removed unused png_measure_compressed_chunk() from pngpriv.h and libpngpf.3
    +  Moved the 'config.h' support from pngconf.h to pngpriv.h
    +  Removed PNGAPI from the png_longjmp_ptr typedef.
    +  Eliminated dependence of pngtest.c on the private pngdebug.h file.
    +  Make all png_debug macros into *unterminated* statements or
    +    expressions (i.e. a trailing ';' must always be added) and correct
    +    the format statements in various png_debug messages.
    +
    +Version 1.5.0beta14 [March 14, 2010]
    +  Removed direct access to png_ptr->io_ptr from the Windows code in pngtest.c
    +  Revised Makefile.am to account for recent additions and replacements.
    +  Corrected CE and OS/2 DEF files (scripts/png*def) for symbols removed and
    +    added ordinal numbers to the Windows DEF file and corrected the duplicated
    +    ordinal numbers on CE symbols that are commented out.
    +  Added back in export symbols that can be present in the Windows build but
    +    are disabled by default.
    +  PNG_EXPORT changed to include an 'ordinal' field for DEF file generation.
    +    PNG_CALLBACK added to make callback definitions uniform.  PNGAPI split
    +    into PNGCAPI (base C form), PNGAPI (exports) and PNGCBAPI (callbacks),
    +    and appropriate changes made to all files.  Cygwin builds re-hinged to
    +    allow procedure call standard changes and to remove the need for the DEF
    +    file (fixes build on Cygwin).
    +  Enabled 'attribute' warnings that are relevant to library APIs and callbacks.
    +  Changed rules for generation of the various symbol files and added a new
    +    rule for a DEF file (which is also added to the distribution).
    +  Updated the symbol file generation to stop it adding spurious spaces
    +    to EOL (coming from preprocessor macro expansion).  Added a facility
    +    to join tokens in the output and rewrite *.dfn to use this.
    +  Eliminated scripts/*.def in favor of libpng.def; updated projects/visualc71
    +    and removed scripts/makefile.cygwin.
    +  Made PNG_BUILD_DLL safe: it can be set whenever a DLL is being built.
    +  Removed the include of sys/types.h - apparently unnecessary now on the
    +    platforms on which it happened (all but Mac OS and RISC OS).
    +  Moved the Mac OS test into pngpriv.h (the only place it is used.)
    +
    +Version 1.5.0beta15 [March 17, 2010]
    +  Added symbols.chk target to Makefile.am to validate the symbols in png.h
    +    against the new DEF file scripts/symbols.def.
    +  Changed the default DEF file back to pngwin.def.
    +  Removed makefile.mingw.
    +  Eliminated PNG_NO_EXTERN and PNG_ALL_EXTERN
    +
    +Version 1.5.0beta16 [April 1, 2010]
    +  Make png_text_struct independent of PNG_iTXt_SUPPORTED, so that
    +    fields are initialized in all configurations.  The READ/WRITE
    +    macros (PNG_(READ|WRITE)_iTXt_SUPPORTED) still function as
    +    before to disable code to actually read or write iTXt chunks
    +    and iTXt_SUPPORTED can be used to detect presence of either
    +    read or write support (but it is probably better to check for
    +    the one actually required - read or write.)
    +  Combined multiple png_warning() calls for a single error.
    +  Restored the macro definition of png_check_sig().
    +
    +Version 1.5.0beta17 [April 17, 2010]
    +  Added some "(long)" typecasts to printf calls in png_handle_cHRM().
    +  Documented the fact that png_set_dither() was disabled since libpng-1.4.0.
    +  Reenabled png_set_dither() but renamed it to png_set_quantize() to reflect
    +    more accurately what it actually does.  At the same time, renamed
    +    the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros to
    +    PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS.
    +  Added some "(long)" typecasts to printf calls in png_handle_cHRM().
    +  Freeze build-time only configuration in the build.
    +    In all prior versions of libpng most configuration options
    +    controlled by compiler #defines had to be repeated by the
    +    application code that used libpng.  This patch changes this
    +    so that compilation options that can only be changed at build
    +    time are frozen in the build.  Options that are compiler
    +    dependent (and those that are system dependent) are evaluated
    +    each time - pngconf.h holds these.  Options that can be changed
    +    per-file in the application are in png.h.  Frozen options are
    +    in the new installed header file pnglibconf.h (John Bowler)
    +  Removed the xcode project because it has not been updated to work
    +    with libpng-1.5.0.
    +  Removed the ability to include optional pngusr.h
    +
    +Version 1.5.0beta18 [April 17, 2010]
    +  Restored the ability to include optional pngusr.h
    +  Moved replacements for png_error() and png_warning() from the
    +    contrib/pngminim project to pngerror.c, for use when warnings or
    +    errors are disabled via PNG_NO_WARN or PNG_NO_ERROR_TEXT, to avoid
    +    storing unneeded error/warning text.
    +  Updated contrib/pngminim project to work with the new pnglibconf.h
    +  Added some PNG_NO_* defines to contrib/pngminim/*/pngusr.h to save space.
    +
    +Version 1.5.0beta19 [April 24, 2010]
    +  Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED.  This allows the functions
    +    to read and write ints to be disabled independently of PNG_USE_READ_MACROS,
    +    which allows libpng to be built with the functions even though the default
    +    is to use the macros - this allows applications to choose at app build
    +    time whether or not to use macros (previously impossible because the
    +    functions weren't in the default build.)
    +  Changed Windows calling convention back to __cdecl for API functions.
    +    For Windows/x86 platforms only:
    +      __stdcall is no longer needed for Visual Basic, so libpng-1.5.0 uses
    +      __cdecl throughout (both API functions and callbacks) on Windows/x86
    +      platforms.
    +  Replaced visualc6 and visualc71 projects with new vstudio project
    +  Relaxed the overly-restrictive permissions of some files.
    +
    +Version 1.5.0beta20 [April 24, 2010]
    +  Relaxed more overly-restrictive permissions of some files.
    +
    +Version 1.5.0beta21 [April 27, 2010]
    +  Removed some unwanted binary bytes and changed CRLF to NEWLINE in the new
    +    vstudio project files, and some trivial editing of some files in the
    +    scripts directory.
    +  Set PNG_NO_READ_BGR, PNG_NO_IO_STATE, and PNG_NO_TIME_RFC1123 in
    +    contrib/pngminim/decoder/pngusr.h to make a smaller decoder application.
    +
    +Version 1.5.0beta22 [April 28, 2010]
    +  Fixed dependencies of GET_INT_32 - it does not require READ_INT_FUNCTIONS
    +    because it has a macro equivalent.
    +  Improved the options.awk script; added an "everything off" option.
    +  Revised contrib/pngminim to use the "everything off" option in pngusr.dfa.
    +
    +Version 1.5.0beta23 [April 29, 2010]
    +  Corrected PNG_REMOVED macro to take five arguments.
    +    The macro was documented with two arguments (name,ordinal), however
    +    the symbol checking .dfn files assumed five arguments.  The five
    +    argument form seems more useful so it is changed to that.
    +  Corrected PNG_UNKNOWN_CHUNKS_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +    in gregbook/readpng2.c
    +  Corrected protection of png_get_user_transform_ptr. The API declaration in
    +    png.h is removed if both READ and WRITE USER_TRANSFORM are turned off
    +    but was left defined in pngtrans.c
    +  Added logunsupported=1 to cause pnglibconf.h to document disabled options.
    +    This makes the installed pnglibconf.h more readable but causes no
    +    other change.  The intention is that users of libpng will find it
    +    easier to understand if an API they need is missing.
    +  Include png_reset_zstream() in png.c only when PNG_READ_SUPPORTED is defined.
    +  Removed dummy_inflate.c from contrib/pngminim/encoder
    +  Removed contrib/pngminim/*/gather.sh; gathering is now done in the makefile.
    +
    +Version 1.5.0beta24 [May 7, 2010]
    +  Use bitwise "&" instead of arithmetic mod in pngrutil.c calculation of the
    +    offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.
    +  Added more blank lines for readability.
    +
    +Version 1.5.0beta25 [June 18, 2010]
    +  In pngpread.c: png_push_have_row() add check for new_row > height
    +  Removed the now-redundant check for out-of-bounds new_row from example.c
    +
    +Version 1.5.0beta26 [June 18, 2010]
    +  In pngpread.c: png_push_process_row() add check for too many rows.
    +
    +Version 1.5.0beta27 [June 18, 2010]
    +  Removed the check added in beta25 as it is now redundant.
    +
    +Version 1.5.0beta28 [June 20, 2010]
    +  Rewrote png_process_IDAT_data to consistently treat extra data as warnings
    +    and handle end conditions more cleanly.
    +  Removed the new (beta26) check in png_push_process_row().
    +
    +Version 1.5.0beta29 [June 21, 2010]
    +  Revised scripts/options.awk to work on Sunos (but still doesn't work)
    +  Added comment to options.awk and contrib/pngminim/*/makefile to try nawk.
    +
    +Version 1.5.0beta30 [June 22, 2010]
    +  Stop memory leak when reading a malformed sCAL chunk.
    +
    +Version 1.5.0beta31 [June 26, 2010]
    +  Revised pngpread.c patch of beta28 to avoid an endless loop.
    +  Removed some trailing blanks.
    +
    +Version 1.5.0beta32 [June 26, 2010]
    +  Removed leftover scripts/options.patch and scripts/options.rej
    +
    +Version 1.5.0beta33 [July 6, 3010]
    +  Made FIXED and FLOATING options consistent in the APIs they enable and
    +    disable.  Corrected scripts/options.awk to handle both command line
    +    options and options specified in the .dfa files.
    +  Changed char *msg to PNG_CONST char *msg in pngrutil.c
    +  Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or
    +    floating point APIs, but not both.
    +  Reversed patch to remove error handler when the jmp_buf is stored in the
    +    main program structure, not the png_struct.
    +    The error handler is needed because the default handler in libpng will
    +    always use the jmp_buf in the library control structure; this is never
    +    set.  The gregbook code is a useful example because, even though it
    +    uses setjmp/longjmp, it shows how error handling can be implemented
    +    using control mechanisms not directly supported by libpng.  The
    +    technique will work correctly with mechanisms such as Microsoft
    +    Structure Exceptions or C++ exceptions (compiler willing - note that gcc
    +    does not by default support interworking of C and C++ error handling.)
    +  Reverted changes to call png_longjmp in contrib/gregbook where it is not
    +    appropriate.  If mainprog->jmpbuf is used by setjmp, then png_longjmp
    +    cannot be used.
    +  Changed "extern PNG_EXPORT" to "PNG_EXPORT" in png.h (Jan Nijtmans)
    +  Changed "extern" to "PNG_EXTERN" in pngpriv.h (except for the 'extern "C" {')
    +
    +Version 1.5.0beta34 [July 12, 2010]
    +  Put #ifndef PNG_EXTERN, #endif around the define PNG_EXTERN in pngpriv.h
    +
    +Version 1.5.0beta35 [July 24, 2010]
    +  Removed some newly-added TAB characters.
    +  Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2
    +  Moved the definition of png_snprintf() outside of the enclosing
    +    #ifdef blocks in pngconf.h
    +
    +Version 1.5.0beta36 [July 29, 2010]
    +  Patches by John Bowler:
    +  Fixed point APIs are now supported throughout (no missing APIs).
    +  Internal fixed point arithmetic support exists for all internal floating
    +    point operations.
    +  sCAL validates the floating point strings it is passed.
    +  Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2
    +  Two new APIs exist to get the number of passes without turning on the
    +    PNG_INTERLACE transform and to get the number of rows in the current
    +    pass.
    +  A new test program, pngvalid.c, validates the gamma code.
    +  Errors in the 16-bit gamma correction (overflows) have been corrected.
    +  cHRM chunk testing is done consistently (previously the floating point
    +    API bypassed it, because the test really didn't work on FP, now the test
    +    is performed on the actual values to be stored in the PNG file so it
    +    works in the FP case too.)
    +  Most floating point APIs now simply call the fixed point APIs after
    +    converting the values to the fixed point form used in the PNG file.
    +  The standard headers no longer include zlib.h, which is currently only
    +    required for pngstruct.h and can therefore be internal.
    +  Revised png_get_int_32 to undo the PNG two's complement representation of
    +    negative numbers.
    +
    +Version 1.5.0beta37 [July 30, 2010]
    +  Added a typecast in png_get_int_32() in png.h and pngrutil.h to avoid
    +    a compiler warning.
    +  Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png
    +
    +Version 1.5.0beta38 [July 31, 2010]
    +  Implemented remaining "_fixed" functions.
    +  Corrected a number of recently introduced warnings mostly resulting from
    +    safe but uncast assignments to shorter integers.  Also added a zlib
    +    VStudio release library project because the latest zlib Official Windows
    +    build does not include such a thing.
    +  Revised png_get_int_16() to be similar to png_get_int_32().
    +  Restored projects/visualc71.
    +
    +Version 1.5.0beta39 [August 2, 2010]
    +  VisualC/GCC warning fixes, VisualC build fixes
    +  The changes include support for function attributes in VC in addition to
    +    those already present in GCC - necessary because without these some
    +    warnings are unavoidable.  Fixes include signed/unsigned fixes in
    +    pngvalid and checks with gcc -Wall -Wextra -Wunused.
    +  VC requires function attributes on function definitions as well as
    +    declarations, PNG_FUNCTION has been added to enable this and the
    +    relevant function definitions changed.
    +
    +Version 1.5.0beta40 [August 6, 2010]
    +  Correct use of _WINDOWS_ in pngconf.h
    +  Removed png_mem_ #defines; they are no longer used.
    +  Added the sRGB chunk to pngtest.png
    +
    +Version 1.5.0beta41 [August 11, 2010]
    +  Added the cHRM chunk to pngtest.png
    +  Don't try to use version-script with cygwin/mingw.
    +  Revised contrib/gregbook to work under cygwin/mingw.
    +
    +Version 1.5.0beta42 [August 18, 2010]
    +  Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov)
    +  Made all API functions that have const arguments and constant string
    +    literal pointers declare them (John Bowler).
    +
    +Version 1.5.0beta43 [August 20, 2010]
    +  Removed spurious tabs, shorten long lines (no source change)
    +    Also added scripts/chkfmt to validate the format of all the files that can
    +    reasonably be validated (it is suggested to run "make distclean" before
    +    checking, because some machine generated files have long lines.)
    +  Reformatted the CHANGES file to be more consistent throughout.
    +  Made changes to address various issues identified by GCC, mostly
    +    signed/unsigned and shortening problems on assignment but also a few
    +    difficult to optimize (for GCC) loops.
    +  Fixed non-GCC fixed point builds.  In png.c a declaration was misplaced
    +    in an earlier update.  Fixed to declare the auto variables at the head.
    +  Use cexcept.h in pngvalid.c.
    +
    +Version 1.5.0beta44 [August 24, 2010]
    +  Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for
    +    installing libpng in /usr/lib64 (Funda Wang).
    +  Revised CMakeLists.txt to put the man pages in share/man/man* not man/man*
    +  Revised CMakeLists.txt to make symlinks instead of copies when installing.
    +  Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman)
    +  Implemented memory checks within pngvalid
    +  Reformatted/rearranged pngvalid.c to assist use of progressive reader.
    +  Check interlaced images in pngvalid
    +  Clarified pngusr.h comments in pnglibconf.dfa
    +  Simplified the pngvalid error-handling code now that cexcept.h is in place.
    +  Implemented progressive reader in pngvalid.c for standard tests
    +  Implemented progressive read in pngvalid.c gamma tests
    +  Turn on progressive reader in pngvalid.c by default and tidy code.
    +
    +Version 1.5.0beta45 [August 26, 2010]
    +  Added an explicit make step to projects/vstudio for pnglibconf.h
    +    Also corrected zlib.vcxproj into which Visual Studio had introduced
    +    what it calls an "authoring error".  The change to make pnglibconf.h
    +    simply copies the file; in the future it may actually generate the
    +    file from scripts/pnglibconf.dfa as the other build systems do.
    +  Changed pngvalid to work when floating point APIs are disabled
    +  Renamed the prebuilt scripts/pnglibconf.h to scripts/pnglibconf.h.prebuilt
    +  Supply default values for PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX
    +    in pngpriv.h in case the user neglected to define them in their pngusr.h
    +
    +Version 1.5.0beta46 [August 28, 2010]
    +  Added new private header files to libpng_sources in CMakeLists.txt
    +  Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options.
    +  Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project.
    +
    +Version 1.5.0beta47 [September 11, 2010]
    +  Fixed a number of problems with 64-bit compilation reported by Visual
    +    Studio 2010 (John Bowler).
    +
    +Version 1.5.0beta48 [October 4, 2010]
    +  Updated CMakeLists.txt (Philip Lowman).
    +  Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER,
    +    $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE
    +  Fixed problem with symbols creation in Makefile.am which was assuming that
    +    all versions of ccp write to standard output by default (Martin Banky). The
    +    bug was introduced in libpng-1.2.9beta5.
    +  Removed unused mkinstalldirs.
    +
    +Version 1.5.0beta49 [October 8, 2010]
    +  Undid Makefile.am revision of 1.5.0beta48.
    +
    +Version 1.5.0beta50 [October 14, 2010]
    +  Revised Makefile.in to account for mkinstalldirs being removed.
    +  Added some "(unsigned long)" typecasts in printf statements in pngvalid.c.
    +  Suppressed a compiler warning in png_handle_sPLT().
    +  Check for out-of-range text compression mode in png_set_text().
    +
    +Version 1.5.0beta51 [October 15, 2010]
    +  Changed embedded dates to "(PENDING RELEASE) in beta releases (and future
    +    rc releases) to minimize the difference between releases.
    +
    +Version 1.5.0beta52 [October 16, 2010]
    +  Restored some of the embedded dates (in png.h, png.c, documentation, etc.)
    +
    +Version 1.5.0beta53 [October 18, 2010]
    +  Updated INSTALL to mention using "make maintainer-clean" and to remove
    +    obsolete statement about a custom ltmain.sh
    +  Disabled "color-tests" by default in Makefile.am so it will work with
    +    automake versions earlier than 1.11.1
    +  Use document name "libpng-manual.txt" instead of "libpng-.txt"
    +    to simplify version differences.
    +  Removed obsolete remarks about setjmp handling from INSTALL.
    +  Revised and renamed the typedef in png.h and png.c that was designed
    +    to catch library and header mismatch.
    +
    +Version 1.5.0beta54 [November 10, 2010]
    +  Require 48 bytes, not 64 bytes, for big_row_buf in overflow checks.
    +  Used a consistent structure for the pngget.c functions.
    +
    +Version 1.5.0beta55 [November 21, 2010]
    +  Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin)
    +  Moved reading of file signature into png_read_sig (Cosmin)
    +  Fixed atomicity of chunk header serialization (Cosmin)
    +  Added test for io_state in pngtest.c (Cosmin)
    +  Added "#!/bin/sh" at the top of contrib/pngminim/*/gather.sh scripts.
    +  Changes to remove gcc warnings (John Bowler)
    +    Certain optional gcc warning flags resulted in warnings in libpng code.
    +    With these changes only -Wconversion and -Wcast-qual cannot be turned on.
    +    Changes are trivial rearrangements of code.  -Wconversion is not possible
    +    for pngrutil.c (because of the widespread use of += et al on variables
    +    smaller than (int) or (unsigned int)) and -Wcast-qual is not possible
    +    with pngwio.c and pngwutil.c because the 'write' callback and zlib
    +    compression both fail to declare their input buffers with 'const'.
    +
    +Version 1.5.0beta56 [December 7, 2010]
    +  Added the private PNG_UNUSED() macro definition in pngpriv.h.
    +  Added some commentary about PNG_EXPORT in png.h and pngconf.h
    +  Revised PNG_EXPORT() macro and added PNG_EXPORTA() macro, with the
    +    objective of simplifying and improving the cosmetic appearance of png.h.
    +  Fixed some incorrect "=" macro names in pnglibconf.dfa
    +  Included documentation of changes in 1.5.0 from 1.4.x in libpng-manual.txt
    +
    +Version 1.5.0beta57 [December 9, 2010]
    +  Documented the pngvalid gamma error summary with additional comments and
    +    print statements.
    +  Improved missing symbol handling in checksym.awk; symbols missing in both
    +    the old and new files can now be optionally ignored, treated as errors
    +    or warnings.
    +  Removed references to pngvcrd.c and pnggccrd.c from the vstudio project.
    +  Updated "libpng14" to "libpng15" in the visualc71 project.
    +  Enabled the strip16 tests in pngvalid.`
    +  Don't display test results (except PASS/FAIL) when running "make test".
    +    Instead put them in pngtest-log.txt
    +  Added "--with-zprefix=" to configure.ac
    +  Updated the prebuilt configuration files to autoconf version 2.68
    +
    +Version 1.5.0beta58 [December 19, 2010]
    +  Fixed interlace image handling and add test cases (John Bowler)
    +  Fixed the clean rule in Makefile.am to remove pngtest-log.txt
    +  Made minor changes to work around warnings in gcc 3.4
    +
    +Version 1.5.0rc01 [December 27, 2010]
    +  No changes.
    +
    +Version 1.5.0rc02 [December 27, 2010]
    +  Eliminated references to the scripts/*.def files in project/visualc71.
    +
    +Version 1.5.0rc03 [December 28, 2010]
    +  Eliminated scripts/*.def and revised Makefile.am accordingly
    +
    +Version 1.5.0rc04 [December 29, 2010]
    +  Fixed bug in background transformation handling in pngrtran.c (it was
    +    looking for the flag in png_ptr->transformations instead of in
    +    png_ptr->flags) (David Raymond).
    +
    +Version 1.5.0rc05 [December 31, 2010]
    +  Fixed typo in a comment in CMakeLists.txt (libpng14 => libpng15) (Cosmin)
    +
    +Version 1.5.0rc06 [January 4, 2011]
    +  Changed the new configure option "zprefix=string" to "zlib-prefix=string"
    +
    +Version 1.5.0rc07 [January 4, 2011]
    +  Updated copyright year.
    +
    +Version 1.5.0 [January 6, 2011]
    +  No changes.
    +
    +version 1.5.1beta01 [January 8, 2011]
    +  Added description of png_set_crc_action() to the manual.
    +  Added a note in the manual that the type of the iCCP profile was changed
    +    from png_charpp to png_bytepp in png_get_iCCP().  This change happened
    +    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, 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).
    +  Updated CMakeLists.txt (Clifford Yapp)
    +
    +Version 1.5.1beta03 [January 14, 2011]
    +  Fixed typecasting of some png_debug() statements (Cosmin)
    +
    +Version 1.5.1beta04 [January 16, 2011]
    +  Updated documentation of png_set|get_tRNS() (Thomas Klausner).
    +  Mentioned in the documentation that applications must #include "zlib.h"
    +    if they need access to anything in zlib.h, and that a number of
    +    macros such as png_memset() are no longer accessible by applications.
    +  Corrected pngvalid gamma test "sample" function to access all of the color
    +    samples of each pixel, instead of sampling the red channel three times.
    +  Prefixed variable names index, div, exp, gamma with "png_" to avoid "shadow"
    +    warnings, and (mistakenly) changed png_exp() to exp().
    +
    +Version 1.5.1beta05 [January 16, 2011]
    +  Changed variable names png_index, png_div, png_exp, and png_gamma to
    +    char_index, divisor, exp_b10, and gamma_val, respectively, and
    +    changed exp() back to png_exp().
    +
    +Version 1.5.1beta06 [January 20, 2011]
    +  Prevent png_push_crc_skip() from hanging while reading an unknown chunk
    +    or an over-large compressed zTXt chunk with the progressive reader.
    +  Eliminated more GCC "shadow" warnings.
    +  Revised png_fixed() in png.c to avoid compiler warning about reaching the
    +    end without returning anything.
    +
    +Version 1.5.1beta07 [January 22, 2011]
    +  In the manual, describe the png_get_IHDR() arguments in the correct order.
    +  Added const_png_structp and const_png_infop types, and used them in
    +    prototypes for most png_get_*() functions.
    +
    +Version 1.5.1beta08 [January 23, 2011]
    +  Added png_get_io_chunk_type() and deprecated png_get_io_chunk_name()
    +  Added synopses for the IO_STATE functions and other missing synopses
    +    to the manual. Removed the synopses from libpngpf.3 because they
    +    were out of date and no longer useful.  Better information can be
    +    obtained by reading the prototypes and comments in pngpriv.h
    +  Attempted to fix cpp on Solaris with S. Studio 12 cc, fix build
    +    Added a make macro DFNCPP that is a CPP that will accept the tokens in
    +    a .dfn file and adds configure stuff to test for such a CPP.  ./configure
    +    should fail if one is not available.
    +  Corrected const_png_ in png.h to png_const_ to avoid polluting the namespace.
    +  Added png_get_current_row_number and png_get_current_pass_number for the
    +    benefit of the user transform callback.
    +  Added png_process_data_pause and png_process_data_skip for the benefit of
    +    progressive readers that need to stop data processing or want to optimize
    +    skipping of unread data (e.g., if the reader marks a chunk to be skipped.)
    +
    +Version 1.5.1beta09 [January 24, 2011]
    +  Enhanced pngvalid, corrected an error in gray_to_rgb, corrected doc error.
    +    pngvalid contains tests of transforms, which tests are currently disabled
    +    because they are incompletely tested.  gray_to_rgb was failing to expand
    +    the bit depth for smaller bit depth images; this seems to be a long
    +    standing error and resulted, apparently, in invalid output
    +    (CVE-2011-0408, CERT VU#643140).  The documentation did not accurately
    +    describe what libpng really does when converting RGB to gray.
    +
    +Version 1.5.1beta10 [January 27, 2010]
    +  Fixed incorrect examples of callback prototypes in the manual, that were
    +    introduced in libpng-1.0.0.
    +  In addition the order of the png_get_uint macros with respect to the
    +    relevant function definitions has been reversed.  This helps the
    +    preprocessing of the symbol files be more robust.  Furthermore, the
    +    symbol file preprocessing now uses -DPNG_NO_USE_READ_MACROS even when
    +    the library may actually be built with PNG_USE_READ_MACROS; this stops
    +    the read macros interfering with the symbol file format.
    +  Made the manual, synopses, and function prototypes use the function
    +    argument names file_gamma, int_file_gamma, and srgb_intent consistently.
    +
    +Version 1.5.1beta11 [January 28, 2011]
    +  Changed PNG_UNUSED from "param=param;" to "{if(param){}}".
    +  Corrected local variable type in new API png_process_data_skip()
    +    The type was self-evidently incorrect but only causes problems on 64-bit
    +    architectures.
    +  Added transform tests to pngvalid and simplified the arguments.
    +
    +Version 1.5.1rc01 [January 29, 2011]
    +  No changes.
    +
    +Version 1.5.1rc02 [January 31, 2011]
    +  Added a request in the manual that applications do not use "png_" or
    +    "PNG_" to begin any of their own symbols.
    +  Changed PNG_UNUSED to "(void)param;" and updated the commentary in pngpriv.h
    +
    +Version 1.5.1 [February 3, 2011]
    +  No changes.
    +
    +Version 1.5.2beta01 [February 13, 2011]
    +  More -Wshadow fixes for older gcc compilers.  Older gcc versions apparently
    +    check formal parameters names in function declarations (as well as
    +    definitions) to see if they match a name in the global namespace.
    +  Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the
    +    old VisualC++ preprocessor.
    +  Turned on interlace handling in png_read_png().
    +  Fixed gcc pedantic warnings.
    +  Handle longjmp in Cygwin.
    +  Fixed png_get_current_row_number() in the interlaced case.
    +  Cleaned up ALPHA flags and transformations.
    +  Implemented expansion to 16 bits.
    +
    +Version 1.5.2beta02 [February 19, 2011]
    +  Fixed mistake in the descriptions of user read_transform and write_transform
    +    function prototypes in the manual.  The row_info struct is png_row_infop.
    +  Reverted png_get_current_row_number() to previous (1.5.2beta01) behavior.
    +  Corrected png_get_current_row_number documentation
    +  Fixed the read/write row callback documentation.
    +    This documents the current behavior, where the callback is called after
    +    every row with information pertaining to the next row.
    +
    +Version 1.5.2beta03 [March 3, 2011]
    +  Fixed scripts/makefile.vcwin32
    +  Updated contrib/pngsuite/README to add the word "modify".
    +  Define PNG_ALLOCATED to blank when _MSC_VER<1300.
    +
    +Version 1.5.2rc01 [March 19, 2011]
    +  Define remaining attributes to blank when MSC_VER<1300.
    +  ifdef out mask arrays in pngread.c when interlacing is not supported.
    +
    +Version 1.5.2rc02 [March 22, 2011]
    +  Added a hint to try CPP=/bin/cpp if "cpp -E" fails in scripts/pnglibconf.mak
    +    and in contrib/pngminim/*/makefile, eg., on SunOS 5.10, and removed "strip"
    +    from the makefiles.
    +  Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail
    +    to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill)
    +
    +Version 1.5.2rc03 [March 24, 2011]
    +  Don't include standard header files in png.h while building the symbol table,
    +    to avoid cpp failure on SunOS (introduced PNG_BUILDING_SYMBOL_TABLE macro).
    +
    +Version 1.5.2 [March 31, 2011]
    +  No changes.
    +
    +Version 1.5.3beta01 [April 1, 2011]
    +  Re-initialize the zlib compressor before compressing 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.
    +  Only compile the new zlib re-initializing code when text or iCCP is
    +    supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.
    +  Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
    +  Optimize the zlib CMF byte in non-IDAT compressed chunks
    +
    +Version 1.5.3beta03 [April 16, 2011]
    +  Fixed gcc -ansi -pedantic compile. A strict ANSI system does not have
    +    snprintf, and the "__STRICT_ANSI__" detects that condition more reliably
    +    than __STDC__ (John Bowler).
    +  Removed the PNG_PTR_NORETURN attribute because it too dangerous. It tells
    +    the compiler that a user supplied callback (the error handler) does not
    +    return, yet there is no guarantee in practice that the application code
    +    will correctly implement the error handler because the compiler only
    +    issues a warning if there is a mistake (John Bowler).
    +  Removed the no-longer-used PNG_DEPSTRUCT macro.
    +  Updated the zlib version to 1.2.5 in the VStudio project.
    +  Fixed 64-bit builds where png_uint_32 is smaller than png_size_t in
    +    pngwutil.c (John Bowler).
    +  Fixed bug with stripping the filler or alpha channel when writing, that
    +    was introduced in libpng-1.5.2beta01 (bug report by Andrew Church).
    +
    +Version 1.5.3beta04 [April 27, 2011]
    +  Updated pngtest.png with the new zlib CMF optimization.
    +  Cleaned up conditional compilation code and of background/gamma handling
    +    Internal changes only except a new option to avoid compiling the
    +    png_build_grayscale_palette API (which is not used at all internally.)
    +    The main change is to move the transform tests (READ_TRANSFORMS,
    +    WRITE_TRANSFORMS) up one level to the caller of the APIs.  This avoids
    +    calls to spurious functions if all transforms are disabled and slightly
    +    simplifies those functions.  Pngvalid modified to handle this.
    +    A minor change is to stop the strip_16 and expand_16 interfaces from
    +    disabling each other; this allows the future alpha premultiplication
    +    code to use 16-bit intermediate values while still producing 8-bit output.
    +    png_do_background and png_do_gamma have been simplified to take a single
    +    pointer to the png_struct rather than pointers to every item required
    +    from the png_struct. This makes no practical difference to the internal
    +    code.
    +  A serious bug in the pngvalid internal routine 'standard_display_init' has
    +    been fixed - this failed to initialize the red channel and accidentally
    +    initialized the alpha channel twice.
    +  Changed png_struct jmp_buf member name from png_jmpbuf to tmp_jmpbuf to
    +    avoid a possible clash with the png_jmpbuf macro on some platforms.
    +
    +Version 1.5.3beta05 [May 6, 2011]
    +  Added the "_POSIX_SOURCE" feature test macro to ensure libpng sees the
    +    correct API. _POSIX_SOURCE is defined in pngpriv.h, pngtest.c and
    +    pngvalid.c to ensure that POSIX conformant systems disable non-POSIX APIs.
    +  Removed png_snprintf and added formatted warning messages.  This change adds
    +    internal APIs to allow png_warning messages to have parameters without
    +    requiring the host OS to implement snprintf.  As a side effect the
    +    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.  This fixes CVE-2011-2691.
    +  Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte
    +    optimization configurable.
    +  IDAT compression failed if preceded by a compressed text chunk (bug
    +    introduced in libpng-1.5.3beta01-02).  This was because the attempt to
    +    reset the zlib stream in png_write_IDAT happened after the first IDAT
    +    chunk had been deflated - much too late.  In this change internal
    +    functions were added to claim/release the z_stream and, hopefully, make
    +    the code more robust.  Also deflateEnd checking is added - previously
    +    libpng would ignore an error at the end of the stream.
    +
    +Version 1.5.3beta06 [May 8, 2011]
    +  Removed the -D_ALL_SOURCE from definitions for AIX in CMakeLists.txt
    +  Implemented premultiplied alpha support: png_set_alpha_mode API
    +
    +Version 1.5.3beta07 [May 11, 2011]
    +  Added expand_16 support to the high level interface.
    +  Added named value and 'flag' gamma support to png_set_gamma.  Made a minor
    +    change from the previous (unreleased) ABI/API to hide the exact value used
    +    for Macs - it's not a good idea to embed this in the ABI!
    +  Moved macro definitions for PNG_HAVE_IHDR, PNG_HAVE_PLTE, and PNG_AFTER_IDAT
    +    from pngpriv.h to png.h because they must be visible to applications
    +    that call png_set_unknown_chunks().
    +  Check for up->location !PNG_AFTER_IDAT when writing unknown chunks
    +    before IDAT.
    +
    +Version 1.5.3beta08 [May 16, 2011]
    +  Improved "pngvalid --speed" to exclude more of pngvalid from the time.
    +  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.  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
    +    the default anyway.
    +  Added memory overwrite and palette image checks to pngvalid.c
    +    Previously palette image code was poorly checked. Since the transformation
    +    code has a special palette path in most cases this was a severe weakness.
    +  Minor cleanup and some extra checking in pngrutil.c and pngrtran.c. When
    +    expanding an indexed image, always expand to RGBA if transparency is
    +    present.
    +
    +Version 1.5.3beta09 [May 17, 2011]
    +  Reversed earlier 1.5.3 change of transformation order; move png_expand_16
    +    back where it was.  The change doesn't work because it requires 16-bit
    +    gamma tables when the code only generates 8-bit ones.  This fails
    +    silently; the libpng code just doesn't do any gamma correction.  Moving
    +    the tests back leaves the old, inaccurate, 8-bit gamma calculations, but
    +    these are clearly better than none!
    +
    +Version 1.5.3beta10 [May 20, 2011]
    +
    +  png_set_background() and png_expand_16() did not work together correctly.
    +    This problem is present in 1.5.2; if png_set_background is called with
    +    need_expand false and the matching 16 bit color libpng erroneously just
    +    treats it as an 8-bit color because of where png_do_expand_16 is in the
    +    transform list.  This simple fix reduces the supplied colour to 8-bits,
    +    so it gets smashed, but this is better than the current behavior.
    +  Added tests for expand16, more fixes for palette image tests to pngvalid.
    +    Corrects the code for palette image tests and disables attempts to
    +    validate palette colors.
    +
    +Version 1.5.3rc01 [June 3, 2011]
    +  No changes.
    +
    +Version 1.5.3rc02 [June 8, 2011]
    +  Fixed uninitialized memory read in png_format_buffer() (Bug report by
    +    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. 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
    +    limit beyond the PNG_USER_WIDTH|HEIGHT_MAX; previously it could only
    +    reduce it.
    +  Make the 16-to-8 scaling accurate. Dividing by 256 with no rounding is
    +    wrong (high by one) 25% of the time. Dividing by 257 with rounding is
    +    wrong in 128 out of 65536 cases. Getting the right answer all the time
    +    without division is easy.
    +  Added "_SUPPORTED" to the PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION macro.
    +  Added projects/owatcom, an IDE project for OpenWatcom to replace
    +    scripts/makefile.watcom.  This project works with OpenWatcom 1.9. The
    +    IDE autogenerates appropriate makefiles (libpng.mk) for batch processing.
    +    The project is configurable, unlike the Visual Studio project, so long
    +    as the developer has an awk.
    +  Changed png_set_gAMA to limit the gamma value range so that the inverse
    +    of the stored value cannot overflow the fixed point representation,
    +    and changed other things OpenWatcom warns about.
    +  Revised pngvalid.c to test PNG_ALPHA_MODE_SUPPORTED correctly. This allows
    +    pngvalid to build when ALPHA_MODE is not supported, which is required if
    +    it is to build on libpng 1.4.
    +  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
    +    and there will be no libpng-1.5.3 release.
    +
    +Version 1.5.4beta01 [June 14, 2011]
    +  Made it possible to undefine PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
    +    to get the same (inaccurate) output as libpng-1.5.2 and earlier.
    +  Moved definitions of PNG_HAVE_IHDR, PNG_AFTER_IDAT, and PNG_HAVE_PLTE
    +    outside of an unknown-chunk block in png.h because they are also
    +    needed for other uses.
    +
    +Version 1.5.4beta02 [June 14, 2011]
    +  Fixed and clarified LEGACY 16-to-8 scaling code.
    +  Added png_set_chop_16() API, to match inaccurate results from previous
    +    libpng versions.
    +  Removed the ACCURATE and LEGACY options (they are no longer useable)
    +  Use the old scaling method for background if png_set_chop_16() was
    +    called.
    +  Made png_set_chop_16() API removeable by disabling PNG_CHOP_16_TO_8_SUPPORTED
    +
    +Version 1.5.4beta03 [June 15, 2011]
    +  Fixed a problem in png_do_expand_palette() exposed by optimization in
    +    1.5.3beta06
    +  Also removed a spurious and confusing "trans" member ("trans") from png_info.
    +  The palette expand optimization prevented expansion to an intermediate RGBA
    +    form if tRNS was present but alpha was marked to be stripped; this exposed
    +    a check for tRNS in png_do_expand_palette() which is inconsistent with the
    +    code elsewhere in libpng.
    +  Correction to the expand_16 code; removed extra instance of
    +    png_set_scale_16_to_8 from pngpriv.h
    +
    +Version 1.5.4beta04 [June 16, 2011]
    +  Added a missing "#ifdef PNG_READ_BACKGROUND_SUPPORTED/#endif" in pngrtran.c
    +  Added PNG_TRANSFORM_CHOP_16 to the high-level read transforms.
    +  Made PNG_READ_16_TO_8_ACCURATE_SCALE configurable again.  If this is
    +    not enabled, png_set_strip_16() and png_do_scale_16_to_8() aren't built.
    +  Revised contrib/visupng, gregbook, and pngminim to demonstrate chop_16_to_8
    +
    +Version 1.5.4beta05 [June 16, 2011]
    +  Renamed png_set_strip_16() to png_set_scale_16() and renamed
    +    png_set_chop_16() to png_set_strip(16) in an attempt to minimize the
    +    behavior changes between libpng14 and libpng15.
    +
    +Version 1.5.4beta06 [June 18, 2011]
    +  Fixed new bug that was causing both strip_16 and scale_16 to be applied.
    +
    +Version 1.5.4beta07 [June 19, 2011]
    +  Fixed pngvalid, simplified macros, added checking for 0 in sCAL.
    +    The ACCURATE scale macro is no longer defined in 1.5 - call the
    +    png_scale_16_to_8 API.  Made sure that PNG_READ_16_TO_8 is still defined
    +    if the png_strip_16_to_8 API is present.  png_check_fp_number now
    +    maintains some state so that positive, negative and zero values are
    +    identified.  sCAL uses these to be strictly spec conformant.
    +
    +Version 1.5.4beta08 [June 23, 2011]
    +  Fixed pngvalid if ACCURATE_SCALE is defined.
    +  Updated scripts/pnglibconf.h.prebuilt.
    +
    +Version 1.5.4rc01 [June 30, 2011]
    +  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 uninitialized 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 concatenation
    +    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 desirable 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 png_set_tIME() and png_convert_to_rfc1123()
    +    (Frank Busse). Note: This prevented CVE-2015-7981 from affecting
    +    libpng-1.5.7 and later.
    +  Added MINGW support to CMakeLists.txt
    +  Reject invalid compression flag or method when reading the iTXt chunk.
    +  Backed out 'simplified' API changes. The API seems too complex and there
    +    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.
    +  Dropped support for 16-bit platforms. The use of FAR/far has been eliminated
    +    and the definition of png_alloc_size_t is now controlled by a flag so
    +    that 'small size_t' systems can select it if necessary.  Libpng 1.6 may
    +    not currently work on such systems -- it seems likely that it will
    +    ask 'malloc' for more than 65535 bytes with any image that has a
    +    sufficiently large row size (rather than simply failing to read such
    +    images).
    +  New tools directory containing tools used to generate libpng code.
    +  Fixed race conditions in parallel make builds. With higher degrees of
    +    parallelism during 'make' the use of the same temporary file names such
    +    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 ancillary 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 unnecessary 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 desirable 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.
    +  Added a new configure option:
    +    --enable-arm-neon=always will stop the run-time checks. New checks
    +    within arm/arm_init.c will cause the code not to be compiled unless
    +    __ARM_NEON__ is set. This should make it fail safe (if someone asks
    +    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.  It also makes those tests compile and link on Android.
    +  Added an API png_set_option() to set optimization options externally,
    +    providing an alternative and general solution for the non-portable
    +    run-time tests used by the ARM Neon code, using the PNG_ARM_NEON option.
    +  The order of settings vs options in pnglibconf.h is reversed to allow
    +    settings to depend on options and options can now set (or override) the
    +    defaults for settings.
    +
    +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, via a new PNG_MAXIMUM_INFLATE_WINDOW
    +    option for png_set_options().
    +  Added png-fix-itxt and png-fix-too-far-back to the built programs and
    +    removed warnings from the source code and timepng that are revealed as
    +    a result.
    +  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 usage.
    +    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 ).  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 " 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.
    +  Fixed an out-of-range read in png_user_version_check() (Bug report from
    +    Qixue Xiao, CVE-2015-8540).
    +  Simplified and future-proofed png_user_version_check().
    +  Fixed GCC unsigned int->float warnings. Various versions of GCC
    +    seem to generate warnings when an unsigned value is implicitly
    +    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, CVE-2015-0973).
    +
    +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
    +    (Bug report and fix by John Bowler, CVE-2014-9495).
    +
    +Version 1.6.16 [December 22, 2014]
    +  No changes.
    +
    +Version 1.6.17beta01 [January 29, 2015]
    +  Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h
    +  Corrected the width limit calculation in png_check_IHDR().
    +  Removed user limits from pngfix. Also pass NULL pointers to
    +    png_read_row to skip the unnecessary row de-interlace stuff.
    +  Added testing of png_set_packing() to pngvalid.c
    +  Regenerated configure scripts in the *.tar distributions with libtool-2.4.4
    +  Implement previously untested cases of libpng transforms in pngvalid.c
    +  Fixed byte order in png_do_read_filler() with 16-bit input. Previously
    +    the high and low bytes of the filler, from png_set_filler() or from
    +    png_set_add_alpha(), were read in the wrong order.
    +  Made the check for out-of-range values in png_set_tRNS() detect
    +    values that are exactly 2^bit_depth, and work on 16-bit platforms.
    +  Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47.
    +  Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and
    +    pngset.c to avoid warnings about dead code.
    +  Added "& 0xff" to many instances of expressions that are typecast
    +    to (png_byte), to avoid Coverity warnings.
    +
    +Version 1.6.17beta02 [February 7, 2015]
    +  Work around one more Coverity-scan dead-code warning.
    +  Do not build png_product2() when it is unused.
    +
    +Version 1.6.17beta03 [February 17, 2015]
    +  Display user limits in the output from pngtest.
    +  Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column
    +    and 1-million-row default limits in pnglibconf.dfa, that can be reset
    +    by the user at build time or run time.  This provides a more robust
    +    defense against DOS and as-yet undiscovered overflows.
    +
    +Version 1.6.17beta04 [February 21, 2015]
    +  Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default.
    +  Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins).
    +  Rebuilt configure scripts with automake-1.15 and libtool-2.4.6
    +
    +Version 1.6.17beta05 [February 25, 2015]
    +  Restored compiling of png_reciprocal2 with PNG_NO_16BIT.
    +
    +Version 1.6.17beta06 [February 27, 2015]
    +  Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block
    +    of png.h.
    +  Avoid runtime checks when converting integer to png_byte with
    +    Visual Studio (Sergey Kosarevsky)
    +
    +Version 1.6.17rc01 [March 4, 2015]
    +  No changes.
    +
    +Version 1.6.17rc02 [March 9, 2015]
    +  Removed some comments that the configure script did not handle
    +    properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt.
    +  Free the unknown_chunks structure even when it contains no data.
    +
    +Version 1.6.17rc03 [March 12, 2015]
    +  Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF
    +    for consistency, and remove some useless tests (Alexey Petruchik).
    +
    +Version 1.6.17rc04 [March 16, 2015]
    +  Remove pnglibconf.h, pnglibconf.c, and pnglibconf.out instead of
    +    pnglibconf.* in "make clean" (Cosmin).
    +  Fix bug in calculation of maxbits, in png_write_sBIT, introduced
    +    in libpng-1.6.17beta01 (John Bowler).
    +
    +Version 1.6.17rc05 [March 21, 2015]
    +  Define PNG_FILTER_* and PNG_FILTER_VALUE_* in png.h even when WRITE
    +    is not supported (John Bowler).  This fixes an error introduced in
    +    libpng-1.6.17beta06.
    +  Reverted "& 0xff" additions of version 1.6.17beta01. Libpng passes
    +    the Coverity scan without them.
    +
    +Version 1.6.17rc06 [March 23, 2015]
    +  Remove pnglibconf.dfn and pnglibconf.pre with "make clean".
    +  Reformatted some "&0xff" instances to "& 0xff".
    +  Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha
    +    value was wrong.  It's not clear if this affected the final stored
    +    value; in the obvious code path the upper and lower 8-bits of the
    +    alpha value were identical and the alpha was truncated to 8-bits
    +    rather than dividing by 257 (John Bowler).
    +
    +Version 1.6.17 [March 26, 2015]
    +  No changes.
    +
    +Version 1.6.18beta01 [April 1, 2015]
    +  Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They
    +    have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves
    +    bug report by Andrew Church).
    +  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c.  This
    +    fixes some arithmetic errors that caused some tests to fail on
    +    some 32-bit platforms (Bug reports by Peter Breitenlohner [i686]
    +    and Petr Gajdos [i586]).
    +
    +Version 1.6.18beta02 [April 26, 2015]
    +  Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler
    +    (Bug report by Viktor Szakats).
    +
    +Version 1.6.18beta03 [May 6, 2015]
    +  Replaced "unexpected" with an integer (0xabadca11) in pngset.c
    +    where a long was expected, to avoid a compiler warning when PNG_DEBUG > 1.
    +  Added contrib/examples/simpleover.c, to demonstrate how to handle
    +    alpha compositing of multiple images, using the "simplified API"
    +    and an example PNG generation tool, contrib/examples/genpng.c
    +    (John Bowler).
    +
    +Version 1.6.18beta04 [May 20, 2015]
    +  PNG_RELEASE_BUILD replaces tests where the code depended on the build base
    +    type and can be defined on the command line, allowing testing in beta
    +    builds (John Bowler).
    +  Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds.
    +  Avoid a harmless potential integer overflow in png_XYZ_from_xy() (Bug
    +    report from Christopher Ferris).
    +
    +Version 1.6.18beta05 [May 31, 2015]
    +  Backport filter selection code from libpng-1.7.0beta51, to combine
    +    sub_row, up_row, avg_row, and paeth_row into try_row and tst_row.
    +  Changed png_voidcast(), etc., to voidcast(), etc., in contrib/tools/pngfix.c
    +    to avoid confusion with the libpng private macros.
    +  Fixed old cut&paste bug in the weighted filter selection code in
    +    pngwutil.c, introduced in libpng-0.95, March 1997.
    +
    +Version 1.6.18beta06 [June 1, 2015]
    +  Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the
    +    compiled library size. It never worked properly and as far as we can
    +    tell, no one uses it. The png_set_filter_heuristics() and
    +    png_set_filter_heuristics_fixed() APIs are retained but deprecated
    +    and do nothing.
    +
    +Version 1.6.18beta07 [June 6, 2015]
    +  Removed non-working progressive reader 'skip' function. This
    +    function has apparently never been used. It was implemented
    +    to support back-door modification of png_struct in libpng-1.4.x
    +    but (because it does nothing and cannot do anything) was apparently
    +    never tested (John Bowler).
    +  Fixed cexcept.h in which GCC 5 now reports that one of the auto
    +    variables in the Try macro needs to be volatile to prevent value
    +    being lost over the setjmp (John Bowler).
    +  Fixed NO_WRITE_FILTER and -Wconversion build breaks (John Bowler).
    +  Fix g++ build breaks (John Bowler).
    +  Quieted some Coverity issues in pngfix.c, png-fix-itxt.c, pngvalid.c,
    +    pngstest.c, and pngimage.c. Most seem harmless, but png-fix-itxt
    +    would only work with iTXt chunks with length 255 or less.
    +  Added #ifdef's to contrib/examples programs so people don't try
    +    to compile them without the minimum required support enabled
    +    (suggested by Flavio Medeiros).
    +
    +Version 1.6.18beta08 [June 30, 2015]
    +  Eliminated the final two Coverity defects (insecure temporary file
    +    handling in contrib/libtests/pngstest.c; possible overflow of
    +    unsigned char in contrib/tools/png-fix-itxt.c). To use the "secure"
    +    file handling, define PNG_USE_MKSTEMP, otherwise "tmpfile()" will
    +    be used.
    +  Removed some unused WEIGHTED_FILTER macros from png.h and pngstruct.h
    +
    +Version 1.6.18beta09 [July 5, 2015]
    +  Removed some useless typecasts from contrib/tools/png-fix-itxt.c
    +  Fixed a new signed-unsigned comparison in pngrtran.c (Max Stepin).
    +  Replaced arbitrary use of 'extern' with #define PNG_LINKAGE_*.  To
    +    preserve API compatibility, the new defines all default to "extern"
    +    (requested by Jan Nijtmans).
    +
    +Version 1.6.18rc01 [July 9, 2015]
    +  Belatedly added Mans Rullgard and James Yu to the list of Contributing
    +    Authors.
    +
    +Version 1.6.18rc02 [July 12, 2015]
    +  Restored unused FILTER_HEURISTIC macros removed at libpng-1.6.18beta08
    +    to png.h to avoid compatibility warnings.
    +
    +Version 1.6.18rc03 [July 15, 2015]
    +  Minor changes to the man page
    +
    +Version 1.6.18 [July 23, 2015]
    +  No changes.
    +
    +Version 1.6.19beta01 [July 30, 2015]
    +  Updated obsolete information about the simplified API macros in the
    +    manual pages (Bug report by Arc Riley).
    +  Avoid potentially dereferencing NULL info_ptr in png_info_init_3().
    +  Rearranged png.h to put the major sections in the same order as
    +    in libpng17.
    +  Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and
    +    PNG_WEIGHT_FACTOR macros.
    +  Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler
    +    (Bug report by Viktor Szakats).  Several warnings remain and are
    +    unavoidable, where we test for overflow.
    +  Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
    +  Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
    +
    +Version 1.6.19beta02 [August 19, 2015]
    +  Moved config.h.in~ from the "libpng_autotools_files" list to the
    +    "libpng_autotools_extra" list in autogen.sh because it was causing a
    +    false positive for missing files (bug report by Robert C. Seacord).
    +  Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c
    +    to suppress clang warnings (Bug report by Viktor Szakats).
    +  Fixed some bad links in the man page.
    +  Changed "n bit" to "n-bit" in comments.
    +  Added signed/unsigned 16-bit safety net. This removes the dubious
    +    0x8000 flag definitions on 16-bit systems. They aren't supported
    +    yet the defs *probably* work, however it seems much safer to do this
    +    and be advised if anyone, contrary to advice, is building libpng 1.6
    +    on a 16-bit system. It also adds back various switch default clauses
    +    for GCC; GCC errors out if they are not present (with an appropriately
    +    high level of warnings).
    +  Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert
    +    Seacord).
    +  Fixed the recently reported 1's complement security issue by replacing
    +    the value that is illegal in the PNG spec, in both signed and unsigned
    +    values, with 0. Illegal unsigned values (anything greater than or equal
    +    to  0x80000000) can still pass through, but since these are not illegal
    +    in ANSI-C (unlike 0x80000000 in the signed case) the checking that
    +    occurs later can catch them (John Bowler).
    +
    +Version 1.6.19beta03 [September 26, 2015]
    +  Fixed png_save_int_32 when int is not 2's complement (John Bowler).
    +  Updated libpng16 with all the recent test changes from libpng17,
    +    including changes to pngvalid.c to ensure that the original,
    +    distributed, version of contrib/visupng/cexcept.h can be used
    +    (John Bowler).
    +  pngvalid contains the correction to the use of SAVE/STORE_
    +    UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More
    +    tests contain the --strict option to detect warnings and the
    +    pngvalid-standard test has been corrected so that it does not
    +    turn on progressive-read. There is a separate test which does
    +    that. (John Bowler)
    +  Also made some signed/unsigned fixes.
    +  Make pngstest error limits version specific. Splitting the machine
    +    generated error structs out to a file allows the values to be updated
    +    without changing pngstest.c itself. Since libpng 1.6 and 1.7 have
    +    slightly different error limits this simplifies maintenance. The
    +    makepngs.sh script has also been updated to more accurately reflect
    +    current problems in libpng 1.7 (John Bowler).
    +  Incorporated new test PNG files into make check.  tests/pngstest-*
    +    are changed so that the new test files are divided into 8 groups by
    +    gamma and alpha channel.  These tests have considerably better code
    +    and pixel-value coverage than contrib/pngsuite; however,coverage is
    +    still incomplete (John Bowler).
    +  Removed the '--strict' in 1.6 because of the double-gamma-correction
    +    warning, updated pngstest-errors.h for the errors detected with the
    +    new contrib/testspngs PNG test files (John Bowler).
    +
    +Version 1.6.19beta04 [October 15, 2015]
    +  Worked around rgb-to-gray issues in libpng 1.6.  The previous
    +    attempts to ignore the errors in the code aren't quite enough to
    +    deal with the 'channel selection' encoding added to libpng 1.7; abort.
    +    pngvalid.c is changed to drop this encoding in prior versions.
    +  Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a
    +    macro, therefore the argument list cannot contain preprocessing
    +    directives.  Make sure pow is a function where this happens. This is
    +    a minimal safe fix, the issue only arises in non-performance-critical
    +    code (bug report by Curtis Leach, fix by John Bowler).
    +  Added sPLT support to pngtest.c
    +
    +Version 1.6.19rc01 [October 23, 2015]
    +  No changes.
    +
    +Version 1.6.19rc02 [October 31, 2015]
    +  Prevent setting or writing over-length PLTE chunk (Cosmin Truta).
    +  Silently truncate over-length PLTE chunk while reading.
    +  Libpng incorrectly calculated the output rowbytes when the application
    +    decreased either the number of channels or the bit depth (or both) in
    +    a user transform.  This was safe; libpng overallocated buffer space
    +   (potentially by quite a lot; up to 4 times the amount required) but,
    +   from 1.5.4 on, resulted in a png_error (John Bowler).
    +
    +Version 1.6.19rc03 [November 3, 2015]
    +  Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed().
    +  Clarified COPYRIGHT information to state explicitly that versions
    +    are derived from previous versions.
    +  Removed much of the long list of previous versions from png.h and
    +    libpng.3.
    +
    +Version 1.6.19rc04 [November 5, 2015]
    +  Fixed new bug with CRC error after reading an over-length palette
    +    (bug report by Cosmin Truta) (CVE-2015-8126).
    +
    +Version 1.6.19 [November 12, 2015]
    +  Cleaned up coding style in png_handle_PLTE().
    +
    +Version 1.6.20beta01 [November 20, 2015]
    +  Avoid potential pointer overflow/underflow in png_handle_sPLT() and
    +    png_handle_pCAL() (Bug report by John Regehr).
    +
    +Version 1.6.20beta02 [November 23, 2015]
    +  Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
    +    not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
    +    vulnerability.  Fixes CVE-2015-8472.
    +
    +Version 1.6.20beta03 [November 24, 2015]
    +  Backported tests from libpng-1.7.0beta69.
    +
    +Version 1.6.20rc01 [November 26, 2015]
    +  Fixed an error in handling of bad zlib CMINFO field in pngfix, found by
    +    American Fuzzy Lop, reported by Brian Carpenter.  inflate() doesn't
    +    immediately fault a bad CMINFO field; instead a 'too far back' error
    +    happens later (at least some times).  pngfix failed to limit CMINFO to
    +    the allowed values but then assumed that window_bits was in range,
    +    triggering an assert. The bug is mostly harmless; the PNG file cannot
    +    be fixed.
    +
    +Version 1.6.20rc02 [November 29, 2015]
    +  In libpng 1.6 zlib initialization was changed to use the window size
    +    in the zlib stream, not a fixed value. This causes some invalid images,
    +    where CINFO is too large, to display 'correctly' if the rest of the
    +    data is valid.  This provides a workaround for zlib versions where the
    +    error arises (ones that support the API change to use the window size
    +    in the stream).
    +
    +Version 1.6.20 [December 3, 2015]
    +  No changes.
    +
    +Version 1.6.21beta01 [December 11, 2015]
    +  Fixed syntax "$(command)" in tests/pngstest that some shells other than
    +    bash could not parse (Bug report by Nelson Beebe). Use `command` instead.
    +
    +Version 1.6.21beta02 [December 14, 2015]
    +  Moved png_check_keyword() from pngwutil.c to pngset.c
    +  Removed LE/BE dependencies in pngvalid, to 'fix' the current problem
    +    in the BigEndian tests by not testing it, making the BE code the same 
    +    as the LE version.
    +  Fixes to pngvalid for various reduced build configurations (eliminate unused
    +    statics) and a fix for the case in rgb_to_gray when the digitize option
    +    reduces graylo to 0, producing a large error.
    +
    +Version 1.6.21beta03 [December 18, 2015]
    +  Widened the 'limit' check on the internally calculated error limits in
    +    the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error
    +    checks) and changed the check to only operate in non-release builds
    +    (base build type not RC or RELEASE.)
    +  Fixed undefined behavior in pngvalid.c, undefined because
    +    (png_byte) << shift is undefined if it changes the signed bit
    +    (because png_byte is promoted to int). The libpng exported functions
    +    png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by
    +    David Drysdale as a result of reports from UBSAN in clang 3.8).
    +  This changes pngvalid to use BE random numbers; this used to produce
    +    errors but these should not be fixed as a result of the previous changes.
    +
    +Version 1.6.21rc01 [January 4, 2016]
    +  In projects/vstudio, combined readme.txt and WARNING into README.txt
    +
    +Version 1.6.21rc02 [January 7, 2016]
    +  Relocated assert() in contrib/tools/pngfix.c, bug found by American
    +    Fuzzy Lop, reported by Brian Carpenter.
    +  Marked 'limit' UNUSED in transform_range_check().  This only affects
    +    release builds.
    +
    +Version 1.6.21 [January 15, 2016]
    +  Worked around a false-positive Coverity issue in pngvalid.c.
    +
    +Version 1.6.22beta01 [January 23, 2016]
    +  Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate
    +    "tmpfile()" implementation in contrib/libtests/pngstest.c
    +  Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io()
    +    if there is no stdio.h support.
    +  Added a png_image_write_to_memory() API and a number of assist macros
    +    to allow an application that uses the simplified API write to bypass
    +    stdio and write directly to memory.
    +  Added some warnings (png.h) and some check code to detect *possible*
    +    overflow in the ROW_STRIDE and simplified image SIZE macros.  This
    +    disallows image width/height/format that *might* overflow.  This is
    +    a quiet API change that limits in-memory image size (uncompressed) to
    +    less than 4GByte and image row size (stride) to less than 2GByte.
    +  Revised workaround for false-positive Coverity issue in pngvalid.c.
    +
    +Version 1.6.22beta02 [February 8, 2016]
    +  Only use exit(77) in configure builds.
    +  Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported
    +    the palette size because it failed to take into account that the memory
    +    palette has to be expanded to full RGB when it is written to PNG.
    +  Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in
    +    and test.cmake.in (Roger Leigh).
    +  Relaxed limit checks on gamma values in pngrtran.c. As suggested in
    +    the comments gamma values outside the range currently permitted
    +    by png_set_alpha_mode are useful for HDR data encoding.  These values
    +    are already permitted by png_set_gamma so it is reasonable caution to
    +    extend the png_set_alpha_mode range as HDR imaging systems are starting
    +    to emerge.
    +
    +Version 1.6.22beta03 [March 9, 2016]
    +  Added a common-law trademark notice and export control information
    +    to the LICENSE file, png.h, and the man page.
    +  Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that
    +    were accidentally removed from libpng-1.6.17. 
    +  Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h
    +    (Robert C. Seacord).
    +  Removed dubious "#if INT_MAX" test from png.h that was added to
    +    libpng-1.6.19beta02 (John Bowler).
    +  Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok).
    +  Updated LICENSE to say files in the contrib directory are not
    +    necessarily under the libpng license, and that some makefiles have
    +    other copyright owners.
    +  Added INTEL-SSE2 support (Mike Klein and Matt Sarett, Google, Inc.).
    +  Made contrib/libtests/timepng more robust.  The code no longer gives
    +    up/fails on invalid PNG data, it just skips it (with error messages).
    +    The code no longer fails on PNG files with data beyond IEND.  Options
    +    exist to use png_read_png (reading the whole image, not by row) and, in
    +    that case, to apply any of the supported transforms.  This makes for
    +    more realistic testing; the decoded data actually gets used in a
    +    meaningful fashion (John Bowler).
    +  Fixed some misleading indentation (Krishnaraj Bhat).
    +
    +Version 1.6.22beta04 [April 5, 2016]
    +  Force GCC compilation to C89 if needed (Dagobert Michelsen).
    +  SSE filter speed improvements for bpp=3:
    +    memcpy-free implementations of load3() / store3().
    +    call load3() only when needed at the end of a scanline.
    +
    +Version 1.6.22beta05 [April 27, 2016]
    +  Added PNG_FAST_FILTERS macro (defined as
    +    PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_UP).
    +  Various fixes for contrib/libtests/timepng.c
    +  Moved INTEL-SSE code from pngpriv.h into contrib/intel/intel_sse.patch.
    +  Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED
    +    (Bug report by Y.Ohashik).
    +
    +Version 1.6.22beta06 [May 5, 2016]
    +  Rebased contrib/intel_sse.patch.
    +  Quieted two Coverity issues in contrib/libtests/timepng.c.
    +  Fixed issues with scripts/genout.cmake.in (David Capello, Nixon Kwok):
    +    Added support to use multiple directories in ZLIBINCDIR variable,
    +    Fixed CMAKE_C_FLAGS with multiple values when genout is compiled on MSVC,
    +    Fixed pnglibconf.c compilation on OS X including the sysroot path.
    +
    +Version 1.6.22rc01 [May 14, 2016]
    +  No changes.
    +
    +Version 1.6.22rc02 [May 16, 2016]
    +  Removed contrib/timepng from default build; it does not build on platforms
    +    that don't supply clock_gettime().
    +
    +Version 1.6.22rc03 [May 17, 2016]
    +  Restored contrib/timepng to default build but check for the presence
    +    of clock_gettime() in configure.ac and Makefile.am.
    +
    +Version 1.6.22 [May 26, 2016]
    +  No changes.
    +
    +Version 1.6.23beta01 [May 29, 2016]
    +  Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying).
    +  Fixed the progressive reader to handle empty first IDAT chunk properly
    +    (patch by Timothy Nikkel).  This bug was introduced in libpng-1.6.0 and
    +    only affected the libpng16 branch.
    +  Added tests in pngvalid.c to check zero-length IDAT chunks in various
    +    positions.  Fixed the sequential reader to handle these more robustly
    +    (John Bowler).
    +
    +Version 1.6.23rc01 [June 2, 2016]
    +  Corrected progressive read input buffer in pngvalid.c. The previous version
    +    the code invariably passed just one byte at a time to libpng.  The intent
    +    was to pass a random number of bytes in the range 0..511.
    +  Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch.
    +  Added missing ")" in pngerror.c (Matt Sarrett).
    +
    +Version 1.6.23rc02 [June 4, 2016]
    +  Fixed undefined behavior in png_push_save_buffer(). Do not call
    +    memcpy() with a null source, even if count is zero (Leon Scroggins III).
    +
    +Version 1.6.23 [June 9, 2016]
    +  Fixed bad link to RFC2083 in png.5 (Nikola Forro).
    +
    +Version 1.6.24beta01 [June 11, 2016]
    +  Avoid potential overflow of the PNG_IMAGE_SIZE macro.  This macro
    +    is not used within libpng, but is used in some of the examples.
    +
    +Version 1.6.24beta02 [June 23, 2016]
    +  Correct filter heuristic overflow handling. This was broken when the
    +    write filter code was moved out-of-line; if there is a single filter and
    +    the heuristic sum overflows the calculation of the filtered line is not
    +    completed.  In versions prior to 1.6 the code was duplicated in-line
    +    and the check not performed, so the filter operation completed; however,
    +    in the multi-filter case where the sum is performed the 'none' filter would
    +    be selected if all the sums overflowed, even if it wasn't in the filter
    +    list.  The fix to the first problem is simply to provide PNG_SIZE_MAX as
    +    the current lmins sum value; this means the sum can never exceed it and
    +    overflows silently.  A reasonable compiler that does choose to inline
    +    the code will simply eliminate the sum check.
    +  The fix to the second problem is to use high precision arithmetic (this is
    +    implemented in 1.7), however a simple safe fix here is to chose the lowest
    +    numbered filter in the list from png_set_filter (this only works if the
    +    first problem is also fixed) (John Bowler).
    +  Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois).
    +  Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application
    +    as a result of the application using an increased 'row_stride'; previously
    +    png_image_finish_read only checked for overflow on the base calculation of
    +    components.  (I.e. it checked for overflow of a 32-bit number on the total
    +    number of pixel components in the output format, not the possibly padded row
    +    length and not the number of bytes, which for linear formats is twice the
    +    number of components.)
    +  MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned)
    +  MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless
    +    the conversion is explicitly invoked by a cast.
    +  Put the SKIP definition in the correct place. It needs to come after the
    +    png.h include (see all the other .c files in contrib/libtests) because it
    +    depends on PNG_LIBPNG_VER.
    +  Removed the three compile warning options from the individual project
    +    files into the zlib.props globals.  It increases the warning level from 4
    +    to All and adds a list of the warnings that need to be turned off.  This is
    +    semi-documentary; the intent is to tell libpng users which warnings have
    +    been examined and judged non-fixable at present.  The warning about
    +    structure padding is fixable, but it would be a significant change (moving
    +    structure members around).
    +
    +Version 1.6.24beta03 [July 4, 2016]
    +  Optimized absolute value calculation in filter selection, similar to
    +    code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to
    +    use this.
    +  Added pngcp to the build together with a pngcp.dfa configuration test.
    +  Added high resolution timing to pngcp.
    +  Added "Common linking failures" section to INSTALL.
    +  Relocated misplaced #endif in png.c sRGB profile checking.
    +  Fixed two Coverity issues in pngcp.c.
    +
    +Version 1.6.24beta04 [July 8, 2016]
    +  Avoid filter-selection heuristic sum calculations in cases where only one
    +    filter is a candidate for selection. This trades off code size (added
    +    private png_setup_*_row_only() functions) for speed.
    +
    +Version 1.6.24beta05 [July 13, 2016]
    +  Fixed some indentation to comply with our coding style.
    +  Added contrib/tools/reindent.
    +
    +Version 1.6.24beta06 [July 18, 2016]
    +  Fixed more indentation to comply with our coding style.
    +  Eliminated unnecessary tests of boolean png_isaligned() vs 0.
    +
    +Version 1.6.24rc01 [July 25, 2016]
    +  No changes.
    +
    +Version 1.6.24rc02 [August 1, 2016]
    +  Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch
    +  Conditionally compile png_decompress_chunk().
    +
    +Version 1.6.24rc03 [August 2, 2016]
    +  Conditionally compile ARM_NEON headers in pngpriv.h
    +  Updated contrib/intel/intel_sse.patch
    +
    +Version 1.6.24[August 4, 2016]
    +  No changes.
    +
    +Version 1.6.25beta01 [August 12, 2016]
    +  Reject oversized iCCP profile immediately.
    +  Cleaned up PNG_DEBUG compile of pngtest.c.
    +  Conditionally compile png_inflate().
    +
    +Version 1.6.25beta02 [August 18, 2016]
    +  Don't install pngcp; it conflicts with pngcp in the pngtools package.
    +  Minor editing of INSTALL, (whitespace, added copyright line)
    +
    +Version 1.6.25rc01 [August 24, 2016]
    +  No changes.
    +
    +Version 1.6.25rc02 [August 29, 2016]
    +  Added MIPS support (Mandar Sahastrabuddhe ).
    +  Only the UP filter is currently implemented.
    +
    +Version 1.6.25rc03 [August 29, 2016]
    +  Rebased contrib/intel/intel_sse.patch after the MIPS implementation.
    +
    +Version 1.6.25rc04 [August 30, 2016]
    +  Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe).
    +
    +Version 1.6.25rc05 [August 30, 2016]
    +  Rebased contrib/intel/intel_sse.patch after the MIPS implementation update..
    +
    +Version 1.6.25 [September 1, 2016]
    +  No changes.
    +
    +Version 1.6.26beta01 [September 26, 2016]
    +  Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo,
    +    bugfix by John Bowler).
    +  Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL
    +    has allocated memory that libpng needs to free.
    +  Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c
    +  Issue a png_benign_error instead of a png_error on ADLER32 mismatch
    +    while decoding compressed data chunks.
    +  Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and
    +    pngrutil.c.
    +  If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE,
    +    ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs.
    +  Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error().
    +  Add tests/badcrc.png and tests/badadler.png to tests/pngtest.
    +  Merged pngtest.c with libpng-1.7.0beta84/pngtest.c
    +
    +Version 1.6.26beta02 [October 1, 2016]
    +  Updated the documentation about CRC and ADLER32 handling.
    +  Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c,
    +     pngwrite.c, pngunknown.c, and pngvalid.c.
    +  Quieted 58 (out of 144) -Wconversion compiler warnings by changing
    +    flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes
    +    in png.c, pngread.c, and pngwutil.c.
    +
    +Version 1.6.26beta03 [October 2, 2016]
    +  Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs.
    +  Quieted the 86 remaining -Wconversion compiler warnings by
    +    revising the png_isaligned() macro and trivial changes in png.c,
    +    pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c,
    +    pngwtran.c, pngwrite.c, and pngwutil.c.
    +
    +Version 1.6.26beta04 [October 3, 2016]
    +  Quieted (bogus?) clang warnings about "absolute value has no effect"
    +    when PNG_USE_ABS is defined.
    +  Fixed offsets in contrib/intel/intel_sse.patch
    +
    +Version 1.6.26beta05 [October 6, 2016]
    +  Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h
    +    to avoid a signed/unsigned compare in the preprocessor.
    +
    +Version 1.6.26beta06 [October 7, 2016]
    +  Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to
    +    optionally avoid ADLER32 evaluation.
    +
    +Version 1.6.26rc01 [October 12, 2016]
    +  No changes.
    +
    +Version 1.6.26 [October 20, 2016]
    +  Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c
    +  Despammed email addresses (replaced "@" with " at ").
    +
    +Version 1.6.27beta01 [November 2, 2016]
    +  Restrict the new ADLER32-skipping to IDAT chunks.  It broke iCCP chunk
    +    handling: an erroneous iCCP chunk would throw a png_error and reject the
    +    entire PNG image instead of rejecting just the iCCP chunk with a warning,
    +    if built with zlib-1.2.8.1.
    +
    +Version 1.6.27rc01 [December 27, 2016]
    +  Control ADLER32 checking with new PNG_IGNORE_ADLER32 option. Fixes
    +    an endless loop when handling erroneous ADLER32 checksums; bug
    +    introduced in libpng-1.6.26.
    +  Removed the use of a macro containing the pre-processor 'defined'
    +    operator.  It is unclear whether this is valid; a macro that
    +    "generates" 'defined' is not permitted, but the use of the word
    +    "generates" within the C90 standard seems to imply more than simple
    +    substitution of an expression itself containing a well-formed defined
    +    operation.
    +  Added ARM support to CMakeLists.txt (Andreas Franek).
    +
    +Version 1.6.27 [December 29, 2016]
    +  Fixed a potential null pointer dereference in png_set_text_2() (bug report
    +    and patch by Patrick Keshishian, CVE-2016-10087).
    +
    +Version 1.6.28rc01 [January 3, 2017]
    +  Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna).
    +  Added option to Cmake build allowing a custom location of zlib to be
    +    specified in a scenario where libpng is being built as a subproject
    +    alongside zlib by another project (Sam Serrels).
    +  Changed png_ptr->options from a png_byte to png_uint_32, to accommodate
    +    up to 16 options.
    +
    +Version 1.6.28rc02 [January 4, 2017]
    +  Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
    +  Moved SSE2 optimization code into the main libpng source directory.
    +    Configure libpng with "configure --enable-intel-sse" or compile
    +    libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
    +
    +Version 1.6.28rc03 [January 4, 2017]
    +  Backed out the SSE optimization and last CMakeLists.txt to allow time for QA.
    +
    +Version 1.6.28 [January 5, 2017]
    +  No changes.
    +
    +Version 1.6.29beta01 [January 12, 2017]
    +  Readded "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
    +  Moved SSE2 optimization code into the main libpng source directory.
    +    Configure libpng with "configure --enable-intel-sse" or compile
    +    libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
    +  Simplified conditional compilation in pngvalid.c, for AIX (Michael Felt).
    +
    +Version 1.6.29beta02 [February 22, 2017]
    +  Avoid conditional directives that break statements in pngrutil.c (Romero
    +    Malaquias)
    +  The contrib/examples/pngtopng.c recovery code was in the wrong "if"
    +    branches; the comments were correct.
    +  Added code for PowerPC VSX optimisation (Vadim Barkov).
    +
    +Version 1.6.29beta03 [March 1, 2017]
    +  Avoid potential overflow of shift operations in png_do_expand() (Aaron Boxer).
    +  Change test ZLIB_VERNUM >= 0x1281 to ZLIB_VERNUM >= 0x1290 in pngrutil.c
    +    because Solaris 11 distributes zlib-1.2.8.f that is older than 1.2.8.1,
    +    as suggested in zlib FAQ, item 24.
    +  Suppress clang warnings about implicit sign changes in png.c
    +
    +Version 1.6.29 [March 16, 2017]
    +  No changes.
    +
    +Version 1.6.30beta01 [April 1, 2017]
    +  Added missing "$(CPPFLAGS)" to the compile line for c.pic.o in
    +    makefile.linux and makefile.solaris-x86 (Cosmin).
    +  Revised documentation of png_get_error_ptr() in the libpng manual.
    +  Silence clang -Wcomma and const drop warnings (Viktor Szakats).
    +  Update Sourceforge URLs in documentation (https instead of http).
    +
    +Version 1.6.30beta02 [April 22, 2017]
    +  Document need to check for integer overflow when allocating a pixel
    +    buffer for multiple rows in contrib/gregbook, contrib/pngminus,
    +    example.c, and in the manual (suggested by Jaeseung Choi). This
    +    is similar to the bug reported against pngquant in CVE-2016-5735.
    +  Removed reference to the obsolete PNG_SAFE_LIMITS macro in the documentation.
    +
    +Version 1.6.30beta03 [May 22, 2017]
    +  Check for integer overflow in contrib/visupng and contrib/tools/genpng.
    +  Do not double evaluate CMAKE_SYSTEM_PROCESSOR in CMakeLists.txt.
    +  Test CMAKE_HOST_WIN32 instead of WIN32 in CMakeLists.txt.
    +  Fix some URL in documentation.
    +
    +Version 1.6.30beta04 [June 7, 2017]
    +  Avoid writing an empty IDAT when the last IDAT exactly fills the
    +    compression buffer (bug report by Brian Baird). This bug was
    +    introduced in libpng-1.6.0.
    +
    +Version 1.6.30rc01 [June 14, 2017]
    +  No changes.
    +
    +Version 1.6.30rc02 [June 25, 2017]
    +  Update copyright year in pnglibconf.h, make ltmain.sh executable.
    +  Add a reference to the libpng.download site in README.
    +
    +Version 1.6.30 [June 28, 2017]
    +  No changes.
    +
    +Version 1.6.31beta01 [July 5, 2017]
    +  Guard the definition of _POSIX_SOURCE in pngpriv.h (AIX already defines it;
    +    bug report by Michael Felt).
    +  Revised pngpriv.h to work around failure to compile arm/filter_neon.S
    +    ("typedef" directive is unrecognized by the assembler). The problem
    +    was introduced in libpng-1.6.30beta01.
    +  Added "Requires: zlib" to libpng.pc.in (Pieter Neerincx).
    +  Added special case for FreeBSD in arm/filter_neon.S (Maya Rashish).
    +
    +Version 1.6.31beta02 [July 8, 2017]
    +  Added instructions for disabling hardware optimizations in INSTALL.
    +  Added "--enable-hardware-optimizations" configuration flag to enable
    +    or disable all hardware optimizations with one flag.
    +
    +Version 1.6.31beta03 [July 9, 2017]
    +  Updated CMakeLists.txt to add INTEL_SSE and MIPS_MSA platforms.
    +  Changed "int" to "png_size_t" in intel/filter_sse2.c to prevent
    +    possible integer overflow (Bug report by John Bowler).
    +  Quieted "declaration after statement" warnings in intel/filter_sse2.c.
    +  Added scripts/makefile-linux-opt, which has hardware optimizations enabled.
    +
    +Version 1.6.31beta04 [July 11, 2017]
    +  Removed one of the GCC-7.1.0 'strict-overflow' warnings that result when
    +    integers appear on both sides of a compare.  Worked around the others by
    +    forcing the strict-overflow setting in the relevant functions to a level
    +    where they are not reported (John Bowler).
    +  Changed "FALL THROUGH" comments to "FALLTHROUGH" because GCC doesn't like
    +    the space.
    +  Worked around some C-style casts from (void*) because g++ 5.4.0 objects
    +    to them.
    +  Increased the buffer size for 'sprint' to pass the gcc 7.1.0 'sprint
    +    overflow' check that is on by default with -Wall -Wextra.
    +
    +Version 1.6.31beta05 [July 13, 2017]
    +  Added eXIf chunk support.
    +
    +Version 1.6.31beta06 [July 17, 2017]
    +  Added a minimal eXIf chunk (with Orientation and FocalLengthIn35mmFilm
    +    tags) to pngtest.png.
    +
    +Version 1.6.31beta07 [July 18, 2017]
    +  Revised the eXIf chunk in pngtest.png to fix "Bad IFD1 Directory" warning.
    +
    +Version 1.6.31rc01 [July 19, 2017]
    +  No changes.
    +
    +Version 1.6.31rc02 [July 25, 2017]
    +  Fixed typo in example.c (png_free_image should be png_image_free) (Bug
    +    report by John Smith)
    +
    +Version 1.6.31 [July 27, 2017]
    +  No changes.
    +
    +Version 1.6.32beta01 [July 31, 2017]
    +  Avoid possible NULL dereference in png_handle_eXIf when benign_errors
    +    are allowed. Avoid leaking the input buffer "eXIf_buf".
    +  Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif
    +    to arguments for png_get_eXIf() and png_set_eXIf().
    +  Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in
    +    pngwrite.c, and made various other fixes to png_write_eXIf().
    +  Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and
    +    png_set_eXIf_1(), respectively, to avoid breaking API compatibility
    +    with libpng-1.6.31.
    +
    +Version 1.6.32beta02 [August 1, 2017]
    +  Updated contrib/libtests/pngunknown.c with eXIf chunk.
    +
    +Version 1.6.32beta03 [August 2, 2017]
    +  Initialized btoa[] in pngstest.c
    +  Stop memory leak when returning from png_handle_eXIf() with an error
    +    (Bug report from the OSS-fuzz project).
    +
    +Version 1.6.32beta04 [August 2, 2017]
    +  Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf().
    +  Update libpng.3 and libpng-manual.txt about eXIf functions.
    +
    +Version 1.6.32beta05 [August 2, 2017]
    +  Restored png_get_eXIf() and png_set_eXIf() to maintain API compatibility.
    +
    +Version 1.6.32beta06 [August 2, 2017]
    +  Removed png_get_eXIf_1() and png_set_eXIf_1().
    +
    +Version 1.6.32beta07 [August 3, 2017]
    +  Check length of all chunks except IDAT against user limit to fix an
    +    OSS-fuzz issue (Fixes CVE-2017-12652).
    +
    +Version 1.6.32beta08 [August 3, 2017]
    +  Check length of IDAT against maximum possible IDAT size, accounting
    +    for height, rowbytes, interlacing and zlib/deflate overhead.
    +  Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf)
    +    does not work (the eXIf chunk data can contain zeroes).
    +
    +Version 1.6.32beta09 [August 3, 2017]
    +  Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation,
    +    no longer using deprecated cmake LOCATION feature (Clifford Yapp).
    +  Fixed five-byte error in the calculation of IDAT maximum possible size.
    +  
    +Version 1.6.32beta10 [August 5, 2017]
    +  Moved chunk-length check into a png_check_chunk_length() private
    +    function (Suggested by Max Stepin).
    +  Moved bad pngs from tests to contrib/libtests/crashers
    +  Moved testing of bad pngs into a separate tests/pngtest-badpngs script
    +  Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL
    +    in the output but PASS for the libpng test.
    +  Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp).
    +  Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the
    +    num_exif argument to png_get_eXIf_1() (Github Issue 171).
    +
    +Version 1.6.32beta11 [August 7, 2017]
    +  Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks().
    +  Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers.
    +  Make pngtest --strict, --relax, --xfail options imply -m (multiple).
    +  Removed unused chunk_name parameter from png_check_chunk_length().
    +  Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak.
    +  Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue.
    +  Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR.
    +  Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue.
    +  Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account
    +    for the minimum 'deflate' stream, and relocate the test to a point
    +    after the keyword has been read.
    +  Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM".
    +
    +Version 1.6.32rc01 [August 18, 2017]
    +  Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers,
    +    one for each known chunk type, with length = 2GB-1.
    +  Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts
    +    in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706,
    +    and 162707).
    +  Renamed chunks in contrib/testpngs/crashers to avoid having files whose
    +    names differ only in case; this causes problems with some platforms
    +    (github issue #172).
    +
    +Version 1.6.32rc02 [August 22, 2017]
    +  Added contrib/oss-fuzz directory which contains files used by the oss-fuzz
    +    project (https://github.com/google/oss-fuzz/tree/master/projects/libpng).
    +
    +Version 1.6.32 [August 24, 2017]
    +  No changes.
    +
    +Version 1.6.33beta01 [August 28, 2017]
    +  Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing
    +    parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse).
    +  Fixed off-by-one error in png_do_check_palette_indexes() (Bug report
    +    by Mick P., Source Forge Issue #269).
    +
    +Version 1.6.33beta02 [September 3, 2017]
    +  Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
    +    to fix shortlived oss-fuzz issue 3234.
    +  Compute a larger limit on IDAT because some applications write a deflate
    +    buffer for each row (Bug report by Andrew Church).
    +  Use current date (DATE) instead of release-date (RDATE) in last
    +    changed date of contrib/oss-fuzz files.
    +  Enabled ARM support in CMakeLists.txt (Bernd Kuhls).
    +
    +Version 1.6.33beta03 [September 14, 2017]
    +  Fixed incorrect typecast of some arguments to png_malloc() and
    +    png_calloc() that were png_uint_32 instead of png_alloc_size_t
    +    (Bug report by "irwir" in Github libpng issue #175).
    +  Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github
    +    issue 162, by rcdailey).
    +
    +Version 1.6.33rc01 [September 20, 2017]
    +  Initialize memory allocated by png_inflate to zero, using memset, to
    +    stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2()
    +    due to truncated iTXt or zTXt chunk.
    +  Initialize memory allocated by png_read_buffer to zero, using memset, to
    +    stop an oss-fuzz "use of uninitialized value" detection in
    +    png_icc_check_tag_table() due to truncated iCCP chunk.
    +  Removed a redundant test (suggested by "irwir" in Github issue #180).
    +
    +Version 1.6.33rc02 [September 23, 2017]
    +  Added an interlaced version of each file in contrib/pngsuite.
    +  Relocate new memset() call in pngrutil.c.
    +  Removed more redundant tests (suggested by "irwir" in Github issue #180).
    +  Add support for loading images with associated alpha in the Simplified
    +    API (Samuel Williams).
    +
    +Version 1.6.33 [September 28, 2017]
    +  Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state.
    +  Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
    +  Add end_info structure and png_read_end() to the libpng fuzzer.
    +
    +Version 1.6.34 [September 29, 2017]
    +  Removed contrib/pngsuite/i*.png; some of them caused test failures.
    +
    +Version 1.6.35beta01 [March 6, 2018]
    +  Restored 21 of the contrib/pngsuite/i*.png, which do not cause test
    +    failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png.
    +  Added calls to png_set_*() transforms commonly used by browsers to
    +    the fuzzer.
    +  Removed some unnecessary brackets in pngrtran.c
    +  Fixed miscellaneous typos (Patch by github user "luzpaz").
    +  Change "ASM C" to "C ASM" in CMakeLists.txt
    +  Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin)
    +  Added hardware optimization directories to zip and 7z distributions.
    +  Fixed incorrect bitmask for options.
    +  Fixed many spelling typos.
    +
    +Version 1.6.35beta02 [March 28, 2018]
    +  Make png_get_iCCP consistent with man page (allow compression-type argument
    +  to be NULL, bug report by Lenard Szolnoki).
    +
    +Version 1.6.35 [July 15, 2018]
    +  Replaced the remaining uses of png_size_t with size_t (Cosmin)
    +  Fixed the calculation of row_factor in png_check_chunk_length
    +    (reported by Thuan Pham in SourceForge issue #278)
    +  Added missing parentheses to a macro definition
    +    (suggested by "irwir" in GitHub issue #216)
    +
    +Version 1.6.36 [December 1, 2018]
    +  Optimized png_do_expand_palette for ARM processors.
    +  Improved performance by around 10-22% on a recent ARM Chromebook.
    +    (Contributed by Richard Townsend, ARM Holdings)
    +  Fixed manipulation of machine-specific optimization options.
    +    (Contributed by Vicki Pfau)
    +  Used memcpy instead of manual pointer arithmetic on Intel SSE2.
    +    (Contributed by Samuel Williams)
    +  Fixed build errors with MSVC on ARM64.
    +    (Contributed by Zhijie Liang)
    +  Fixed detection of libm in CMakeLists.
    +    (Contributed by Cameron Cawley)
    +  Fixed incorrect creation of pkg-config file in CMakeLists.
    +    (Contributed by Kyle Bentley)
    +  Fixed the CMake build on Windows MSYS by avoiding symlinks.
    +  Fixed a build warning on OpenBSD.
    +    (Contributed by Theo Buehler)
    +  Fixed various typos in comments.
    +    (Contributed by "luz.paz")
    +  Raised the minimum required CMake version from 3.0.2 to 3.1.
    +  Removed yet more of the vestigial support for pre-ANSI C compilers.
    +  Removed ancient makefiles for ancient systems that have been broken
    +    across all previous libpng-1.6.x versions.
    +  Removed the Y2K compliance statement and the export control
    +    information.
    +  Applied various code style and documentation fixes.
    +
    +Version 1.6.37 [April 14, 2019]
    +  Fixed a use-after-free vulnerability (CVE-2019-7317) in png_image_free.
    +  Fixed a memory leak in the ARM NEON implementation of png_do_expand_palette.
    +  Fixed a memory leak in pngtest.c.
    +  Fixed two vulnerabilities (CVE-2018-14048, CVE-2018-14550) in
    +    contrib/pngminus; refactor.
    +  Changed the license of contrib/pngminus to MIT; refresh makefile and docs.
    +    (Contributed by Willem van Schaik)
    +  Fixed a typo in the libpng license v2.
    +    (Contributed by Miguel Ojeda)
    +  Added makefiles for AddressSanitizer-enabled builds.
    +  Cleaned up various makefiles.
    +
    +Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
    +Subscription is required; visit
    +https://lists.sourceforge.net/lists/listinfo/png-mng-implement
    +to subscribe.
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,134 @@
    +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
    +=========================================
    +
    +PNG Reference Library License version 2
    +---------------------------------------
    +
    + * Copyright (c) 1995-2019 The PNG Reference Library Authors.
    + * Copyright (c) 2018-2019 Cosmin Truta.
    + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
    + * Copyright (c) 1996-1997 Andreas Dilger.
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    +
    +The software is supplied "as is", without warranty of any kind,
    +express or implied, including, without limitation, the warranties
    +of merchantability, fitness for a particular purpose, title, and
    +non-infringement.  In no event shall the Copyright owners, or
    +anyone distributing the software, be liable for any damages or
    +other liability, whether in contract, tort or otherwise, arising
    +from, out of, or in connection with the software, or the use or
    +other dealings in the software, even if advised of the possibility
    +of such damage.
    +
    +Permission is hereby granted to use, copy, modify, and distribute
    +this software, or portions hereof, for any purpose, without fee,
    +subject to the following restrictions:
    +
    + 1. The origin of this software must not be misrepresented; you
    +    must not claim that you wrote the original software.  If you
    +    use this software in a product, an acknowledgment in the product
    +    documentation would be appreciated, but is not required.
    +
    + 2. Altered source versions must be plainly marked as such, and must
    +    not be misrepresented as being the original software.
    +
    + 3. This Copyright notice may not be removed or altered from any
    +    source or altered source distribution.
    +
    +
    +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
    +-----------------------------------------------------------------------
    +
    +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
    +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
    +derived from libpng-1.0.6, and are distributed according to the same
    +disclaimer and license as libpng-1.0.6 with the following individuals
    +added to the list of Contributing Authors:
    +
    +    Simon-Pierre Cadieux
    +    Eric S. Raymond
    +    Mans Rullgard
    +    Cosmin Truta
    +    Gilles Vollant
    +    James Yu
    +    Mandar Sahastrabuddhe
    +    Google Inc.
    +    Vadim Barkov
    +
    +and with the following additions to the disclaimer:
    +
    +    There is no warranty against interference with your enjoyment of
    +    the library or against infringement.  There is no warranty that our
    +    efforts or the library will fulfill any of your particular purposes
    +    or needs.  This library is provided with all faults, and the entire
    +    risk of satisfactory quality, performance, accuracy, and effort is
    +    with the user.
    +
    +Some files in the "contrib" directory and some configure-generated
    +files that are distributed with libpng have other copyright owners, and
    +are released under other open source licenses.
    +
    +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
    +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
    +libpng-0.96, and are distributed according to the same disclaimer and
    +license as libpng-0.96, with the following individuals added to the
    +list of Contributing Authors:
    +
    +    Tom Lane
    +    Glenn Randers-Pehrson
    +    Willem van Schaik
    +
    +libpng versions 0.89, June 1996, through 0.96, May 1997, are
    +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
    +and are distributed according to the same disclaimer and license as
    +libpng-0.88, with the following individuals added to the list of
    +Contributing Authors:
    +
    +    John Bowler
    +    Kevin Bracey
    +    Sam Bushell
    +    Magnus Holmgren
    +    Greg Roelofs
    +    Tom Tanner
    +
    +Some files in the "scripts" directory have other copyright owners,
    +but are released under this license.
    +
    +libpng versions 0.5, May 1995, through 0.88, January 1996, are
    +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    +
    +For the purposes of this copyright and license, "Contributing Authors"
    +is defined as the following set of individuals:
    +
    +    Andreas Dilger
    +    Dave Martindale
    +    Guy Eric Schalnat
    +    Paul Schmidt
    +    Tim Wegner
    +
    +The PNG Reference Library is supplied "AS IS".  The Contributing
    +Authors and Group 42, Inc. disclaim all warranties, expressed or
    +implied, including, without limitation, the warranties of
    +merchantability and of fitness for any purpose.  The Contributing
    +Authors and Group 42, Inc. assume no liability for direct, indirect,
    +incidental, special, exemplary, or consequential damages, which may
    +result from the use of the PNG Reference Library, even if advised of
    +the possibility of such damage.
    +
    +Permission is hereby granted to use, copy, modify, and distribute this
    +source code, or portions hereof, for any purpose, without fee, subject
    +to the following restrictions:
    +
    + 1. The origin of this source code must not be misrepresented.
    +
    + 2. Altered versions must be plainly marked as such and must not
    +    be misrepresented as being the original source.
    +
    + 3. This Copyright notice may not be removed or altered from any
    +    source or altered source distribution.
    +
    +The Contributing Authors and Group 42, Inc. specifically permit,
    +without fee, and encourage the use of this source code as a component
    +to supporting the PNG file format in commercial products.  If you use
    +this source code in a product, acknowledgment is not required but would
    +be appreciated.
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/png.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/png.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/png.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/png.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,4635 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* png.c - location for general purpose libpng functions
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +#include "pngpriv.h"
    +
    +/* Generate a compiler error if there is an old png.h in the search path. */
    +typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37;
    +
    +#ifdef __GNUC__
    +/* The version tests may need to be added to, but the problem warning has
    + * consistently been fixed in GCC versions which obtain wide-spread release.
    + * The problem is that many versions of GCC rearrange comparison expressions in
    + * the optimizer in such a way that the results of the comparison will change
    + * if signed integer overflow occurs.  Such comparisons are not permitted in
    + * ANSI C90, however GCC isn't clever enough to work out that that do not occur
    + * below in png_ascii_from_fp and png_muldiv, so it produces a warning with
    + * -Wextra.  Unfortunately this is highly dependent on the optimizer and the
    + * machine architecture so the warning comes and goes unpredictably and is
    + * impossible to "fix", even were that a good idea.
    + */
    +#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
    +#define GCC_STRICT_OVERFLOW 1
    +#endif /* GNU 7.1.x */
    +#endif /* GNU */
    +#ifndef GCC_STRICT_OVERFLOW
    +#define GCC_STRICT_OVERFLOW 0
    +#endif
    +
    +/* 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
    + * stream we can set num_bytes = 8 so that libpng will not attempt to read
    + * or write any of the magic bytes before it starts on the IHDR.
    + */
    +
    +#ifdef PNG_READ_SUPPORTED
    +void PNGAPI
    +png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
    +{
    +   unsigned int nb = (unsigned int)num_bytes;
    +
    +   png_debug(1, "in png_set_sig_bytes");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (num_bytes < 0)
    +      nb = 0;
    +
    +   if (nb > 8)
    +      png_error(png_ptr, "Too many bytes for PNG signature");
    +
    +   png_ptr->sig_bytes = (png_byte)nb;
    +}
    +
    +/* Checks whether the supplied bytes match the PNG signature.  We allow
    + * checking less than the full 8-byte signature so that those apps that
    + * already read the first few bytes of a file to determine the file type
    + * 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 behavior as strcmp, memcmp, etc).
    + */
    +int PNGAPI
    +png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
    +{
    +   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    +
    +   if (num_to_check > 8)
    +      num_to_check = 8;
    +
    +   else if (num_to_check < 1)
    +      return (-1);
    +
    +   if (start > 7)
    +      return (-1);
    +
    +   if (start + num_to_check > 8)
    +      num_to_check = 8 - start;
    +
    +   return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
    +}
    +
    +#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_alloc_size_t num_bytes = size;
    +
    +   if (png_ptr == NULL)
    +      return NULL;
    +
    +   if (items >= (~(png_alloc_size_t)0)/size)
    +   {
    +      png_warning (png_voidcast(png_structrp, png_ptr),
    +          "Potential overflow in png_zalloc()");
    +      return NULL;
    +   }
    +
    +   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_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_structrp png_ptr)
    +{
    +   /* 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
    + * much data to this routine as the largest single buffer size.  We
    + * also check that this data will actually be used before going to the
    + * trouble of calculating it.
    + */
    +void /* PRIVATE */
    +png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
    +{
    +   int need_crc = 1;
    +
    +   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 */
    +   {
    +      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
    +         need_crc = 0;
    +   }
    +
    +   /* '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;
    +#ifndef __COVERITY__
    +         if (safe_length == 0)
    +            safe_length = (uInt)-1; /* evil, but safe */
    +#endif
    +
    +         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.
    + */
    +int
    +png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
    +{
    +   /* Libpng versions 1.0.0 and later are binary compatible if the version
    +    * string matches through the second '.'; we must recompile any
    +    * applications that use any older library version.
    +    */
    +
    +   if (user_png_ver != NULL)
    +   {
    +      int i = -1;
    +      int found_dots = 0;
    +
    +      do
    +      {
    +         i++;
    +         if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
    +            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
    +         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) != 0)
    +   {
    +#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_STRING);
    +      PNG_UNUSED(pos)
    +
    +      png_warning(png_ptr, m);
    +#endif
    +
    +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
    +      png_ptr->flags = 0;
    +#endif
    +
    +      return 0;
    +   }
    +
    +   /* Success return. */
    +   return 1;
    +}
    +
    +/* 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))
    +#  endif
    +      {
    +#  ifdef PNG_SETJMP_SUPPORTED
    +         /* Temporarily fake out the longjmp information until we have
    +          * successfully completed this function.  This only works if we have
    +          * setjmp() support compiled in, but it is safe - this stuff should
    +          * never happen.
    +          */
    +         create_struct.jmp_buf_ptr = &create_jmp_buf;
    +         create_struct.jmp_buf_size = 0; /*stack allocation*/
    +         create_struct.longjmp_fn = longjmp;
    +#  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_const_structrp png_ptr),PNG_ALLOCATED)
    +{
    +   png_inforp info_ptr;
    +
    +   png_debug(1, "in png_create_info_struct");
    +
    +   if (png_ptr == NULL)
    +      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)
    +      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.  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_const_structrp png_ptr, png_infopp info_ptr_ptr)
    +{
    +   png_inforp info_ptr = NULL;
    +
    +   png_debug(1, "in png_destroy_info_struct");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (info_ptr_ptr != NULL)
    +      info_ptr = *info_ptr_ptr;
    +
    +   if (info_ptr != NULL)
    +   {
    +      /* 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.  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.
    + */
    +PNG_FUNCTION(void,PNGAPI
    +png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
    +    PNG_DEPRECATED)
    +{
    +   png_inforp info_ptr = *ptr_ptr;
    +
    +   png_debug(1, "in png_info_init_3");
    +
    +   if (info_ptr == NULL)
    +      return;
    +
    +   if ((sizeof (png_info)) > png_info_struct_size)
    +   {
    +      *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)));
    +      if (info_ptr == NULL)
    +         return;
    +      *ptr_ptr = info_ptr;
    +   }
    +
    +   /* Set everything to 0 */
    +   memset(info_ptr, 0, (sizeof *info_ptr));
    +}
    +
    +/* The following API is not called internally */
    +void PNGAPI
    +png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
    +    int freer, png_uint_32 mask)
    +{
    +   png_debug(1, "in png_data_freer");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   if (freer == PNG_DESTROY_WILL_FREE_DATA)
    +      info_ptr->free_me |= mask;
    +
    +   else if (freer == PNG_USER_WILL_FREE_DATA)
    +      info_ptr->free_me &= ~mask;
    +
    +   else
    +      png_error(png_ptr, "Unknown freer parameter in png_data_freer");
    +}
    +
    +void PNGAPI
    +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");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +#ifdef PNG_TEXT_SUPPORTED
    +   /* Free text item num or (if num == -1) all text items */
    +   if (info_ptr->text != NULL &&
    +       ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
    +   {
    +      if (num != -1)
    +      {
    +         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(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->max_text = 0;
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_tRNS_SUPPORTED
    +   /* Free any tRNS entry */
    +   if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
    +   {
    +      info_ptr->valid &= ~PNG_INFO_tRNS;
    +      png_free(png_ptr, info_ptr->trans_alpha);
    +      info_ptr->trans_alpha = NULL;
    +      info_ptr->num_trans = 0;
    +   }
    +#endif
    +
    +#ifdef PNG_sCAL_SUPPORTED
    +   /* Free any sCAL entry */
    +   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);
    +      info_ptr->scal_s_width = NULL;
    +      info_ptr->scal_s_height = NULL;
    +      info_ptr->valid &= ~PNG_INFO_sCAL;
    +   }
    +#endif
    +
    +#ifdef PNG_pCAL_SUPPORTED
    +   /* Free any pCAL entry */
    +   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 < info_ptr->pcal_nparams; i++)
    +               png_free(png_ptr, info_ptr->pcal_params[i]);
    +
    +            png_free(png_ptr, info_ptr->pcal_params);
    +            info_ptr->pcal_params = NULL;
    +         }
    +      info_ptr->valid &= ~PNG_INFO_pCAL;
    +   }
    +#endif
    +
    +#ifdef PNG_iCCP_SUPPORTED
    +   /* 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);
    +      info_ptr->iccp_name = NULL;
    +      info_ptr->iccp_profile = NULL;
    +      info_ptr->valid &= ~PNG_INFO_iCCP;
    +   }
    +#endif
    +
    +#ifdef PNG_sPLT_SUPPORTED
    +   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
    +   if (info_ptr->splt_palettes != NULL &&
    +       ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
    +   {
    +      if (num != -1)
    +      {
    +         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
    +      {
    +         int 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;
    +         info_ptr->splt_palettes_num = 0;
    +         info_ptr->valid &= ~PNG_INFO_sPLT;
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    +   if (info_ptr->unknown_chunks != NULL &&
    +       ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
    +   {
    +      if (num != -1)
    +      {
    +          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
    +          info_ptr->unknown_chunks[num].data = NULL;
    +      }
    +
    +      else
    +      {
    +         int i;
    +
    +         for (i = 0; i < info_ptr->unknown_chunks_num; i++)
    +            png_free(png_ptr, info_ptr->unknown_chunks[i].data);
    +
    +         png_free(png_ptr, info_ptr->unknown_chunks);
    +         info_ptr->unknown_chunks = NULL;
    +         info_ptr->unknown_chunks_num = 0;
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_eXIf_SUPPORTED
    +   /* Free any eXIf entry */
    +   if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
    +   {
    +# ifdef PNG_READ_eXIf_SUPPORTED
    +      if (info_ptr->eXIf_buf)
    +      {
    +         png_free(png_ptr, info_ptr->eXIf_buf);
    +         info_ptr->eXIf_buf = NULL;
    +      }
    +# endif
    +      if (info_ptr->exif)
    +      {
    +         png_free(png_ptr, info_ptr->exif);
    +         info_ptr->exif = NULL;
    +      }
    +      info_ptr->valid &= ~PNG_INFO_eXIf;
    +   }
    +#endif
    +
    +#ifdef PNG_hIST_SUPPORTED
    +   /* Free any hIST entry */
    +   if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
    +   {
    +      png_free(png_ptr, info_ptr->hist);
    +      info_ptr->hist = NULL;
    +      info_ptr->valid &= ~PNG_INFO_hIST;
    +   }
    +#endif
    +
    +   /* Free any PLTE entry that was internally allocated */
    +   if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
    +   {
    +      png_free(png_ptr, info_ptr->palette);
    +      info_ptr->palette = NULL;
    +      info_ptr->valid &= ~PNG_INFO_PLTE;
    +      info_ptr->num_palette = 0;
    +   }
    +
    +#ifdef PNG_INFO_IMAGE_SUPPORTED
    +   /* Free any image bits attached to the info structure */
    +   if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
    +   {
    +      if (info_ptr->row_pointers != NULL)
    +      {
    +         png_uint_32 row;
    +         for (row = 0; row < info_ptr->height; row++)
    +            png_free(png_ptr, info_ptr->row_pointers[row]);
    +
    +         png_free(png_ptr, info_ptr->row_pointers);
    +         info_ptr->row_pointers = NULL;
    +      }
    +      info_ptr->valid &= ~PNG_INFO_IDAT;
    +   }
    +#endif
    +
    +   if (num != -1)
    +      mask &= ~PNG_FREE_MUL;
    +
    +   info_ptr->free_me &= ~mask;
    +}
    +#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_const_structrp png_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return (NULL);
    +
    +   return (png_ptr->io_ptr);
    +}
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +#  ifdef PNG_STDIO_SUPPORTED
    +/* 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 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_structrp png_ptr, png_FILE_p fp)
    +{
    +   png_debug(1, "in png_init_io");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->io_ptr = (png_voidp)fp;
    +}
    +#  endif
    +
    +#  ifdef PNG_SAVE_INT_32_SUPPORTED
    +/* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90
    + * defines a cast of a signed integer to an unsigned integer either to preserve
    + * the value, if it is positive, or to calculate:
    + *
    + *     (UNSIGNED_MAX+1) + integer
    + *
    + * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
    + * negative integral value is added the result will be an unsigned value
    + * correspnding to the 2's complement representation.
    + */
    +void PNGAPI
    +png_save_int_32(png_bytep buf, png_int_32 i)
    +{
    +   png_save_uint_32(buf, (png_uint_32)i);
    +}
    +#  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.
    + */
    +int PNGAPI
    +png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
    +{
    +   static const char short_months[12][4] =
    +        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
    +         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    +
    +   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(out, 29, pos, (string))
    +#     define APPEND_NUMBER(format, value)\
    +         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
    +#     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)]);
    +      APPEND(' ');
    +      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
    +      APPEND(' ');
    +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
    +      APPEND(':');
    +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
    +      APPEND(':');
    +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
    +      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
    +      PNG_UNUSED (pos)
    +
    +#     undef APPEND
    +#     undef APPEND_NUMBER
    +#     undef APPEND_STRING
    +   }
    +
    +   return 1;
    +}
    +
    +#    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_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 /* LIBPNG_VER < 10700 */
    +#  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
    +   return PNG_STRING_COPYRIGHT
    +#else
    +   return PNG_STRING_NEWLINE \
    +      "libpng version 1.6.37" PNG_STRING_NEWLINE \
    +      "Copyright (c) 2018-2019 Cosmin Truta" PNG_STRING_NEWLINE \
    +      "Copyright (c) 1998-2002,2004,2006-2018 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;
    +#endif
    +}
    +
    +/* The following return the library version as a short string in the
    + * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
    + * used with your application, print out PNG_LIBPNG_VER_STRING, which
    + * is defined in png.h.
    + * Note: now there is no difference between png_get_libpng_ver() and
    + * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
    + * it is guaranteed that png.c uses the correct version of png.h.
    + */
    +png_const_charp PNGAPI
    +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_structrp png_ptr)
    +{
    +   /* Version of *.h files used when building libpng */
    +   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
    +   return PNG_LIBPNG_VER_STRING;
    +}
    +
    +png_const_charp PNGAPI
    +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 */
    +#ifdef __STDC__
    +   return PNG_HEADER_VERSION_STRING
    +#  ifndef PNG_READ_SUPPORTED
    +      " (NO READ SUPPORT)"
    +#  endif
    +      PNG_STRING_NEWLINE;
    +#else
    +   return PNG_HEADER_VERSION_STRING;
    +#endif
    +}
    +
    +#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 & 0xff);
    +      palette[i].green = (png_byte)(v & 0xff);
    +      palette[i].blue = (png_byte)(v & 0xff);
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    +int PNGAPI
    +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 */
    +   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 correctly.
    +    */
    +   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;
    +}
    +
    +#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_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 /* READ */
    +
    +/* This function was added to libpng-1.0.7 */
    +png_uint_32 PNGAPI
    +png_access_version_number(void)
    +{
    +   /* Version of *.c files used when building libpng */
    +   return((png_uint_32)PNG_LIBPNG_VER);
    +}
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +/* 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)
    +{
    +   /* 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;
    +   }
    +}
    +
    +/* 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_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 asymmetrical 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 /* GAMMA */
    +
    +#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).  We check
    +    * xy->whitey against 5, not 0, to avoid a possible integer overflow.
    +    */
    +   if (xy->redx   < 0 || xy->redx > PNG_FP_1) return 1;
    +   if (xy->redy   < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
    +   if (xy->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 < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
    +
    +   /* The reverse calculation is more difficult because the original tristimulus
    +    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
    +    * 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_colorspace_set_chromaticities(png_const_structrp png_ptr,
    +    png_colorspacerp colorspace, const png_xy *xy, int preferred)
    +{
    +   /* We must check the end points to ensure they are reasonable - in the past
    +    * color management systems have crashed as a result of getting bogus
    +    * 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");
    +   }
    +
    +   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");
    +   }
    +
    +   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;
    +
    +   /* 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 (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
    +      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
    +          (png_alloc_size_t)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",
    +         (png_alloc_size_t)intent, "inconsistent rendering intents");
    +
    +   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
    +   {
    +      png_benign_error(png_ptr, "duplicate sRGB information ignored");
    +      return 0;
    +   }
    +
    +   /* 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 };
    +
    +static int /* bool */
    +icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    +    png_const_charp name, png_uint_32 profile_length)
    +{
    +   if (profile_length < 132)
    +      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    +          "too short");
    +   return 1;
    +}
    +
    +#ifdef PNG_READ_iCCP_SUPPORTED
    +int /* PRIVATE */
    +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    +    png_const_charp name, png_uint_32 profile_length)
    +{
    +   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
    +      return 0;
    +
    +   /* This needs to be here because the 'normal' check is in
    +    * png_decompress_chunk, yet this happens after the attempt to
    +    * png_malloc_base the required data.  We only need this on read; on write
    +    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
    +    * the call to icc_check_length below (the write case).
    +    */
    +#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
    +      else if (png_ptr->user_chunk_malloc_max > 0 &&
    +               png_ptr->user_chunk_malloc_max < profile_length)
    +         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    +             "exceeds application limits");
    +#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
    +      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
    +         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    +             "exceeds libpng limits");
    +#  else /* !SET_USER_LIMITS */
    +      /* This will get compiled out on all 32-bit and better systems. */
    +      else if (PNG_SIZE_MAX < profile_length)
    +         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    +             "exceeds system limits");
    +#  endif /* !SET_USER_LIMITS */
    +
    +   return 1;
    +}
    +#endif /* READ_iCCP */
    +
    +int /* PRIVATE */
    +png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    +    png_const_charp name, png_uint_32 profile_length,
    +    png_const_bytep profile/* first 132 bytes only */, int color_type)
    +{
    +   png_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 accommodate 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)
    +   {
    +      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");
    +   }
    +
    +   /* 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)
    +   {
    +      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;
    +   }
    +
    +   /* 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)
    +   {
    +      case 0x58595a20: /* 'XYZ ' */
    +      case 0x4c616220: /* 'Lab ' */
    +         break;
    +
    +      default:
    +         return png_icc_profile_error(png_ptr, colorspace, name, temp,
    +             "unexpected ICC PCS encoding");
    +   }
    +
    +   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_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.
    +       */
    +
    +      /* 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");
    +
    +      if ((tag_start & 3) != 0)
    +      {
    +         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
    +          * only a warning here because libpng does not care about the
    +          * alignment.
    +          */
    +         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
    +             "ICC profile tag start not a multiple of 4");
    +      }
    +   }
    +
    +   return 1; /* success, maybe with warnings */
    +}
    +
    +#ifdef PNG_sRGB_SUPPORTED
    +#if 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)
    +   {
    +      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_uint_32) png_sRGB_checks[i].length &&
    +            intent == (png_uint_32) png_sRGB_checks[i].intent)
    +         {
    +            /* Now calculate the adler32 if not done already. */
    +            if (adler == 0)
    +            {
    +               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 0; /* no match */
    +}
    +
    +void /* PRIVATE */
    +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_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
    +      (void)png_colorspace_set_sRGB(png_ptr, colorspace,
    +         (int)/*already checked*/png_get_uint_32(profile+64));
    +}
    +#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
    +#endif /* sRGB */
    +
    +int /* PRIVATE */
    +png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
    +    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
    +    int color_type)
    +{
    +   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
    +      return 0;
    +
    +   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
    +       png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
    +           color_type) != 0 &&
    +       png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
    +           profile) != 0)
    +   {
    +#     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
    +         /* If no sRGB support, don't try storing sRGB information */
    +         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
    +#     endif
    +      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 /* READ_RGB_TO_GRAY */
    +
    +#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)
    +{
    +   int error = 0;
    +
    +   /* Check for width and height valid values */
    +   if (width == 0)
    +   {
    +      png_warning(png_ptr, "Image width is zero in IHDR");
    +      error = 1;
    +   }
    +
    +   if (width > PNG_UINT_31_MAX)
    +   {
    +      png_warning(png_ptr, "Invalid image width in IHDR");
    +      error = 1;
    +   }
    +
    +   if (png_gt(((width + 7) & (~7U)),
    +       ((PNG_SIZE_MAX
    +           - 48        /* big_row_buf hack */
    +           - 1)        /* filter byte */
    +           / 8)        /* 8-byte RGBA pixels */
    +           - 1))       /* 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;
    +   }
    +
    +#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;
    +   }
    +
    +   if (height > PNG_UINT_31_MAX)
    +   {
    +      png_warning(png_ptr, "Invalid image height 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;
    +   }
    +
    +   /* Check other values */
    +   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
    +       bit_depth != 8 && bit_depth != 16)
    +   {
    +      png_warning(png_ptr, "Invalid bit depth in IHDR");
    +      error = 1;
    +   }
    +
    +   if (color_type < 0 || color_type == 1 ||
    +       color_type == 5 || color_type > 6)
    +   {
    +      png_warning(png_ptr, "Invalid color type in IHDR");
    +      error = 1;
    +   }
    +
    +   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
    +       ((color_type == PNG_COLOR_TYPE_RGB ||
    +         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
    +         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
    +   {
    +      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
    +      error = 1;
    +   }
    +
    +   if (interlace_type >= PNG_INTERLACE_LAST)
    +   {
    +      png_warning(png_ptr, "Unknown interlace method in IHDR");
    +      error = 1;
    +   }
    +
    +   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
    +   {
    +      png_warning(png_ptr, "Unknown compression method in IHDR");
    +      error = 1;
    +   }
    +
    +#ifdef PNG_MNG_FEATURES_SUPPORTED
    +   /* Accept filter_method 64 (intrapixel differencing) only if
    +    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    +    * 2. Libpng did not read a PNG signature (this filter_method is only
    +    *    used in PNG datastreams that are embedded in MNG datastreams) and
    +    * 3. The application called png_permit_mng_features with a mask that
    +    *    included PNG_FLAG_MNG_FILTER_64 and
    +    * 4. The filter_method is 64 and
    +    * 5. The color_type is RGB or RGBA
    +    */
    +   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) != 0 &&
    +          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
    +          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
    +          (color_type == PNG_COLOR_TYPE_RGB ||
    +          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
    +      {
    +         png_warning(png_ptr, "Unknown filter method in IHDR");
    +         error = 1;
    +      }
    +
    +      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
    +      {
    +         png_warning(png_ptr, "Invalid filter method in IHDR");
    +         error = 1;
    +      }
    +   }
    +
    +#else
    +   if (filter_type != PNG_FILTER_TYPE_BASE)
    +   {
    +      png_warning(png_ptr, "Unknown filter method in IHDR");
    +      error = 1;
    +   }
    +#endif
    +
    +   if (error == 1)
    +      png_error(png_ptr, "Invalid IHDR data");
    +}
    +
    +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
    +/* ASCII to fp functions */
    +/* Check an ASCII formatted floating point value, see the more detailed
    + * comments in pngpriv.h
    + */
    +/* The following is used internally to preserve the sticky flags */
    +#define png_fp_add(state, flags) ((state) |= (flags))
    +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
    +
    +int /* PRIVATE */
    +png_check_fp_number(png_const_charp string, size_t size, int *statep,
    +    png_size_tp whereami)
    +{
    +   int state = *statep;
    +   size_t i = *whereami;
    +
    +   while (i < size)
    +   {
    +      int type;
    +      /* First find the type of the next character */
    +      switch (string[i])
    +      {
    +      case 43:  type = PNG_FP_SAW_SIGN;                   break;
    +      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
    +      case 46:  type = PNG_FP_SAW_DOT;                    break;
    +      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
    +      case 49: case 50: case 51: case 52:
    +      case 53: case 54: case 55: case 56:
    +      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
    +      case 69:
    +      case 101: type = PNG_FP_SAW_E;                      break;
    +      default:  goto PNG_FP_End;
    +      }
    +
    +      /* Now deal with this type according to the current
    +       * state, the type is arranged to not overlap the
    +       * bits of the PNG_FP_STATE.
    +       */
    +      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
    +      {
    +      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
    +         if ((state & PNG_FP_SAW_ANY) != 0)
    +            goto PNG_FP_End; /* not a part of the number */
    +
    +         png_fp_add(state, type);
    +         break;
    +
    +      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
    +         /* Ok as trailer, ok as lead of fraction. */
    +         if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
    +            goto PNG_FP_End;
    +
    +         else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
    +            png_fp_add(state, type);
    +
    +         else
    +            png_fp_set(state, PNG_FP_FRACTION | type);
    +
    +         break;
    +
    +      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
    +         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);
    +
    +         break;
    +
    +      case PNG_FP_INTEGER + PNG_FP_SAW_E:
    +         if ((state & PNG_FP_SAW_DIGIT) == 0)
    +            goto PNG_FP_End;
    +
    +         png_fp_set(state, PNG_FP_EXPONENT);
    +
    +         break;
    +
    +   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
    +         goto PNG_FP_End; ** no sign in fraction */
    +
    +   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
    +         goto PNG_FP_End; ** Because SAW_DOT is always set */
    +
    +      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
    +         png_fp_add(state, type | PNG_FP_WAS_VALID);
    +         break;
    +
    +      case PNG_FP_FRACTION + PNG_FP_SAW_E:
    +         /* This is correct because the trailing '.' on an
    +          * integer is handled above - so we can only get here
    +          * with the sequence ".E" (with no preceding digits).
    +          */
    +         if ((state & PNG_FP_SAW_DIGIT) == 0)
    +            goto PNG_FP_End;
    +
    +         png_fp_set(state, PNG_FP_EXPONENT);
    +
    +         break;
    +
    +      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
    +         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);
    +
    +         break;
    +
    +   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
    +         goto PNG_FP_End; */
    +
    +      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
    +         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
    +
    +         break;
    +
    +   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
    +         goto PNG_FP_End; */
    +
    +      default: goto PNG_FP_End; /* I.e. break 2 */
    +      }
    +
    +      /* The character seems ok, continue. */
    +      ++i;
    +   }
    +
    +PNG_FP_End:
    +   /* Here at the end, update the state and return the correct
    +    * return code.
    +    */
    +   *statep = state;
    +   *whereami = i;
    +
    +   return (state & PNG_FP_SAW_DIGIT) != 0;
    +}
    +
    +
    +/* The same but for a complete string. */
    +int
    +png_check_fp_string(png_const_charp string, size_t size)
    +{
    +   int        state=0;
    +   size_t char_index=0;
    +
    +   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 || sCAL */
    +
    +#ifdef PNG_sCAL_SUPPORTED
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +/* Utility used below - a simple accurate power of ten from an integral
    + * exponent.
    + */
    +static double
    +png_pow10(int power)
    +{
    +   int recip = 0;
    +   double d = 1;
    +
    +   /* Handle negative exponent with a reciprocal at the end because
    +    * 10 is exact whereas .1 is inexact in base 2
    +    */
    +   if (power < 0)
    +   {
    +      if (power < DBL_MIN_10_EXP) return 0;
    +      recip = 1; power = -power;
    +   }
    +
    +   if (power > 0)
    +   {
    +      /* Decompose power bitwise. */
    +      double mult = 10;
    +      do
    +      {
    +         if (power & 1) d *= mult;
    +         mult *= mult;
    +         power >>= 1;
    +      }
    +      while (power > 0);
    +
    +      if (recip != 0) d = 1/d;
    +   }
    +   /* else power is 0 and d is 1 */
    +
    +   return d;
    +}
    +
    +/* Function to format a floating point value in ASCII with a given
    + * precision.
    + */
    +#if GCC_STRICT_OVERFLOW
    +#pragma GCC diagnostic push
    +/* The problem arises below with exp_b10, which can never overflow because it
    + * comes, originally, from frexp and is therefore limited to a range which is
    + * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
    + */
    +#pragma GCC diagnostic warning "-Wstrict-overflow=2"
    +#endif /* GCC_STRICT_OVERFLOW */
    +void /* PRIVATE */
    +png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
    +    double fp, unsigned int precision)
    +{
    +   /* We use standard functions from math.h, but not printf because
    +    * that would require stdio.  The caller must supply a buffer of
    +    * sufficient size or we will png_error.  The tests on size and
    +    * the space in ascii[] consumed are indicated below.
    +    */
    +   if (precision < 1)
    +      precision = DBL_DIG;
    +
    +   /* Enforce the limit of the implementation precision too. */
    +   if (precision > DBL_DIG+1)
    +      precision = DBL_DIG+1;
    +
    +   /* Basic sanity checks */
    +   if (size >= precision+5) /* See the requirements below. */
    +   {
    +      if (fp < 0)
    +      {
    +         fp = -fp;
    +         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
    +         --size;
    +      }
    +
    +      if (fp >= DBL_MIN && fp <= DBL_MAX)
    +      {
    +         int exp_b10;   /* A base 10 exponent */
    +         double base;   /* 10^exp_b10 */
    +
    +         /* First extract a base 10 exponent of the number,
    +          * the calculation below rounds down when converting
    +          * from base 2 to base 10 (multiply by log10(2) -
    +          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
    +          * be increased.  Note that the arithmetic shift
    +          * performs a floor() unlike C arithmetic - using a
    +          * C multiply would break the following for negative
    +          * exponents.
    +          */
    +         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
    +
    +         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
    +
    +         /* Avoid underflow here. */
    +         base = png_pow10(exp_b10); /* May underflow */
    +
    +         while (base < DBL_MIN || base < fp)
    +         {
    +            /* And this may overflow. */
    +            double test = png_pow10(exp_b10+1);
    +
    +            if (test <= DBL_MAX)
    +            {
    +               ++exp_b10; base = test;
    +            }
    +
    +            else
    +               break;
    +         }
    +
    +         /* Normalize fp and correct exp_b10, after this fp is in the
    +          * range [.1,1) and exp_b10 is both the exponent and the digit
    +          * *before* which the decimal point should be inserted
    +          * (starting with 0 for the first digit).  Note that this
    +          * works even if 10^exp_b10 is out of range because of the
    +          * test on DBL_MAX above.
    +          */
    +         fp /= base;
    +         while (fp >= 1)
    +         {
    +            fp /= 10; ++exp_b10;
    +         }
    +
    +         /* Because of the code above fp may, at this point, be
    +          * less than .1, this is ok because the code below can
    +          * handle the leading zeros this generates, so no attempt
    +          * is made to correct that here.
    +          */
    +
    +         {
    +            unsigned int czero, clead, cdigits;
    +            char exponent[10];
    +
    +            /* Allow up to two leading zeros - this will not lengthen
    +             * the number compared to using E-n.
    +             */
    +            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
    +            {
    +               czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
    +               exp_b10 = 0;      /* Dot added below before first output. */
    +            }
    +            else
    +               czero = 0;    /* No zeros to add */
    +
    +            /* Generate the digit list, stripping trailing zeros and
    +             * inserting a '.' before a digit if the exponent is 0.
    +             */
    +            clead = czero; /* Count of leading zeros */
    +            cdigits = 0;   /* Count of digits in list. */
    +
    +            do
    +            {
    +               double d;
    +
    +               fp *= 10;
    +               /* Use modf here, not floor and subtract, so that
    +                * the separation is done in one step.  At the end
    +                * of the loop don't break the number into parts so
    +                * that the final digit is rounded.
    +                */
    +               if (cdigits+czero+1 < precision+clead)
    +                  fp = modf(fp, &d);
    +
    +               else
    +               {
    +                  d = floor(fp + .5);
    +
    +                  if (d > 9)
    +                  {
    +                     /* Rounding up to 10, handle that here. */
    +                     if (czero > 0)
    +                     {
    +                        --czero; d = 1;
    +                        if (cdigits == 0) --clead;
    +                     }
    +                     else
    +                     {
    +                        while (cdigits > 0 && d > 9)
    +                        {
    +                           int ch = *--ascii;
    +
    +                           if (exp_b10 != (-1))
    +                              ++exp_b10;
    +
    +                           else if (ch == 46)
    +                           {
    +                              ch = *--ascii; ++size;
    +                              /* Advance exp_b10 to '1', so that the
    +                               * decimal point happens after the
    +                               * previous digit.
    +                               */
    +                              exp_b10 = 1;
    +                           }
    +
    +                           --cdigits;
    +                           d = ch - 47;  /* I.e. 1+(ch-48) */
    +                        }
    +
    +                        /* Did we reach the beginning? If so adjust the
    +                         * exponent but take into account the leading
    +                         * decimal point.
    +                         */
    +                        if (d > 9)  /* cdigits == 0 */
    +                        {
    +                           if (exp_b10 == (-1))
    +                           {
    +                              /* Leading decimal point (plus zeros?), if
    +                               * we lose the decimal point here it must
    +                               * be reentered below.
    +                               */
    +                              int ch = *--ascii;
    +
    +                              if (ch == 46)
    +                              {
    +                                 ++size; exp_b10 = 1;
    +                              }
    +
    +                              /* Else lost a leading zero, so 'exp_b10' is
    +                               * still ok at (-1)
    +                               */
    +                           }
    +                           else
    +                              ++exp_b10;
    +
    +                           /* In all cases we output a '1' */
    +                           d = 1;
    +                        }
    +                     }
    +                  }
    +                  fp = 0; /* Guarantees termination below. */
    +               }
    +
    +               if (d == 0)
    +               {
    +                  ++czero;
    +                  if (cdigits == 0) ++clead;
    +               }
    +               else
    +               {
    +                  /* Included embedded zeros in the digit count. */
    +                  cdigits += czero - clead;
    +                  clead = 0;
    +
    +                  while (czero > 0)
    +                  {
    +                     /* exp_b10 == (-1) means we just output the decimal
    +                      * place - after the DP don't adjust 'exp_b10' any
    +                      * more!
    +                      */
    +                     if (exp_b10 != (-1))
    +                     {
    +                        if (exp_b10 == 0)
    +                        {
    +                           *ascii++ = 46; --size;
    +                        }
    +                        /* PLUS 1: TOTAL 4 */
    +                        --exp_b10;
    +                     }
    +                     *ascii++ = 48; --czero;
    +                  }
    +
    +                  if (exp_b10 != (-1))
    +                  {
    +                     if (exp_b10 == 0)
    +                     {
    +                        *ascii++ = 46; --size; /* counted above */
    +                     }
    +
    +                     --exp_b10;
    +                  }
    +                  *ascii++ = (char)(48 + (int)d); ++cdigits;
    +               }
    +            }
    +            while (cdigits+czero < precision+clead && fp > DBL_MIN);
    +
    +            /* The total output count (max) is now 4+precision */
    +
    +            /* Check for an exponent, if we don't need one we are
    +             * done and just need to terminate the string.  At this
    +             * point, exp_b10==(-1) is effectively a flag: it got
    +             * to '-1' because of the decrement, after outputting
    +             * the decimal point above. (The exponent required is
    +             * *not* -1.)
    +             */
    +            if (exp_b10 >= (-1) && exp_b10 <= 2)
    +            {
    +               /* The following only happens if we didn't output the
    +                * leading zeros above for negative exponent, so this
    +                * doesn't add to the digit requirement.  Note that the
    +                * two zeros here can only be output if the two leading
    +                * zeros were *not* output, so this doesn't increase
    +                * the output count.
    +                */
    +               while (exp_b10-- > 0) *ascii++ = 48;
    +
    +               *ascii = 0;
    +
    +               /* Total buffer requirement (including the '\0') is
    +                * 5+precision - see check at the start.
    +                */
    +               return;
    +            }
    +
    +            /* Here if an exponent is required, adjust size for
    +             * the digits we output but did not count.  The total
    +             * digit output here so far is at most 1+precision - no
    +             * decimal point and no leading or trailing zeros have
    +             * been output.
    +             */
    +            size -= cdigits;
    +
    +            *ascii++ = 69; --size;    /* 'E': PLUS 1 TOTAL 2+precision */
    +
    +            /* The following use of an unsigned temporary avoids ambiguities in
    +             * the signed arithmetic on exp_b10 and permits GCC at least to do
    +             * better optimization.
    +             */
    +            {
    +               unsigned int uexp_b10;
    +
    +               if (exp_b10 < 0)
    +               {
    +                  *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
    +                  uexp_b10 = 0U-exp_b10;
    +               }
    +
    +               else
    +                  uexp_b10 = 0U+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
    +             * this need not be considered above.
    +             */
    +            if (size > cdigits)
    +            {
    +               while (cdigits > 0) *ascii++ = exponent[--cdigits];
    +
    +               *ascii = 0;
    +
    +               return;
    +            }
    +         }
    +      }
    +      else if (!(fp >= DBL_MIN))
    +      {
    +         *ascii++ = 48; /* '0' */
    +         *ascii = 0;
    +         return;
    +      }
    +      else
    +      {
    +         *ascii++ = 105; /* 'i' */
    +         *ascii++ = 110; /* 'n' */
    +         *ascii++ = 102; /* 'f' */
    +         *ascii = 0;
    +         return;
    +      }
    +   }
    +
    +   /* Here on buffer too small. */
    +   png_error(png_ptr, "ASCII conversion buffer too small");
    +}
    +#if GCC_STRICT_OVERFLOW
    +#pragma GCC diagnostic pop
    +#endif /* GCC_STRICT_OVERFLOW */
    +
    +#  endif /* FLOATING_POINT */
    +
    +#  ifdef PNG_FIXED_POINT_SUPPORTED
    +/* Function to format a fixed point value in ASCII.
    + */
    +void /* PRIVATE */
    +png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
    +    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:
    +    */
    +   if (size > 12)
    +   {
    +      png_uint_32 num;
    +
    +      /* Avoid overflow here on the minimum integer. */
    +      if (fp < 0)
    +      {
    +         *ascii++ = 45; num = (png_uint_32)(-fp);
    +      }
    +      else
    +         num = (png_uint_32)fp;
    +
    +      if (num <= 0x80000000) /* else overflowed */
    +      {
    +         unsigned int ndigits = 0, first = 16 /* flag value */;
    +         char digits[10];
    +
    +         while (num)
    +         {
    +            /* Split the low digit off num: */
    +            unsigned int tmp = num/10;
    +            num -= tmp*10;
    +            digits[ndigits++] = (char)(48 + num);
    +            /* Record the first non-zero digit, note that this is a number
    +             * starting at 1, it's not actually the array index.
    +             */
    +            if (first == 16 && num > 0)
    +               first = ndigits;
    +            num = tmp;
    +         }
    +
    +         if (ndigits > 0)
    +         {
    +            while (ndigits > 5) *ascii++ = digits[--ndigits];
    +            /* The remaining digits are fractional digits, ndigits is '5' or
    +             * smaller at this point.  It is certainly not zero.  Check for a
    +             * non-zero fractional digit:
    +             */
    +            if (first <= 5)
    +            {
    +               unsigned int i;
    +               *ascii++ = 46; /* decimal point */
    +               /* ndigits may be <5 for small numbers, output leading zeros
    +                * then ndigits digits to first:
    +                */
    +               i = 5;
    +               while (ndigits < i)
    +               {
    +                  *ascii++ = 48; --i;
    +               }
    +               while (ndigits >= first) *ascii++ = digits[--ndigits];
    +               /* Don't output the trailing zeros! */
    +            }
    +         }
    +         else
    +            *ascii++ = 48;
    +
    +         /* And null terminate the string: */
    +         *ascii = 0;
    +         return;
    +      }
    +   }
    +
    +   /* Here on buffer too small. */
    +   png_error(png_ptr, "ASCII conversion buffer too small");
    +}
    +#   endif /* FIXED_POINT */
    +#endif /* SCAL */
    +
    +#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_fixed_point
    +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_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
    + * the nearest .00001).  Overflow and divide by zero are signalled in
    + * the result, a boolean - true on success, false on overflow.
    + */
    +#if GCC_STRICT_OVERFLOW /* from above */
    +/* It is not obvious which comparison below gets optimized in such a way that
    + * signed overflow would change the result; looking through the code does not
    + * reveal any tests which have the form GCC complains about, so presumably the
    + * optimizer is moving an add or subtract into the 'if' somewhere.
    + */
    +#pragma GCC diagnostic push
    +#pragma GCC diagnostic warning "-Wstrict-overflow=2"
    +#endif /* GCC_STRICT_OVERFLOW */
    +int
    +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
    +    png_int_32 divisor)
    +{
    +   /* Return a * times / divisor, rounded. */
    +   if (divisor != 0)
    +   {
    +      if (a == 0 || times == 0)
    +      {
    +         *res = 0;
    +         return 1;
    +      }
    +      else
    +      {
    +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    +         double r = a;
    +         r *= times;
    +         r /= divisor;
    +         r = floor(r+.5);
    +
    +         /* A png_fixed_point is a 32-bit integer. */
    +         if (r <= 2147483647. && r >= -2147483648.)
    +         {
    +            *res = (png_fixed_point)r;
    +            return 1;
    +         }
    +#else
    +         int negative = 0;
    +         png_uint_32 A, T, D;
    +         png_uint_32 s16, s32, s00;
    +
    +         if (a < 0)
    +            negative = 1, A = -a;
    +         else
    +            A = a;
    +
    +         if (times < 0)
    +            negative = !negative, T = -times;
    +         else
    +            T = times;
    +
    +         if (divisor < 0)
    +            negative = !negative, D = -divisor;
    +         else
    +            D = divisor;
    +
    +         /* Following can't overflow because the arguments only
    +          * have 31 bits each, however the result may be 32 bits.
    +          */
    +         s16 = (A >> 16) * (T & 0xffff) +
    +                           (A & 0xffff) * (T >> 16);
    +         /* Can't overflow because the a*times bit is only 30
    +          * bits at most.
    +          */
    +         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
    +         s00 = (A & 0xffff) * (T & 0xffff);
    +
    +         s16 = (s16 & 0xffff) << 16;
    +         s00 += s16;
    +
    +         if (s00 < s16)
    +            ++s32; /* carry */
    +
    +         if (s32 < D) /* else overflow */
    +         {
    +            /* s32.s00 is now the 64-bit product, do a standard
    +             * division, we know that s32 < D, so the maximum
    +             * required shift is 31.
    +             */
    +            int bitshift = 32;
    +            png_fixed_point result = 0; /* NOTE: signed */
    +
    +            while (--bitshift >= 0)
    +            {
    +               png_uint_32 d32, d00;
    +
    +               if (bitshift > 0)
    +                  d32 = D >> (32-bitshift), d00 = D << bitshift;
    +
    +               else
    +                  d32 = 0, d00 = D;
    +
    +               if (s32 > d32)
    +               {
    +                  if (s00 < d00) --s32; /* carry */
    +                  s32 -= d32, s00 -= d00, result += 1<= d00)
    +                     s32 = 0, s00 -= d00, result += 1<= (D >> 1))
    +               ++result;
    +
    +            if (negative != 0)
    +               result = -result;
    +
    +            /* Check for overflow. */
    +            if ((negative != 0 && result <= 0) ||
    +                (negative == 0 && result >= 0))
    +            {
    +               *res = result;
    +               return 1;
    +            }
    +         }
    +#endif
    +      }
    +   }
    +
    +   return 0;
    +}
    +#if GCC_STRICT_OVERFLOW
    +#pragma GCC diagnostic pop
    +#endif /* GCC_STRICT_OVERFLOW */
    +#endif /* READ_GAMMA || INCH_CONVERSIONS */
    +
    +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
    +/* The following is for when the caller doesn't much care about the
    + * result.
    + */
    +png_fixed_point
    +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) != 0)
    +      return result;
    +
    +   png_warning(png_ptr, "fixed point overflow ignored");
    +   return 0;
    +}
    +#endif
    +
    +#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)
    +{
    +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    +   double r = floor(1E10/a+.5);
    +
    +   if (r <= 2147483647. && r >= -2147483648.)
    +      return (png_fixed_point)r;
    +#else
    +   png_fixed_point res;
    +
    +   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
    +#ifdef PNG_16BIT_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
    +   double r = a * 1E-5;
    +   r *= b;
    +   r = floor(r+.5);
    +
    +   if (r <= 2147483647. && r >= -2147483648.)
    +      return (png_fixed_point)r;
    +#else
    +   png_fixed_point res;
    +
    +   if (png_muldiv(&res, a, b, 100000) != 0)
    +      return res;
    +#endif
    +
    +   return 0; /* overflow */
    +}
    +#endif /* 16BIT */
    +
    +/* The inverse of the above. */
    +png_fixed_point
    +png_reciprocal2(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
    +   if (a != 0 && b != 0)
    +   {
    +      double r = 1E15/a;
    +      r /= b;
    +      r = floor(r+.5);
    +
    +      if (r <= 2147483647. && r >= -2147483648.)
    +         return (png_fixed_point)r;
    +   }
    +#else
    +   /* This may overflow because the range of png_fixed_point isn't symmetric,
    +    * but this API is only used for the product of file and screen gamma so it
    +    * doesn't matter that the smallest number it can produce is 1/21474, not
    +    * 1/100000
    +    */
    +   png_fixed_point res = png_product2(a, b);
    +
    +   if (res != 0)
    +      return png_reciprocal(res);
    +#endif
    +
    +   return 0; /* overflow */
    +}
    +#endif /* READ_GAMMA */
    +
    +#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.
    + *
    + * 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 const png_uint_32
    +png_8bit_l2[128] =
    +{
    +   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
    +   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
    +   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
    +   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
    +   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
    +   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
    +   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
    +   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
    +   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
    +   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
    +   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
    +   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
    +   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
    +   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
    +   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
    +   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
    +   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
    +   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
    +   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
    +   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
    +    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
    +    * use these all the shifts below must be adjusted appropriately.
    +    */
    +   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
    +   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
    +   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
    +   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
    +   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
    +   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
    +   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
    +   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
    +   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
    +   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
    +   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
    +   1119, 744, 372
    +#endif
    +};
    +
    +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 -1 for the overflow (log 0) case, - so the result is
    +    * always at most 19 bits.
    +    */
    +   if ((x &= 0xff) == 0)
    +      return -1;
    +
    +   if ((x & 0xf0) == 0)
    +      lg2  = 4, x <<= 4;
    +
    +   if ((x & 0xc0) == 0)
    +      lg2 += 2, x <<= 2;
    +
    +   if ((x & 0x80) == 0)
    +      lg2 += 1, x <<= 1;
    +
    +   /* result is at most 19 bits, so this cast is safe: */
    +   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
    +}
    +
    +/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
    + * for 16-bit images we use the most significant 8 bits of the 16-bit value to
    + * get an approximation then multiply the approximation by a correction factor
    + * determined by the remaining up to 8 bits.  This requires an additional step
    + * in the 16-bit case.
    + *
    + * We want log2(value/65535), we have log2(v'/255), where:
    + *
    + *    value = v' * 256 + v''
    + *          = v' * f
    + *
    + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
    + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
    + * than 258.  The final factor also needs to correct for the fact that our 8-bit
    + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
    + *
    + * This gives a final formula using a calculated value 'x' which is value/v' and
    + * scaling by 65536 to match the above table:
    + *
    + *   log2(x/257) * 65536
    + *
    + * Since these numbers are so close to '1' we can use simple linear
    + * interpolation between the two end values 256/257 (result -368.61) and 258/257
    + * (result 367.179).  The values used below are scaled by a further 64 to give
    + * 16-bit precision in the interpolation:
    + *
    + * Start (256): -23591
    + * Zero  (257):      0
    + * End   (258):  23499
    + */
    +#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 -1;
    +
    +   if ((x & 0xff00) == 0)
    +      lg2  = 8, x <<= 8;
    +
    +   if ((x & 0xf000) == 0)
    +      lg2 += 4, x <<= 4;
    +
    +   if ((x & 0xc000) == 0)
    +      lg2 += 2, x <<= 2;
    +
    +   if ((x & 0x8000) == 0)
    +      lg2 += 1, x <<= 1;
    +
    +   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
    +    * value.
    +    */
    +   lg2 <<= 28;
    +   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
    +
    +   /* Now we need to interpolate the factor, this requires a division by the top
    +    * 8 bits.  Do this with maximum precision.
    +    */
    +   x = ((x << 16) + (x >> 9)) / (x >> 8);
    +
    +   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
    +    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
    +    * 16 bits to interpolate to get the low bits of the result.  Round the
    +    * answer.  Note that the end point values are scaled by 64 to retain overall
    +    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
    +    * the overall scaling by 6-12.  Round at every step.
    +    */
    +   x -= 1U << 24;
    +
    +   if (x <= 65536U) /* <= '257' */
    +      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
    +
    +   else
    +      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
    +
    +   /* 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 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.
    + *
    + * To deal with this the following exp() function works out the exponent of the
    + * fractional part of the logarithm by using an accurate 32-bit value from the
    + * top four fractional bits then multiplying in the remaining bits.
    + */
    +static const png_uint_32
    +png_32bit_exp[16] =
    +{
    +   /* 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,
    +   2553802834U, 2445529972U, 2341847524U, 2242560872U
    +};
    +
    +/* Adjustment table; provided to explain the numbers in the code below. */
    +#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
    +    9 45303.31936980687359311872
    +    8 45364.65110595323018870784
    +    7 45395.35850361789624614912
    +    6 45410.72259715102037508096
    +    5 45418.40724413220722311168
    +    4 45422.25021786898173001728
    +    3 45424.17186732298419044352
    +    2 45425.13273269940811464704
    +    1 45425.61317555035558641664
    +    0 45425.85339951654943850496
    +#endif
    +
    +static png_uint_32
    +png_exp(png_fixed_point x)
    +{
    +   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
    +   {
    +      /* Obtain a 4-bit approximation */
    +      png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
    +
    +      /* Incorporate the low 12 bits - these decrease the returned value by
    +       * multiplying by a number less than 1 if the bit is set.  The multiplier
    +       * is determined by the above table and the shift. Notice that the values
    +       * converge on 45426 and this is used to allow linear interpolation of the
    +       * low bits.
    +       */
    +      if (x & 0x800)
    +         e -= (((e >> 16) * 44938U) +  16U) >> 5;
    +
    +      if (x & 0x400)
    +         e -= (((e >> 16) * 45181U) +  32U) >> 6;
    +
    +      if (x & 0x200)
    +         e -= (((e >> 16) * 45303U) +  64U) >> 7;
    +
    +      if (x & 0x100)
    +         e -= (((e >> 16) * 45365U) + 128U) >> 8;
    +
    +      if (x & 0x080)
    +         e -= (((e >> 16) * 45395U) + 256U) >> 9;
    +
    +      if (x & 0x040)
    +         e -= (((e >> 16) * 45410U) + 512U) >> 10;
    +
    +      /* And handle the low 6 bits in a single block. */
    +      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
    +
    +      /* Handle the upper bits of x. */
    +      e >>= x >> 16;
    +      return e;
    +   }
    +
    +   /* Check for overflow */
    +   if (x <= 0)
    +      return png_32bit_exp[0];
    +
    +   /* Else underflow */
    +   return 0;
    +}
    +
    +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
    +    * second, rounding, step can't overflow because of the first, subtraction,
    +    * step.
    +    */
    +   x -= x >> 8;
    +   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
    +}
    +
    +#ifdef PNG_16BIT_SUPPORTED
    +static png_uint_16
    +png_exp16bit(png_fixed_point lg2)
    +{
    +   /* Get a 32-bit value: */
    +   png_uint_32 x = png_exp(lg2);
    +
    +   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
    +   x -= x >> 16;
    +   return (png_uint_16)((x + 32767U) >> 16);
    +}
    +#endif /* 16BIT */
    +#endif /* FLOATING_ARITHMETIC */
    +
    +png_byte
    +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
    +{
    +   if (value > 0 && value < 255)
    +   {
    +#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    +         /* '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) != 0)
    +            return png_exp8bit(res);
    +
    +         /* Overflow. */
    +         value = 0;
    +#     endif
    +   }
    +
    +   return (png_byte)(value & 0xff);
    +}
    +
    +#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
    +      /* The same (unsigned int)->(double) constraints apply here as above,
    +       * however in this case the (unsigned int) to (int) conversion can
    +       * overflow on an ANSI-C90 compliant system so the cast needs to ensure
    +       * that this is not possible.
    +       */
    +      double r = floor(65535*pow((png_int_32)value/65535.,
    +          gamma_val*.00001)+.5);
    +      return (png_uint_16)r;
    +# else
    +      png_int_32 lg2 = png_log16bit(value);
    +      png_fixed_point res;
    +
    +      if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
    +         return png_exp16bit(res);
    +
    +      /* Overflow. */
    +      value = 0;
    +# endif
    +   }
    +
    +   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
    + * is nominally a 16-bit value if bit depth is 8 then the result is
    + * 8-bit (as are the arguments.)
    + */
    +png_uint_16 /* PRIVATE */
    +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 */
    +}
    +
    +#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).
    + *
    + * The caller is responsible for ensuring that the table gets cleaned up on
    + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
    + * should be somewhere that will be cleaned.
    + */
    +static void
    +png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
    +    unsigned int shift, png_fixed_point gamma_val)
    +{
    +   /* Various values derived from 'shift': */
    +   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.)
    +    */
    +   double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1);
    +#endif
    +   unsigned int max = (1U << (16U - shift)) - 1U;
    +   unsigned int max_by_2 = 1U << (15U - shift);
    +   unsigned int i;
    +
    +   png_uint_16pp table = *ptable =
    +       (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 * (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) != 0)
    +      {
    +         /* The old code would overflow at the end and this would cause the
    +          * 'pow' function to return a result >1, resulting in an
    +          * arithmetic error.  This code follows the spec exactly; ig is
    +          * the recovered input sample, it always has 8-16 bits.
    +          *
    +          * We want input * 65535/max, rounded, the arithmetic fits in 32
    +          * bits (unsigned) so long as max <= 32767.
    +          */
    +         unsigned int j;
    +         for (j = 0; j < 256; j++)
    +         {
    +            png_uint_32 ig = (j << (8-shift)) + i;
    +#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    +               /* Inline the 'max' scaling operation: */
    +               /* 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 != 0)
    +                  ig = (ig * 65535U + max_by_2)/max;
    +
    +               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
    +#           endif
    +         }
    +      }
    +      else
    +      {
    +         /* We must still build a table, but do it the fast way. */
    +         unsigned int j;
    +
    +         for (j = 0; j < 256; j++)
    +         {
    +            png_uint_32 ig = (j << (8-shift)) + i;
    +
    +            if (shift != 0)
    +               ig = (ig * 65535U + max_by_2)/max;
    +
    +            sub_table[j] = (png_uint_16)ig;
    +         }
    +      }
    +   }
    +}
    +
    +/* NOTE: this function expects the *inverse* of the overall gamma transformation
    + * required.
    + */
    +static void
    +png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
    +    unsigned int shift, png_fixed_point gamma_val)
    +{
    +   unsigned int num = 1U << (8U - shift);
    +   unsigned int max = (1U << (16U - shift))-1U;
    +   unsigned int i;
    +   png_uint_32 last;
    +
    +   png_uint_16pp table = *ptable =
    +       (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 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 * (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.
    +    *
    +    * In the loop 'i' is used to find output values.  Since the output is
    +    * 8-bit there are only 256 possible values.  The tables are set up to
    +    * select the closest possible output value for each input by finding
    +    * the input value at the boundary between each pair of output values
    +    * and filling the table up to that boundary with the lower output
    +    * value.
    +    *
    +    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
    +    * values the code below uses a 16-bit value in i; the values start at
    +    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
    +    * entries are filled with 255).  Start i at 128 and fill all 'last'
    +    * table entries <= 'max'
    +    */
    +   last = 0;
    +   for (i = 0; i < 255; ++i) /* 8-bit output value */
    +   {
    +      /* Find the corresponding maximum input value */
    +      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
    +
    +      /* Find the boundary value in 16 bits: */
    +      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
    +
    +      /* Adjust (round) to (16-shift) bits: */
    +      bound = (bound * max + 32768U)/65535U + 1U;
    +
    +      while (last < bound)
    +      {
    +         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
    +         last++;
    +      }
    +   }
    +
    +   /* And fill in the final entries. */
    +   while (last < (num << 8))
    +   {
    +      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
    +      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.
    + */
    +static void
    +png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
    +    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) != 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 & 0xff);
    +}
    +
    +/* 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
    + * tables, we don't make a full table if we are reducing to 8-bit in
    + * the future.  Note also how the gamma_16 tables are segmented so that
    + * we don't need to allocate > 64K chunks for a full 16-bit table.
    + */
    +void /* PRIVATE */
    +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->colorspace.gamma,
    +          png_ptr->screen_gamma) : PNG_FP_1);
    +
    +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    +   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    +      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
    +      {
    +         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
    +             png_reciprocal(png_ptr->colorspace.gamma));
    +
    +         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
    +             png_ptr->screen_gamma > 0 ?
    +             png_reciprocal(png_ptr->screen_gamma) :
    +             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
    +      }
    +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
    +   }
    +#ifdef PNG_16BIT_SUPPORTED
    +   else
    +   {
    +      png_byte shift, sig_bit;
    +
    +      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
    +      {
    +         sig_bit = png_ptr->sig_bit.red;
    +
    +         if (png_ptr->sig_bit.green > sig_bit)
    +            sig_bit = png_ptr->sig_bit.green;
    +
    +         if (png_ptr->sig_bit.blue > sig_bit)
    +            sig_bit = png_ptr->sig_bit.blue;
    +      }
    +      else
    +         sig_bit = png_ptr->sig_bit.gray;
    +
    +      /* 16-bit gamma code uses this equation:
    +       *
    +       *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
    +       *
    +       * Where 'iv' is the input color value and 'ov' is the output value -
    +       * pow(iv, gamma).
    +       *
    +       * Thus the gamma table consists of up to 256 256-entry tables.  The table
    +       * is selected by the (8-gamma_shift) most significant of the low 8 bits
    +       * of the color value then indexed by the upper 8 bits:
    +       *
    +       *   table[low bits][high 8 bits]
    +       *
    +       * So the table 'n' corresponds to all those 'iv' of:
    +       *
    +       *   ..<(n+1 << gamma_shift)-1>
    +       *
    +       */
    +      if (sig_bit > 0 && sig_bit < 16U)
    +         /* shift == insignificant bits */
    +         shift = (png_byte)((16U - sig_bit) & 0xff);
    +
    +      else
    +         shift = 0; /* keep all 16 bits */
    +
    +      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
    +      {
    +         /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
    +          * the significant bits in the *input* when the output will
    +          * eventually be 8 bits.  By default it is 11.
    +          */
    +         if (shift < (16U - PNG_MAX_GAMMA_8))
    +            shift = (16U - PNG_MAX_GAMMA_8);
    +      }
    +
    +      if (shift > 8U)
    +         shift = 8U; /* Guarantees at least one table! */
    +
    +      png_ptr->gamma_shift = shift;
    +
    +      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
    +       * PNG_COMPOSE).  This effectively smashed the background calculation for
    +       * 16-bit output because the 8-bit table assumes the result will be
    +       * reduced to 8 bits.
    +       */
    +      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
    +          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
    +          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
    +          png_ptr->screen_gamma) : PNG_FP_1);
    +
    +      else
    +          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
    +          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
    +          png_ptr->screen_gamma) : PNG_FP_1);
    +
    +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    +   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    +      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
    +      {
    +         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
    +             png_reciprocal(png_ptr->colorspace.gamma));
    +
    +         /* Notice that the '16 from 1' table should be full precision, however
    +          * the lookup on this table still uses gamma_shift, so it can't be.
    +          * TODO: fix this.
    +          */
    +         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
    +             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
    +             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
    +      }
    +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
    +   }
    +#endif /* 16BIT */
    +}
    +#endif /* READ_GAMMA */
    +
    +/* 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)
    +   {
    +      png_uint_32 mask = 3U << option;
    +      png_uint_32 setting = (2U + (onoff != 0)) << option;
    +      png_uint_32 current = png_ptr->options;
    +
    +      png_ptr->options = (png_uint_32)((current & ~mask) | setting);
    +
    +      return (int)(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 https://en.wikipedia.org/wiki/SRGB)
    + * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
    + * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
    + * The 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)
    +   {
    +      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 */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,651 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngconf.h - machine-configurable file for libpng
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * libpng version 1.6.37
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * Any machine specific code is near the front of this file, so if you
    + * are configuring libpng for a machine, you may want to read the section
    + * starting here down to where it starts to typedef png_color, png_text,
    + * and png_info.
    + */
    +
    +#ifndef PNGCONF_H
    +#define PNGCONF_H
    +
    +#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 
    +#include 
    +
    +/* 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 
    +#endif
    +
    +#ifdef PNG_SETJMP_SUPPORTED
    +   /* Required for the definition of jmp_buf and the declaration of longjmp: */
    +#  include 
    +#endif
    +
    +#ifdef PNG_CONVERT_tIME_SUPPORTED
    +   /* Required for struct tm: */
    +#  include 
    +#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.
    + */
    +#define PNG_CONST const /* backward compatibility only */
    +
    +/* This controls optimization of the reading of 16-bit and 32-bit
    + * values from PNG files.  It can be set on a per-app-file basis: it
    + * just changes whether a macro is used when the function is called.
    + * The library builder sets the default; if read functions are not
    + * built into the library the macro implementation is forced on.
    + */
    +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
    +#  define PNG_USE_READ_MACROS
    +#endif
    +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
    +#  if PNG_DEFAULT_READ_MACROS
    +#    define PNG_USE_READ_MACROS
    +#  endif
    +#endif
    +
    +/* COMPILER SPECIFIC OPTIONS.
    + *
    + * These options are provided so that a variety of difficult compilers
    + * can be used.  Some are fixed at build time (e.g. PNG_API_RULE
    + * below) but still have compiler specific implementations, others
    + * may be changed on a per-file basis when compiling against libpng.
    + */
    +
    +/* 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
    +#  define PNGARG(arglist) arglist
    +#endif
    +
    +/* Function calling conventions.
    + * =============================
    + * Normally it is not necessary to specify to the compiler how to call
    + * a function - it just does it - however on x86 systems derived from
    + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
    + * and some others) there are multiple ways to call a function and the
    + * default can be changed on the compiler command line.  For this reason
    + * libpng specifies the calling convention of every exported function and
    + * every function called via a user supplied function pointer.  This is
    + * done in this file by defining the following macros:
    + *
    + * PNGAPI    Calling convention for exported functions.
    + * PNGCBAPI  Calling convention for user provided (callback) functions.
    + * PNGCAPI   Calling convention used by the ANSI-C library (required
    + *           for longjmp callbacks and sometimes used internally to
    + *           specify the calling convention for zlib).
    + *
    + * These macros should never be overridden.  If it is necessary to
    + * change calling convention in a private build this can be done
    + * by setting PNG_API_RULE (which defaults to 0) to one of the values
    + * below to select the correct 'API' variants.
    + *
    + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
    + *                This is correct in every known environment.
    + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and
    + *                the 'C' calling convention (from PNGCAPI) for
    + *                callbacks (PNGCBAPI).  This is no longer required
    + *                in any known environment - if it has to be used
    + *                please post an explanation of the problem to the
    + *                libpng mailing list.
    + *
    + * These cases only differ if the operating system does not use the C
    + * calling convention, at present this just means the above cases
    + * (x86 DOS/Windows systems) and, even then, this does not apply to
    + * Cygwin running on those systems.
    + *
    + * Note that the value must be defined in pnglibconf.h so that what
    + * the application uses to call the library matches the conventions
    + * set when building the library.
    + */
    +
    +/* Symbol export
    + * =============
    + * When building a shared library it is almost always necessary to tell
    + * the compiler which symbols to export.  The png.h macro 'PNG_EXPORT'
    + * is used to mark the symbols.  On some systems these symbols can be
    + * extracted at link time and need no special processing by the compiler,
    + * on other systems the symbols are flagged by the compiler and just
    + * the declaration requires a special tag applied (unfortunately) in a
    + * compiler dependent way.  Some systems can do either.
    + *
    + * A small number of older systems also require a symbol from a DLL to
    + * be flagged to the program that calls it.  This is a problem because
    + * we do not know in the header file included by application code that
    + * the symbol will come from a shared library, as opposed to a statically
    + * linked one.  For this reason the application must tell us by setting
    + * the magic flag PNG_USE_DLL to turn on the special processing before
    + * it includes png.h.
    + *
    + * Four additional macros are used to make this happen:
    + *
    + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
    + *            the build or imported if PNG_USE_DLL is set - compiler
    + *            and system specific.
    + *
    + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
    + *                       'type', compiler specific.
    + *
    + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to
    + *                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
    + *                PNG_USE_DLL is set.
    + */
    +
    +/* System specific discovery.
    + * ==========================
    + * 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 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__)
    +  /* 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
    +    * understood or because of a redefine just below you cannot use *this*
    +    * build of the library with the compiler you are using.  *This* build was
    +    * build using Watcom and applications must also be built using Watcom!
    +    */
    +#    define PNGCAPI __watcall
    +#  endif
    +
    +#  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
    +#    define PNGCAPI __cdecl
    +#    if PNG_API_RULE == 1
    +   /* If this line results in an error __stdcall is not understood and
    +    * PNG_API_RULE should not have been set to '1'.
    +    */
    +#      define PNGAPI __stdcall
    +#    endif
    +#  else
    +   /* An older compiler, or one not detected (erroneously) above,
    +    * if necessary override on the command line to get the correct
    +    * variants for the compiler.
    +    */
    +#    ifndef PNGCAPI
    +#      define PNGCAPI _cdecl
    +#    endif
    +#    if PNG_API_RULE == 1 && !defined(PNGAPI)
    +#      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"
    +#  endif
    +
    +#  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
    +      (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
    +   /* older Borland and MSC
    +    * compilers used '__export' and required this to be after
    +    * the type.
    +    */
    +#    ifndef PNG_EXPORT_TYPE
    +#      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
    +#    endif
    +#    define PNG_DLL_EXPORT __export
    +#  else /* newer compiler */
    +#    define PNG_DLL_EXPORT __declspec(dllexport)
    +#    ifndef PNG_DLL_IMPORT
    +#      define PNG_DLL_IMPORT __declspec(dllimport)
    +#    endif
    +#  endif /* compiler */
    +
    +#else /* !Windows */
    +#  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
    +#    define PNGAPI _System
    +#  else /* !Windows/x86 && !OS/2 */
    +   /* Use the defaults, or define PNG*API on the command line (but
    +    * this will have to be done for every compile!)
    +    */
    +#  endif /* other system, !OS/2 */
    +#endif /* !Windows/x86 */
    +
    +/* Now do all the defaulting . */
    +#ifndef PNGCAPI
    +#  define PNGCAPI
    +#endif
    +#ifndef PNGCBAPI
    +#  define PNGCBAPI PNGCAPI
    +#endif
    +#ifndef PNGAPI
    +#  define PNGAPI PNGCAPI
    +#endif
    +
    +/* 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
    +#  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
    +#    define PNG_IMPEXP
    +#  endif
    +#endif
    +
    +/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
    + * 'attributes' as a storage class - the attributes go at the start of the
    + * function definition, and attributes are always appended regardless of the
    + * compiler.  This considerably simplifies these macros but may cause problems
    + * if any compilers both need function attributes and fail to handle them as
    + * a storage class (this is unlikely.)
    + */
    +#ifndef PNG_FUNCTION
    +#  define PNG_FUNCTION(type, name, args, attributes) attributes type name args
    +#endif
    +
    +#ifndef PNG_EXPORT_TYPE
    +#  define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
    +#endif
    +
    +   /* The ordinal value is only relevant when preprocessing png.h for symbol
    +    * table entries, so we discard it here.  See the .dfn files in the
    +    * scripts directory.
    +    */
    +
    +#ifndef PNG_EXPORTA
    +#  define PNG_EXPORTA(ordinal, type, name, args, attributes) \
    +      PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
    +      PNG_LINKAGE_API attributes)
    +#endif
    +
    +/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
    + * so make something non-empty to satisfy the requirement:
    + */
    +#define PNG_EMPTY /*empty list*/
    +
    +#define PNG_EXPORT(ordinal, type, name, args) \
    +   PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
    +
    +/* Use PNG_REMOVED to comment out a removed interface. */
    +#ifndef PNG_REMOVED
    +#  define PNG_REMOVED(ordinal, type, name, args, attributes)
    +#endif
    +
    +#ifndef PNG_CALLBACK
    +#  define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
    +#endif
    +
    +/* Support for compiler specific function attributes.  These are used
    + * so that where compiler support is available incorrect use of API
    + * functions in png.h will generate compiler warnings.
    + *
    + * Added at libpng-1.2.41.
    + */
    +
    +#ifndef PNG_NO_PEDANTIC_WARNINGS
    +#  ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
    +#    define PNG_PEDANTIC_WARNINGS_SUPPORTED
    +#  endif
    +#endif
    +
    +#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
    +   * functions in png.h will generate compiler warnings.  Added at libpng
    +   * version 1.2.41.  Disabling these removes the warnings but may also produce
    +   * less efficient code.
    +   */
    +#  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
    +#    if __GNUC__ >= 3
    +#      ifndef PNG_ALLOCATED
    +#        define PNG_ALLOCATED  __attribute__((__malloc__))
    +#      endif
    +#      ifndef PNG_DEPRECATED
    +#        define PNG_DEPRECATED __attribute__((__deprecated__))
    +#      endif
    +#      ifndef PNG_PRIVATE
    +#        if 0 /* Doesn't work so we use deprecated instead*/
    +#          define PNG_PRIVATE \
    +            __attribute__((warning("This function is not exported by libpng.")))
    +#        else
    +#          define PNG_PRIVATE \
    +            __attribute__((__deprecated__))
    +#        endif
    +#      endif
    +#      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 */
    +
    +#  elif defined(_MSC_VER)  && (_MSC_VER >= 1300)
    +#    ifndef PNG_USE_RESULT
    +#      define PNG_USE_RESULT /* not supported */
    +#    endif
    +#    ifndef PNG_NORETURN
    +#      define PNG_NORETURN   __declspec(noreturn)
    +#    endif
    +#    ifndef PNG_ALLOCATED
    +#      if (_MSC_VER >= 1400)
    +#        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
    +
    +#  elif defined(__WATCOMC__)
    +#    ifndef PNG_RESTRICT
    +#      define PNG_RESTRICT __restrict
    +#    endif
    +#  endif
    +#endif /* PNG_PEDANTIC_WARNINGS */
    +
    +#ifndef PNG_DEPRECATED
    +#  define PNG_DEPRECATED  /* Use of this function is deprecated */
    +#endif
    +#ifndef PNG_USE_RESULT
    +#  define PNG_USE_RESULT  /* The result of this function must be checked */
    +#endif
    +#ifndef PNG_NORETURN
    +#  define PNG_NORETURN    /* This function does not return */
    +#endif
    +#ifndef PNG_ALLOCATED
    +#  define PNG_ALLOCATED   /* The result of the function is new memory */
    +#endif
    +#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);
    +#  else                   /* No floating point APIs */
    +#     define PNG_FP_EXPORT(ordinal, type, name, args)
    +#  endif
    +#endif
    +#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);
    +#  else                   /* No fixed point APIs */
    +#     define PNG_FIXED_EXPORT(ordinal, type, name, args)
    +#  endif
    +#endif
    +
    +#ifndef PNG_BUILDING_SYMBOL_TABLE
    +/* Some typedefs to get us started.  These should be safe on most of the common
    + * platforms.
    + *
    + * 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.
    + */
    +#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 > 4294967294U
    +   typedef unsigned int png_uint_32;
    +#elif ULONG_MAX > 4294967294U
    +   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 and ptrdiff_t.
    + * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
    + * behavior of sizeof and ptrdiff_t are required.
    + * The legacy typedefs are provided here for backwards compatibility.
    + */
    +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
    +
    +/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
    + * than png_uint_32.  Casts from 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 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 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.
    + */
    +
    +/* 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                  * 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 size_t                * png_size_tp;
    +typedef const size_t          * png_const_size_tp;
    +
    +#ifdef PNG_STDIO_SUPPORTED
    +typedef FILE            * png_FILE_p;
    +#endif
    +
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +typedef double       * png_doublep;
    +typedef const double * png_const_doublep;
    +#endif
    +
    +/* Pointers to pointers; i.e. arrays */
    +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          * * png_doublepp;
    +#endif
    +
    +/* Pointers to pointers to pointers; i.e., pointer to array */
    +typedef char            * * * png_charppp;
    +
    +#endif /* PNG_BUILDING_SYMBOL_TABLE */
    +
    +#endif /* PNGCONF_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngdebug.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngdebug.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngdebug.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngdebug.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,181 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +/* Define PNG_DEBUG at compile time for debugging information.  Higher
    + * numbers for PNG_DEBUG mean more debugging information.  This has
    + * only been added since version 0.95 so it is not implemented throughout
    + * libpng yet, but more support will be added as needed.
    + *
    + * png_debug[1-2]?(level, message ,arg{0-2})
    + *   Expands to a statement (either a simple expression or a compound
    + *   do..while(0) statement) that outputs a message with parameter
    + *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG
    + *   is undefined, 0 or 1 every png_debug expands to a simple expression
    + *   (actually ((void)0)).
    + *
    + *   level: level of detail of message, starting at 0.  A level 'n'
    + *          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
    + *            to the message.
    + *   arg: 0 to 2 arguments for printf(3) style substitution in message.
    + */
    +#ifndef PNGDEBUG_H
    +#define PNGDEBUG_H
    +/* These settings control the formatting of messages in png.c and pngerror.c */
    +/* Moved to pngdebug.h at 1.5.0 */
    +#  ifndef PNG_LITERAL_SHARP
    +#    define PNG_LITERAL_SHARP 0x23
    +#  endif
    +#  ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
    +#    define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
    +#  endif
    +#  ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
    +#    define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
    +#  endif
    +#  ifndef PNG_STRING_NEWLINE
    +#    define PNG_STRING_NEWLINE "\n"
    +#  endif
    +
    +#ifdef PNG_DEBUG
    +#  if (PNG_DEBUG > 0)
    +#    if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
    +#      include 
    +#      if (PNG_DEBUG > 1)
    +#        ifndef _DEBUG
    +#          define _DEBUG
    +#        endif
    +#        ifndef png_debug
    +#          define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
    +#        endif
    +#        ifndef png_debug1
    +#          define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
    +#        endif
    +#        ifndef png_debug2
    +#          define png_debug2(l,m,p1,p2) \
    +             _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
    +#        endif
    +#      endif
    +#    else /* PNG_DEBUG_FILE || !_MSC_VER */
    +#      ifndef PNG_STDIO_SUPPORTED
    +#        include  /* not included yet */
    +#      endif
    +#      ifndef PNG_DEBUG_FILE
    +#        define PNG_DEBUG_FILE stderr
    +#      endif /* PNG_DEBUG_FILE */
    +
    +#      if (PNG_DEBUG > 1)
    +#        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 ? "   " : \
    +         (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 ? "   " : \
    +         (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 ? "   " : \
    +         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1,p2);\
    +       } while (0)
    +#          endif
    +#        else /* __STDC __ */
    +#          ifndef png_debug
    +#            define png_debug(l,m) \
    +       do { \
    +       int num_tabs=l; \
    +       char format[256]; \
    +       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
    +         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
    +         m,PNG_STRING_NEWLINE); \
    +       fprintf(PNG_DEBUG_FILE,format); \
    +       } while (0)
    +#          endif
    +#          ifndef png_debug1
    +#            define png_debug1(l,m,p1) \
    +       do { \
    +       int num_tabs=l; \
    +       char format[256]; \
    +       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
    +         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
    +         m,PNG_STRING_NEWLINE); \
    +       fprintf(PNG_DEBUG_FILE,format,p1); \
    +       } while (0)
    +#          endif
    +#          ifndef png_debug2
    +#            define png_debug2(l,m,p1,p2) \
    +       do { \
    +       int num_tabs=l; \
    +       char format[256]; \
    +       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
    +         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
    +         m,PNG_STRING_NEWLINE); \
    +       fprintf(PNG_DEBUG_FILE,format,p1,p2); \
    +       } while (0)
    +#          endif
    +#        endif /* __STDC __ */
    +#      endif /* (PNG_DEBUG > 1) */
    +
    +#    endif /* _MSC_VER */
    +#  endif /* (PNG_DEBUG > 0) */
    +#endif /* PNG_DEBUG */
    +#ifndef png_debug
    +#  define png_debug(l, m) ((void)0)
    +#endif
    +#ifndef png_debug1
    +#  define png_debug1(l, m, p1) ((void)0)
    +#endif
    +#ifndef png_debug2
    +#  define png_debug2(l, m, p1, p2) ((void)0)
    +#endif
    +#endif /* PNGDEBUG_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngerror.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,991 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngerror.c - stub functions for i/o and memory allocation
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file provides a location for all error handling.  Users who
    + * need special error handling are expected to write replacement functions
    + * and use png_set_error_fn() to use those functions.  See the instructions
    + * at each function.
    + */
    +
    +#include "pngpriv.h"
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +
    +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_const_structrp png_ptr,
    +    png_const_charp warning_message));
    +#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,
    + * you should supply a replacement error function and use png_set_error_fn()
    + * to replace the error function at run-time.
    + */
    +#ifdef PNG_ERROR_TEXT_SUPPORTED
    +PNG_FUNCTION(void,PNGAPI
    +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)) != 0)
    +      {
    +         if (*error_message == PNG_LITERAL_SHARP)
    +         {
    +            /* Strip "#nnnn " from beginning of error message. */
    +            int offset;
    +            for (offset = 1; offset<15; offset++)
    +               if (error_message[offset] == ' ')
    +                  break;
    +
    +            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
    +            {
    +               int i;
    +               for (i = 0; i < offset - 1; i++)
    +                  msg[i] = error_message[i + 1];
    +               msg[i - 1] = '\0';
    +               error_message = msg;
    +            }
    +
    +            else
    +               error_message += offset;
    +         }
    +
    +         else
    +         {
    +            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
    +            {
    +               msg[0] = '0';
    +               msg[1] = '\0';
    +               error_message = msg;
    +            }
    +         }
    +      }
    +   }
    +#endif
    +   if (png_ptr != NULL && png_ptr->error_fn != NULL)
    +      (*(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. */
    +   png_default_error(png_ptr, error_message);
    +}
    +#else
    +PNG_FUNCTION(void,PNGAPI
    +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
    +    * apparently an error, introduced in libpng-1.2.20, and png_default_error
    +    * will crash in this case.
    +    */
    +   if (png_ptr != NULL && png_ptr->error_fn != NULL)
    +      (*(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 /* ERROR_TEXT */
    +
    +/* Utility to safely appends strings to a buffer.  This never errors out so
    + * error checking is not required in the caller.
    + */
    +size_t
    +png_safecat(png_charp buffer, size_t bufsize, size_t pos,
    +    png_const_charp string)
    +{
    +   if (buffer != NULL && pos < bufsize)
    +   {
    +      if (string != NULL)
    +         while (*string != '\0' && pos < bufsize-1)
    +           buffer[pos++] = *string++;
    +
    +      buffer[pos] = '\0';
    +   }
    +
    +   return pos;
    +}
    +
    +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
    +/* Utility to dump an unsigned value into a buffer, given a start pointer and
    + * and end pointer (which should point just *beyond* the end of the buffer!)
    + * Returns the pointer to the start of the formatted string.
    + */
    +png_charp
    +png_format_number(png_const_charp start, png_charp end, int format,
    +    png_alloc_size_t number)
    +{
    +   int count = 0;    /* number of digits output */
    +   int mincount = 1; /* minimum number required */
    +   int output = 0;   /* digit output (for the fixed point format) */
    +
    +   *--end = '\0';
    +
    +   /* This is written so that the loop always runs at least once, even with
    +    * number zero.
    +    */
    +   while (end > start && (number != 0 || count < mincount))
    +   {
    +
    +      static const char digits[] = "0123456789ABCDEF";
    +
    +      switch (format)
    +      {
    +         case PNG_NUMBER_FORMAT_fixed:
    +            /* Needs five digits (the fraction) */
    +            mincount = 5;
    +            if (output != 0 || number % 10 != 0)
    +            {
    +               *--end = digits[number % 10];
    +               output = 1;
    +            }
    +            number /= 10;
    +            break;
    +
    +         case PNG_NUMBER_FORMAT_02u:
    +            /* Expects at least 2 digits. */
    +            mincount = 2;
    +            /* FALLTHROUGH */
    +
    +         case PNG_NUMBER_FORMAT_u:
    +            *--end = digits[number % 10];
    +            number /= 10;
    +            break;
    +
    +         case PNG_NUMBER_FORMAT_02x:
    +            /* This format expects at least two digits */
    +            mincount = 2;
    +            /* FALLTHROUGH */
    +
    +         case PNG_NUMBER_FORMAT_x:
    +            *--end = digits[number & 0xf];
    +            number >>= 4;
    +            break;
    +
    +         default: /* an error */
    +            number = 0;
    +            break;
    +      }
    +
    +      /* Keep track of the number of digits added */
    +      ++count;
    +
    +      /* Float a fixed number here: */
    +      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 != 0)
    +            *--end = '.';
    +         else if (number == 0) /* and !output */
    +            *--end = '0';
    +      }
    +   }
    +
    +   return end;
    +}
    +#endif
    +
    +#ifdef PNG_WARNINGS_SUPPORTED
    +/* This function is called whenever there is a non-fatal error.  This function
    + * should not be changed.  If there is a need to handle warnings differently,
    + * you should supply a replacement warning function and use
    + * png_set_error_fn() to replace the warning function at run-time.
    + */
    +void PNGAPI
    +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)) != 0)
    +#endif
    +      {
    +         if (*warning_message == PNG_LITERAL_SHARP)
    +         {
    +            for (offset = 1; offset < 15; offset++)
    +               if (warning_message[offset] == ' ')
    +                  break;
    +         }
    +      }
    +   }
    +   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
    +      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
    +          warning_message + offset);
    +   else
    +      png_default_warning(png_ptr, warning_message + offset);
    +}
    +
    +/* These functions support 'formatted' warning messages with up to
    + * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter
    + * is introduced by @, where 'number' starts at 1.  This follows the
    + * standard established by X/Open for internationalizable error messages.
    + */
    +void
    +png_warning_parameter(png_warning_parameters p, int number,
    +    png_const_charp string)
    +{
    +   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
    +      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
    +}
    +
    +void
    +png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
    +    png_alloc_size_t value)
    +{
    +   char buffer[PNG_NUMBER_BUFFER_SIZE];
    +   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
    +}
    +
    +void
    +png_warning_parameter_signed(png_warning_parameters p, int number, int format,
    +    png_int_32 value)
    +{
    +   png_alloc_size_t u;
    +   png_charp str;
    +   char buffer[PNG_NUMBER_BUFFER_SIZE];
    +
    +   /* Avoid overflow by doing the negate in a png_alloc_size_t: */
    +   u = (png_alloc_size_t)value;
    +   if (value < 0)
    +      u = ~u + 1;
    +
    +   str = PNG_FORMAT_NUMBER(buffer, format, u);
    +
    +   if (value < 0 && str > buffer)
    +      *--str = '-';
    +
    +   png_warning_parameter(p, number, str);
    +}
    +
    +void
    +png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
    +    png_const_charp message)
    +{
    +   /* The internal buffer is just 192 bytes - enough for all our messages,
    +    * overflow doesn't happen because this code checks!  If someone figures
    +    * 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 = 0; /* Index in the msg[] buffer: */
    +   char msg[192];
    +
    +   /* 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')
    +   {
    +      /* '@' 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_char = *++message; /* Consume the '@' */
    +         static const char valid_parameters[] = "123456789";
    +         int parameter = 0;
    +
    +         /* 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;
    +
    +         /* 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];
    +            png_const_charp pend = p[parameter] + (sizeof p[parameter]);
    +
    +            /* No need to copy the trailing '\0' here, but there is no guarantee
    +             * that parm[] has been initialized, so there is no guarantee of a
    +             * trailing '\0':
    +             */
    +            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.  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++;
    +   }
    +
    +   /* i is always less than (sizeof msg), so: */
    +   msg[i] = '\0';
    +
    +   /* 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 /* WARNINGS */
    +
    +#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    +void PNGAPI
    +png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
    +{
    +   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
    +}
    +
    +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,
    + * 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))
    +static const char png_digit[16] = {
    +   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    +   'A', 'B', 'C', 'D', 'E', 'F'
    +};
    +
    +static void /* PRIVATE */
    +png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
    +    error_message)
    +{
    +   png_uint_32 chunk_name = png_ptr->chunk_name;
    +   int iout = 0, ishift = 24;
    +
    +   while (ishift >= 0)
    +   {
    +      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];
    +         buffer[iout++] = png_digit[c & 0x0f];
    +         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
    +      }
    +
    +      else
    +      {
    +         buffer[iout++] = (char)c;
    +      }
    +   }
    +
    +   if (error_message == NULL)
    +      buffer[iout] = '\0';
    +
    +   else
    +   {
    +      int iin = 0;
    +
    +      buffer[iout++] = ':';
    +      buffer[iout++] = ' ';
    +
    +      while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
    +         buffer[iout++] = error_message[iin++];
    +
    +      /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
    +      buffer[iout] = '\0';
    +   }
    +}
    +#endif /* WARNINGS || ERROR_TEXT */
    +
    +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
    +PNG_FUNCTION(void,PNGAPI
    +png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
    +    PNG_NORETURN)
    +{
    +   char msg[18+PNG_MAX_ERROR_TEXT];
    +   if (png_ptr == NULL)
    +      png_error(png_ptr, error_message);
    +
    +   else
    +   {
    +      png_format_buffer(png_ptr, msg, error_message);
    +      png_error(png_ptr, msg);
    +   }
    +}
    +#endif /* READ && ERROR_TEXT */
    +
    +#ifdef PNG_WARNINGS_SUPPORTED
    +void PNGAPI
    +png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
    +{
    +   char msg[18+PNG_MAX_ERROR_TEXT];
    +   if (png_ptr == NULL)
    +      png_warning(png_ptr, warning_message);
    +
    +   else
    +   {
    +      png_format_buffer(png_ptr, msg, warning_message);
    +      png_warning(png_ptr, msg);
    +   }
    +}
    +#endif /* WARNINGS */
    +
    +#ifdef PNG_READ_SUPPORTED
    +#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    +void PNGAPI
    +png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
    +    error_message)
    +{
    +   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 /* 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_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)
    +   unsigned int  iin;
    +   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
    +   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;
    +      }
    +   msg[fixed_message_ln + iin] = 0;
    +   png_error(png_ptr, msg);
    +}
    +#endif
    +#endif
    +
    +#ifdef PNG_SETJMP_SUPPORTED
    +/* This API only exists if ANSI-C style error handling is used,
    + * otherwise it is necessary for png_default_error to be overridden.
    + */
    +jmp_buf* PNGAPI
    +png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
    +    size_t jmp_buf_size)
    +{
    +   /* 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->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
    +
    +/* This is the default error handling function.  Note that replacements for
    + * this function MUST NOT RETURN, or the program will likely crash.  This
    + * function is used by default, or if the program supplies NULL for the
    + * error function pointer in png_set_error_fn().
    + */
    +static PNG_FUNCTION(void /* PRIVATE */,
    +png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
    +    PNG_NORETURN)
    +{
    +#ifdef PNG_CONSOLE_IO_SUPPORTED
    +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
    +   /* Check on NULL only added in 1.5.4 */
    +   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
    +   {
    +      /* Strip "#nnnn " from beginning of error message. */
    +      int offset;
    +      char error_number[16];
    +      for (offset = 0; offset<15; offset++)
    +      {
    +         error_number[offset] = error_message[offset + 1];
    +         if (error_message[offset] == ' ')
    +            break;
    +      }
    +
    +      if ((offset > 1) && (offset < 15))
    +      {
    +         error_number[offset - 1] = '\0';
    +         fprintf(stderr, "libpng error no. %s: %s",
    +             error_number, error_message + offset + 1);
    +         fprintf(stderr, PNG_STRING_NEWLINE);
    +      }
    +
    +      else
    +      {
    +         fprintf(stderr, "libpng error: %s, offset=%d",
    +             error_message, offset);
    +         fprintf(stderr, PNG_STRING_NEWLINE);
    +      }
    +   }
    +   else
    +#endif
    +   {
    +      fprintf(stderr, "libpng error: %s", error_message ? error_message :
    +         "undefined");
    +      fprintf(stderr, PNG_STRING_NEWLINE);
    +   }
    +#else
    +   PNG_UNUSED(error_message) /* Make compiler happy */
    +#endif
    +   png_longjmp(png_ptr, 1);
    +}
    +
    +PNG_FUNCTION(void,PNGAPI
    +png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
    +{
    +#ifdef PNG_SETJMP_SUPPORTED
    +   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
    +
    +   /* 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();
    +}
    +
    +#ifdef PNG_WARNINGS_SUPPORTED
    +/* 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 them to.  In the default configuration, png_ptr is
    + * not used, but it is passed in case it may be useful.
    + */
    +static void /* PRIVATE */
    +png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
    +{
    +#ifdef PNG_CONSOLE_IO_SUPPORTED
    +#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
    +   if (*warning_message == PNG_LITERAL_SHARP)
    +   {
    +      int offset;
    +      char warning_number[16];
    +      for (offset = 0; offset < 15; offset++)
    +      {
    +         warning_number[offset] = warning_message[offset + 1];
    +         if (warning_message[offset] == ' ')
    +            break;
    +      }
    +
    +      if ((offset > 1) && (offset < 15))
    +      {
    +         warning_number[offset + 1] = '\0';
    +         fprintf(stderr, "libpng warning no. %s: %s",
    +             warning_number, warning_message + offset);
    +         fprintf(stderr, PNG_STRING_NEWLINE);
    +      }
    +
    +      else
    +      {
    +         fprintf(stderr, "libpng warning: %s",
    +             warning_message);
    +         fprintf(stderr, PNG_STRING_NEWLINE);
    +      }
    +   }
    +   else
    +#  endif
    +
    +   {
    +      fprintf(stderr, "libpng warning: %s", warning_message);
    +      fprintf(stderr, PNG_STRING_NEWLINE);
    +   }
    +#else
    +   PNG_UNUSED(warning_message) /* Make compiler happy */
    +#endif
    +   PNG_UNUSED(png_ptr) /* Make compiler happy */
    +}
    +#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->jmp_buf_ptr, 1)
    + */
    +void PNGAPI
    +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)
    +      return;
    +
    +   png_ptr->error_ptr = error_ptr;
    +   png_ptr->error_fn = error_fn;
    +#ifdef PNG_WARNINGS_SUPPORTED
    +   png_ptr->warning_fn = warning_fn;
    +#else
    +   PNG_UNUSED(warning_fn)
    +#endif
    +}
    +
    +
    +/* This function returns a pointer to the error_ptr associated with the user
    + * functions.  The application should free any memory associated with this
    + * pointer before png_write_destroy and png_read_destroy are called.
    + */
    +png_voidp PNGAPI
    +png_get_error_ptr(png_const_structrp png_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return NULL;
    +
    +   return ((png_voidp)png_ptr->error_ptr);
    +}
    +
    +
    +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
    +void PNGAPI
    +png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
    +{
    +   if (png_ptr != NULL)
    +   {
    +      png_ptr->flags &=
    +         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
    +         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
    +   }
    +}
    +#endif
    +
    +#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)
    +{
    +   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)
    +{
    +   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 */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1277 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngget.c - retrieval of values from info struct
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + */
    +
    +#include "pngpriv.h"
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +
    +png_uint_32 PNGAPI
    +png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
    +    png_uint_32 flag)
    +{
    +   if (png_ptr != NULL && info_ptr != NULL)
    +      return(info_ptr->valid & flag);
    +
    +   return(0);
    +}
    +
    +size_t PNGAPI
    +png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
    +{
    +   if (png_ptr != NULL && info_ptr != NULL)
    +      return(info_ptr->rowbytes);
    +
    +   return(0);
    +}
    +
    +#ifdef PNG_INFO_IMAGE_SUPPORTED
    +png_bytepp PNGAPI
    +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);
    +
    +   return(0);
    +}
    +#endif
    +
    +#ifdef PNG_EASY_ACCESS_SUPPORTED
    +/* Easy access to info, added in libpng-0.99 */
    +png_uint_32 PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_uint_32 PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_byte PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_byte PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_byte PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_byte PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_byte PNGAPI
    +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;
    +
    +   return (0);
    +}
    +
    +png_uint_32 PNGAPI
    +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) != 0)
    +      {
    +         png_debug1(1, "in %s retrieval function",
    +             "png_get_x_pixels_per_meter");
    +
    +         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_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) != 0)
    +   {
    +      png_debug1(1, "in %s retrieval function",
    +          "png_get_y_pixels_per_meter");
    +
    +      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_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) != 0)
    +   {
    +      png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
    +
    +      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
    +          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);
    +}
    +
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +float PNGAPI
    +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) != 0)
    +   {
    +      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
    +
    +      if (info_ptr->x_pixels_per_unit != 0)
    +         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);
    +}
    +#endif
    +
    +#ifdef PNG_FIXED_POINT_SUPPORTED
    +png_fixed_point PNGAPI
    +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) != 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;
    +
    +      png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
    +
    +      /* The following casts work because a PNG 4 byte integer only has a valid
    +       * 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) != 0)
    +         return res;
    +   }
    +#else
    +   PNG_UNUSED(png_ptr)
    +   PNG_UNUSED(info_ptr)
    +#endif
    +
    +   return 0;
    +}
    +#endif
    +
    +png_int_32 PNGAPI
    +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) != 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_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) != 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_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) != 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_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) != 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);
    +}
    +
    +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
    +static png_uint_32
    +ppi_from_ppm(png_uint_32 ppm)
    +{
    +#if 0
    +   /* The conversion is *(2.54/100), in binary (32 digits):
    +    * .00000110100000001001110101001001
    +    */
    +   png_uint_32 t1001, t1101;
    +   ppm >>= 1;                  /* .1 */
    +   t1001 = ppm + (ppm >> 3);   /* .1001 */
    +   t1101 = t1001 + (ppm >> 1); /* .1101 */
    +   ppm >>= 20;                 /* .000000000000000000001 */
    +   t1101 += t1101 >> 15;       /* .1101000000000001101 */
    +   t1001 >>= 11;               /* .000000000001001 */
    +   t1001 += t1001 >> 12;       /* .000000000001001000000001001 */
    +   ppm += t1001;               /* .000000000001001000001001001 */
    +   ppm += t1101;               /* .110100000001001110101001001 */
    +   return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
    +#else
    +   /* The argument is a PNG unsigned integer, so it is not permitted
    +    * to be bigger than 2^31.
    +    */
    +   png_fixed_point result;
    +   if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
    +       5000) != 0)
    +      return (png_uint_32)result;
    +
    +   /* Overflow. */
    +   return 0;
    +#endif
    +}
    +
    +png_uint_32 PNGAPI
    +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_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_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_const_structrp png_ptr, png_int_32 microns)
    +{
    +   /* Convert from meters * 1,000,000 to inches * 100,000, meters to
    +    * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
    +    * Notice that this can overflow - a warning is output and 0 is
    +    * returned.
    +    */
    +   return png_muldiv_warn(png_ptr, microns, 500, 127);
    +}
    +
    +png_fixed_point PNGAPI
    +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));
    +}
    +#endif
    +
    +#ifdef PNG_FIXED_POINT_SUPPORTED
    +png_fixed_point PNGAPI
    +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));
    +}
    +#endif
    +
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +float PNGAPI
    +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.
    +    */
    +   return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
    +}
    +#endif
    +
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +float PNGAPI
    +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.
    +    */
    +   return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
    +}
    +#endif
    +
    +#ifdef PNG_pHYs_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0)
    +   {
    +      png_debug1(1, "in %s retrieval function", "pHYs");
    +
    +      if (res_x != NULL)
    +      {
    +         *res_x = info_ptr->x_pixels_per_unit;
    +         retval |= PNG_INFO_pHYs;
    +      }
    +
    +      if (res_y != NULL)
    +      {
    +         *res_y = info_ptr->y_pixels_per_unit;
    +         retval |= PNG_INFO_pHYs;
    +      }
    +
    +      if (unit_type != NULL)
    +      {
    +         *unit_type = (int)info_ptr->phys_unit_type;
    +         retval |= PNG_INFO_pHYs;
    +
    +         if (*unit_type == 1)
    +         {
    +            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
    +            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
    +         }
    +      }
    +   }
    +
    +   return (retval);
    +}
    +#endif /* pHYs */
    +#endif /* INCH_CONVERSIONS */
    +
    +/* png_get_channels really belongs in here, too, but it's been around longer */
    +
    +#endif /* EASY_ACCESS */
    +
    +
    +png_byte PNGAPI
    +png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
    +{
    +   if (png_ptr != NULL && info_ptr != NULL)
    +      return(info_ptr->channels);
    +
    +   return (0);
    +}
    +
    +#ifdef PNG_READ_SUPPORTED
    +png_const_bytep PNGAPI
    +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_structrp png_ptr, png_inforp info_ptr,
    +    png_color_16p *background)
    +{
    +   if (png_ptr != NULL && info_ptr != NULL &&
    +       (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
    +       background != NULL)
    +   {
    +      png_debug1(1, "in %s retrieval function", "bKGD");
    +
    +      *background = &(info_ptr->background);
    +      return (PNG_INFO_bKGD);
    +   }
    +
    +   return (0);
    +}
    +#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_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)
    +{
    +   /* 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->colorspace.end_points_xy.whitex, "cHRM white X");
    +      if (white_y != NULL)
    +         *white_y = png_float(png_ptr,
    +             info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
    +      if (red_x != NULL)
    +         *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->colorspace.end_points_xy.redy,
    +             "cHRM red Y");
    +      if (green_x != NULL)
    +         *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->colorspace.end_points_xy.greeny, "cHRM green Y");
    +      if (blue_x != NULL)
    +         *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
    +             "cHRM blue X");
    +      if (blue_y != NULL)
    +         *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);
    +   }
    +
    +   return (0);
    +}
    +#  endif
    +
    +#  ifdef PNG_FIXED_POINT_SUPPORTED
    +png_uint_32 PNGAPI
    +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->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    +   {
    +      if (white_x != NULL)
    +         *white_x = info_ptr->colorspace.end_points_xy.whitex;
    +      if (white_y != NULL)
    +         *white_y = info_ptr->colorspace.end_points_xy.whitey;
    +      if (red_x != NULL)
    +         *red_x = info_ptr->colorspace.end_points_xy.redx;
    +      if (red_y != NULL)
    +         *red_y = info_ptr->colorspace.end_points_xy.redy;
    +      if (green_x != NULL)
    +         *green_x = info_ptr->colorspace.end_points_xy.greenx;
    +      if (green_y != NULL)
    +         *green_y = info_ptr->colorspace.end_points_xy.greeny;
    +      if (blue_x != NULL)
    +         *blue_x = info_ptr->colorspace.end_points_xy.bluex;
    +      if (blue_y != NULL)
    +         *blue_y = info_ptr->colorspace.end_points_xy.bluey;
    +      return (PNG_INFO_cHRM);
    +   }
    +
    +   return (0);
    +}
    +#  endif
    +#endif
    +
    +#ifdef PNG_gAMA_SUPPORTED
    +#  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->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
    +       file_gamma != NULL)
    +   {
    +      *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_structrp png_ptr, png_const_inforp info_ptr,
    +    double *file_gamma)
    +{
    +   png_debug1(1, "in %s retrieval function", "gAMA(float)");
    +
    +   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 (0);
    +}
    +#  endif
    +#endif
    +
    +#ifdef PNG_sRGB_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 && file_srgb_intent != NULL)
    +   {
    +      *file_srgb_intent = info_ptr->colorspace.rendering_intent;
    +      return (PNG_INFO_sRGB);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_iCCP_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 &&
    +       name != NULL && profile != NULL && proflen != NULL)
    +   {
    +      *name = info_ptr->iccp_name;
    +      *profile = info_ptr->iccp_profile;
    +      *proflen = png_get_uint_32(info_ptr->iccp_profile);
    +      /* This is somewhat irrelevant since the profile data returned has
    +       * actually been uncompressed.
    +       */
    +      if (compression_type != NULL)
    +         *compression_type = PNG_COMPRESSION_TYPE_BASE;
    +      return (PNG_INFO_iCCP);
    +   }
    +
    +   return (0);
    +
    +}
    +#endif
    +
    +#ifdef PNG_sPLT_SUPPORTED
    +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 info_ptr->splt_palettes_num;
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_eXIf_SUPPORTED
    +png_uint_32 PNGAPI
    +png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
    +    png_bytep *exif)
    +{
    +  png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
    +  PNG_UNUSED(info_ptr)
    +  PNG_UNUSED(exif)
    +  return 0;
    +}
    +
    +png_uint_32 PNGAPI
    +png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
    +    png_uint_32 *num_exif, png_bytep *exif)
    +{
    +   png_debug1(1, "in %s retrieval function", "eXIf");
    +
    +   if (png_ptr != NULL && info_ptr != NULL &&
    +       (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
    +   {
    +      *num_exif = info_ptr->num_exif;
    +      *exif = info_ptr->exif;
    +      return (PNG_INFO_eXIf);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_hIST_SUPPORTED
    +png_uint_32 PNGAPI
    +png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
    +    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) != 0 && hist != NULL)
    +   {
    +      *hist = info_ptr->hist;
    +      return (PNG_INFO_hIST);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +png_uint_32 PNGAPI
    +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");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return (0);
    +
    +   if (width != NULL)
    +       *width = info_ptr->width;
    +
    +   if (height != NULL)
    +       *height = info_ptr->height;
    +
    +   if (bit_depth != NULL)
    +       *bit_depth = info_ptr->bit_depth;
    +
    +   if (color_type != NULL)
    +       *color_type = info_ptr->color_type;
    +
    +   if (compression_type != NULL)
    +      *compression_type = info_ptr->compression_type;
    +
    +   if (filter_type != NULL)
    +      *filter_type = info_ptr->filter_type;
    +
    +   if (interlace_type != NULL)
    +      *interlace_type = info_ptr->interlace_type;
    +
    +   /* This is redundant if we can be sure that the info_ptr values were all
    +    * assigned in png_set_IHDR().  We do the check anyhow in case an
    +    * 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,
    +       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
    +       info_ptr->compression_type, info_ptr->filter_type);
    +
    +   return (1);
    +}
    +
    +#ifdef PNG_oFFs_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 &&
    +       offset_x != NULL && offset_y != NULL && unit_type != NULL)
    +   {
    +      *offset_x = info_ptr->x_offset;
    +      *offset_y = info_ptr->y_offset;
    +      *unit_type = (int)info_ptr->offset_unit_type;
    +      return (PNG_INFO_oFFs);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_pCAL_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 &&
    +       purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
    +       nparams != NULL && units != NULL && params != NULL)
    +   {
    +      *purpose = info_ptr->pcal_purpose;
    +      *X0 = info_ptr->pcal_X0;
    +      *X1 = info_ptr->pcal_X1;
    +      *type = (int)info_ptr->pcal_type;
    +      *nparams = (int)info_ptr->pcal_nparams;
    +      *units = info_ptr->pcal_units;
    +      *params = info_ptr->pcal_params;
    +      return (PNG_INFO_pCAL);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_sCAL_SUPPORTED
    +#  ifdef PNG_FIXED_POINT_SUPPORTED
    +#    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
    +         defined(PNG_FLOATING_POINT_SUPPORTED)
    +png_uint_32 PNGAPI
    +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) != 0)
    +   {
    +      *unit = info_ptr->scal_unit;
    +      /*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");
    +      return (PNG_INFO_sCAL);
    +   }
    +
    +   return(0);
    +}
    +#    endif /* FLOATING_ARITHMETIC */
    +#  endif /* FIXED_POINT */
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0)
    +   {
    +      *unit = info_ptr->scal_unit;
    +      *width = atof(info_ptr->scal_s_width);
    +      *height = atof(info_ptr->scal_s_height);
    +      return (PNG_INFO_sCAL);
    +   }
    +
    +   return(0);
    +}
    +#  endif /* FLOATING POINT */
    +png_uint_32 PNGAPI
    +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) != 0)
    +   {
    +      *unit = info_ptr->scal_unit;
    +      *width = info_ptr->scal_s_width;
    +      *height = info_ptr->scal_s_height;
    +      return (PNG_INFO_sCAL);
    +   }
    +
    +   return(0);
    +}
    +#endif /* sCAL */
    +
    +#ifdef PNG_pHYs_SUPPORTED
    +png_uint_32 PNGAPI
    +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;
    +
    +   png_debug1(1, "in %s retrieval function", "pHYs");
    +
    +   if (png_ptr != NULL && info_ptr != NULL &&
    +       (info_ptr->valid & PNG_INFO_pHYs) != 0)
    +   {
    +      if (res_x != NULL)
    +      {
    +         *res_x = info_ptr->x_pixels_per_unit;
    +         retval |= PNG_INFO_pHYs;
    +      }
    +
    +      if (res_y != NULL)
    +      {
    +         *res_y = info_ptr->y_pixels_per_unit;
    +         retval |= PNG_INFO_pHYs;
    +      }
    +
    +      if (unit_type != NULL)
    +      {
    +         *unit_type = (int)info_ptr->phys_unit_type;
    +         retval |= PNG_INFO_pHYs;
    +      }
    +   }
    +
    +   return (retval);
    +}
    +#endif /* pHYs */
    +
    +png_uint_32 PNGAPI
    +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) != 0 && palette != NULL)
    +   {
    +      *palette = info_ptr->palette;
    +      *num_palette = info_ptr->num_palette;
    +      png_debug1(3, "num_palette = %d", *num_palette);
    +      return (PNG_INFO_PLTE);
    +   }
    +
    +   return (0);
    +}
    +
    +#ifdef PNG_sBIT_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 && sig_bit != NULL)
    +   {
    +      *sig_bit = &(info_ptr->sig_bit);
    +      return (PNG_INFO_sBIT);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_TEXT_SUPPORTED
    +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 0x%lx retrieval function",
    +         (unsigned long)png_ptr->chunk_name);
    +
    +      if (text_ptr != NULL)
    +         *text_ptr = info_ptr->text;
    +
    +      if (num_text != NULL)
    +         *num_text = info_ptr->num_text;
    +
    +      return info_ptr->num_text;
    +   }
    +
    +   if (num_text != NULL)
    +      *num_text = 0;
    +
    +   return(0);
    +}
    +#endif
    +
    +#ifdef PNG_tIME_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0 && mod_time != NULL)
    +   {
    +      *mod_time = &(info_ptr->mod_time);
    +      return (PNG_INFO_tIME);
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_tRNS_SUPPORTED
    +png_uint_32 PNGAPI
    +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) != 0)
    +   {
    +      png_debug1(1, "in %s retrieval function", "tRNS");
    +
    +      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      {
    +         if (trans_alpha != NULL)
    +         {
    +            *trans_alpha = info_ptr->trans_alpha;
    +            retval |= PNG_INFO_tRNS;
    +         }
    +
    +         if (trans_color != NULL)
    +            *trans_color = &(info_ptr->trans_color);
    +      }
    +
    +      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
    +      {
    +         if (trans_color != NULL)
    +         {
    +            *trans_color = &(info_ptr->trans_color);
    +            retval |= PNG_INFO_tRNS;
    +         }
    +
    +         if (trans_alpha != NULL)
    +            *trans_alpha = NULL;
    +      }
    +
    +      if (num_trans != NULL)
    +      {
    +         *num_trans = info_ptr->num_trans;
    +         retval |= PNG_INFO_tRNS;
    +      }
    +   }
    +
    +   return (retval);
    +}
    +#endif
    +
    +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    +int PNGAPI
    +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)
    +   {
    +      *unknowns = info_ptr->unknown_chunks;
    +      return info_ptr->unknown_chunks_num;
    +   }
    +
    +   return (0);
    +}
    +#endif
    +
    +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    +png_byte PNGAPI
    +png_get_rgb_to_gray_status (png_const_structrp png_ptr)
    +{
    +   return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
    +}
    +#endif
    +
    +#ifdef PNG_USER_CHUNKS_SUPPORTED
    +png_voidp PNGAPI
    +png_get_user_chunk_ptr(png_const_structrp png_ptr)
    +{
    +   return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
    +}
    +#endif
    +
    +size_t PNGAPI
    +png_get_compression_buffer_size(png_const_structrp png_ptr)
    +{
    +   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_structrp png_ptr)
    +{
    +   return (png_ptr ? png_ptr->user_width_max : 0);
    +}
    +
    +png_uint_32 PNGAPI
    +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_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_structrp png_ptr)
    +{
    +   return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
    +}
    +#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_const_structrp png_ptr)
    +{
    +   return png_ptr->io_state;
    +}
    +
    +png_uint_32 PNGAPI
    +png_get_io_chunk_type (png_const_structrp png_ptr)
    +{
    +   return png_ptr->chunk_name;
    +}
    +#endif /* IO_STATE */
    +
    +#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 */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/png.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/png.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/png.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/png.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,3275 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* png.h - header file for PNG reference library
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * libpng version 1.6.37 - April 14, 2019
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license. (See LICENSE, below.)
    + *
    + * Authors and maintainers:
    + *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
    + *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
    + *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
    + *     Glenn Randers-Pehrson
    + *   libpng versions 1.6.36, December 2018, through 1.6.37, April 2019:
    + *     Cosmin Truta
    + *   See also "Contributing Authors", below.
    + */
    +
    +/*
    + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
    + * =========================================
    + *
    + * PNG Reference Library License version 2
    + * ---------------------------------------
    + *
    + *  * Copyright (c) 1995-2019 The PNG Reference Library Authors.
    + *  * Copyright (c) 2018-2019 Cosmin Truta.
    + *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
    + *  * Copyright (c) 1996-1997 Andreas Dilger.
    + *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * The software is supplied "as is", without warranty of any kind,
    + * express or implied, including, without limitation, the warranties
    + * of merchantability, fitness for a particular purpose, title, and
    + * non-infringement.  In no event shall the Copyright owners, or
    + * anyone distributing the software, be liable for any damages or
    + * other liability, whether in contract, tort or otherwise, arising
    + * from, out of, or in connection with the software, or the use or
    + * other dealings in the software, even if advised of the possibility
    + * of such damage.
    + *
    + * Permission is hereby granted to use, copy, modify, and distribute
    + * this software, or portions hereof, for any purpose, without fee,
    + * subject to the following restrictions:
    + *
    + *  1. The origin of this software must not be misrepresented; you
    + *     must not claim that you wrote the original software.  If you
    + *     use this software in a product, an acknowledgment in the product
    + *     documentation would be appreciated, but is not required.
    + *
    + *  2. Altered source versions must be plainly marked as such, and must
    + *     not be misrepresented as being the original software.
    + *
    + *  3. This Copyright notice may not be removed or altered from any
    + *     source or altered source distribution.
    + *
    + *
    + * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
    + * -----------------------------------------------------------------------
    + *
    + * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
    + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
    + * derived from libpng-1.0.6, and are distributed according to the same
    + * disclaimer and license as libpng-1.0.6 with the following individuals
    + * added to the list of Contributing Authors:
    + *
    + *     Simon-Pierre Cadieux
    + *     Eric S. Raymond
    + *     Mans Rullgard
    + *     Cosmin Truta
    + *     Gilles Vollant
    + *     James Yu
    + *     Mandar Sahastrabuddhe
    + *     Google Inc.
    + *     Vadim Barkov
    + *
    + * and with the following additions to the disclaimer:
    + *
    + *     There is no warranty against interference with your enjoyment of
    + *     the library or against infringement.  There is no warranty that our
    + *     efforts or the library will fulfill any of your particular purposes
    + *     or needs.  This library is provided with all faults, and the entire
    + *     risk of satisfactory quality, performance, accuracy, and effort is
    + *     with the user.
    + *
    + * Some files in the "contrib" directory and some configure-generated
    + * files that are distributed with libpng have other copyright owners, and
    + * are released under other open source licenses.
    + *
    + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
    + * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
    + * libpng-0.96, and are distributed according to the same disclaimer and
    + * license as libpng-0.96, with the following individuals added to the
    + * list of Contributing Authors:
    + *
    + *     Tom Lane
    + *     Glenn Randers-Pehrson
    + *     Willem van Schaik
    + *
    + * libpng versions 0.89, June 1996, through 0.96, May 1997, are
    + * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
    + * and are distributed according to the same disclaimer and license as
    + * libpng-0.88, with the following individuals added to the list of
    + * Contributing Authors:
    + *
    + *     John Bowler
    + *     Kevin Bracey
    + *     Sam Bushell
    + *     Magnus Holmgren
    + *     Greg Roelofs
    + *     Tom Tanner
    + *
    + * Some files in the "scripts" directory have other copyright owners,
    + * but are released under this license.
    + *
    + * libpng versions 0.5, May 1995, through 0.88, January 1996, are
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * For the purposes of this copyright and license, "Contributing Authors"
    + * is defined as the following set of individuals:
    + *
    + *     Andreas Dilger
    + *     Dave Martindale
    + *     Guy Eric Schalnat
    + *     Paul Schmidt
    + *     Tim Wegner
    + *
    + * The PNG Reference Library is supplied "AS IS".  The Contributing
    + * Authors and Group 42, Inc. disclaim all warranties, expressed or
    + * implied, including, without limitation, the warranties of
    + * merchantability and of fitness for any purpose.  The Contributing
    + * Authors and Group 42, Inc. assume no liability for direct, indirect,
    + * incidental, special, exemplary, or consequential damages, which may
    + * result from the use of the PNG Reference Library, even if advised of
    + * the possibility of such damage.
    + *
    + * Permission is hereby granted to use, copy, modify, and distribute this
    + * source code, or portions hereof, for any purpose, without fee, subject
    + * to the following restrictions:
    + *
    + *  1. The origin of this source code must not be misrepresented.
    + *
    + *  2. Altered versions must be plainly marked as such and must not
    + *     be misrepresented as being the original source.
    + *
    + *  3. This Copyright notice may not be removed or altered from any
    + *     source or altered source distribution.
    + *
    + * The Contributing Authors and Group 42, Inc. specifically permit,
    + * without fee, and encourage the use of this source code as a component
    + * to supporting the PNG file format in commercial products.  If you use
    + * this source code in a product, acknowledgment is not required but would
    + * be appreciated.
    + *
    + * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
    + *
    + * TRADEMARK
    + * =========
    + *
    + * The name "libpng" has not been registered by the Copyright owners
    + * as a trademark in any jurisdiction.  However, because libpng has
    + * been distributed and maintained world-wide, continually since 1995,
    + * the Copyright owners claim "common-law trademark protection" in any
    + * jurisdiction where common-law trademark is recognized.
    + */
    +
    +/*
    + * A "png_get_copyright" function is available, for convenient use in "about"
    + * boxes and the like:
    + *
    + *    printf("%s", png_get_copyright(NULL));
    + *
    + * Also, the PNG logo (in PNG format, of course) is supplied in the
    + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
    + */
    +
    +/*
    + * The contributing authors would like to thank all those who helped
    + * with testing, bug fixes, and patience.  This wouldn't have been
    + * possible without all of you.
    + *
    + * Thanks to Frank J. T. Wojcik for helping with the documentation.
    + */
    +
    +/* Note about libpng version numbers:
    + *
    + *    Due to various miscommunications, unforeseen code incompatibilities
    + *    and occasional factors outside the authors' control, version numbering
    + *    on the library has not always been consistent and straightforward.
    + *    The following table summarizes matters since version 0.89c, which was
    + *    the first widely used release:
    + *
    + *    source                 png.h  png.h  shared-lib
    + *    version                string   int  version
    + *    -------                ------ -----  ----------
    + *    0.89c "1.0 beta 3"     0.89      89  1.0.89
    + *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
    + *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
    + *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
    + *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
    + *    0.97c                  0.97      97  2.0.97
    + *    0.98                   0.98      98  2.0.98
    + *    0.99                   0.99      98  2.0.99
    + *    0.99a-m                0.99      99  2.0.99
    + *    1.00                   1.00     100  2.1.0 [100 should be 10000]
    + *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
    + *    1.0.1       png.h string is   10001  2.1.0
    + *    1.0.1a-e    identical to the  10002  from here on, the shared library
    + *    1.0.2       source version)   10002  is 2.V where V is the source code
    + *    1.0.2a-b                      10003  version, except as noted.
    + *    1.0.3                         10003
    + *    1.0.3a-d                      10004
    + *    1.0.4                         10004
    + *    1.0.4a-f                      10005
    + *    1.0.5 (+ 2 patches)           10005
    + *    1.0.5a-d                      10006
    + *    1.0.5e-r                      10100 (not source compatible)
    + *    1.0.5s-v                      10006 (not binary compatible)
    + *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
    + *    1.0.6d-f                      10007 (still binary incompatible)
    + *    1.0.6g                        10007
    + *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
    + *    1.0.6i                        10007  10.6i
    + *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
    + *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
    + *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
    + *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
    + *    1.0.7                    1    10007  (still compatible)
    + *    ...
    + *    1.0.69                  10    10069  10.so.0.69[.0]
    + *    ...
    + *    1.2.59                  13    10259  12.so.0.59[.0]
    + *    ...
    + *    1.4.20                  14    10420  14.so.0.20[.0]
    + *    ...
    + *    1.5.30                  15    10530  15.so.15.30[.0]
    + *    ...
    + *    1.6.37                  16    10637  16.so.16.37[.0]
    + *
    + *    Henceforth the source version will match the shared-library major and
    + *    minor numbers; the shared-library major version number will be used for
    + *    changes in backward compatibility, as it is intended.
    + *    The PNG_LIBPNG_VER macro, which is not used within libpng but is
    + *    available for applications, is an unsigned integer of the form XYYZZ
    + *    corresponding to the source version X.Y.Z (leading zeros in Y and Z).
    + *    Beta versions were given the previous public release number plus a
    + *    letter, until version 1.0.6j; from then on they were given the upcoming
    + *    public release number plus "betaNN" or "rcNN".
    + *
    + *    Binary incompatibility exists only when applications make direct access
    + *    to the info_ptr or png_ptr members through png.h, and the compiled
    + *    application is loaded with a different version of the library.
    + *
    + *    DLLNUM will change each time there are forward or backward changes
    + *    in binary compatibility (e.g., when a new feature is added).
    + *
    + * See libpng.txt or libpng.3 for more information.  The PNG specification
    + * is available as a W3C Recommendation and as an ISO/IEC Standard; see
    + * 
    + */
    +
    +#ifndef PNG_H
    +#define PNG_H
    +
    +/* 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.  If that
    + * file has been stripped from your copy of libpng, you can find it at
    + * 
    + *
    + * 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.6.37"
    +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\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   6
    +#define PNG_LIBPNG_VER_RELEASE 37
    +
    +/* This should be zero for a public release, or non-zero for a
    + * development version.  [Deprecated]
    + */
    +#define PNG_LIBPNG_VER_BUILD  0
    +
    +/* Release Status */
    +#define PNG_LIBPNG_BUILD_ALPHA    1
    +#define PNG_LIBPNG_BUILD_BETA     2
    +#define PNG_LIBPNG_BUILD_RC       3
    +#define PNG_LIBPNG_BUILD_STABLE   4
    +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
    +
    +/* Release-Specific Flags */
    +#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
    +                                       PNG_LIBPNG_BUILD_STABLE only */
    +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
    +                                       PNG_LIBPNG_BUILD_SPECIAL */
    +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
    +                                       PNG_LIBPNG_BUILD_PRIVATE */
    +
    +#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.
    + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here
    + * (only version 1.0.0 was mis-numbered 100 instead of 10000).
    + * From version 1.0.1 it is:
    + * XXYYZZ, where XX=major, YY=minor, ZZ=release
    + */
    +#define PNG_LIBPNG_VER 10637 /* 1.6.37 */
    +
    +/* Library configuration: these options cannot be changed after
    + * the library has been built.
    + */
    +#ifndef PNGLCONF_H
    +/* If pnglibconf.h is missing, you can
    + * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
    + */
    +#   include "pnglibconf.h"
    +#endif
    +
    +#ifndef PNG_VERSION_INFO_ONLY
    +/* Machine specific configuration. */
    +#  include "pngconf.h"
    +#endif
    +
    +/*
    + * Added at libpng-1.2.8
    + *
    + * Ref MSDN: Private as priority over Special
    + * VS_FF_PRIVATEBUILD File *was not* built using standard release
    + * procedures. If this value is given, the StringFileInfo block must
    + * contain a PrivateBuild string.
    + *
    + * VS_FF_SPECIALBUILD File *was* built by the original company using
    + * standard release procedures but is a variation of the standard
    + * file of the same version number. If this value is given, the
    + * StringFileInfo block must contain a SpecialBuild string.
    + */
    +
    +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
    +#  define PNG_LIBPNG_BUILD_TYPE \
    +       (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
    +#else
    +#  ifdef PNG_LIBPNG_SPECIALBUILD
    +#    define PNG_LIBPNG_BUILD_TYPE \
    +         (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
    +#  else
    +#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
    +#  endif
    +#endif
    +
    +#ifndef PNG_VERSION_INFO_ONLY
    +
    +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
    +#ifdef __cplusplus
    +extern "C" {
    +#endif /* __cplusplus */
    +
    +/* Version information for C files, stored in png.c.  This had better match
    + * the version above.
    + */
    +#define png_libpng_ver png_get_header_ver(NULL)
    +
    +/* This file is arranged in several sections:
    + *
    + * 1. [omitted]
    + * 2. Any configuration options that can be specified by for the application
    + *    code when it is built.  (Build time configuration is in pnglibconf.h)
    + * 3. Type definitions (base types are defined in pngconf.h), structure
    + *    definitions.
    + * 4. Exported library functions.
    + * 5. Simplified API.
    + * 6. Implementation options.
    + *
    + * The library source code has additional files (principally pngpriv.h) that
    + * allow configuration of the library.
    + */
    +
    +/* Section 1: [omitted] */
    +
    +/* Section 2: run time configuration
    + * See pnglibconf.h for build time configuration
    + *
    + * Run time configuration allows the application to choose between
    + * implementations of certain arithmetic APIs.  The default is set
    + * at build time and recorded in pnglibconf.h, but it is safe to
    + * override these (and only these) settings.  Note that this won't
    + * change what the library does, only application code, and the
    + * settings can (and probably should) be made on a per-file basis
    + * by setting the #defines before including png.h
    + *
    + * Use macros to read integers from PNG data or use the exported
    + * functions?
    + *   PNG_USE_READ_MACROS: use the macros (see below)  Note that
    + *     the macros evaluate their argument multiple times.
    + *   PNG_NO_USE_READ_MACROS: call the relevant library function.
    + *
    + * Use the alternative algorithm for compositing alpha samples that
    + * does not use division?
    + *   PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
    + *      algorithm.
    + *   PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
    + *
    + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
    + * false?
    + *   PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
    + *      APIs to png_warning.
    + * Otherwise the calls are mapped to png_error.
    + */
    +
    +/* Section 3: type definitions, including structures and compile time
    + * constants.
    + * See pngconf.h for base types that vary by machine/system
    + */
    +
    +/* 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_6_37;
    +
    +/* 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
    + * be png_byte or png_uint_16 (as defined below).
    + */
    +typedef struct png_color_struct
    +{
    +   png_byte red;
    +   png_byte green;
    +   png_byte blue;
    +} png_color;
    +typedef png_color * png_colorp;
    +typedef const png_color * png_const_colorp;
    +typedef png_color * * png_colorpp;
    +
    +typedef struct png_color_16_struct
    +{
    +   png_byte index;    /* used for palette files */
    +   png_uint_16 red;   /* for use in red green blue files */
    +   png_uint_16 green;
    +   png_uint_16 blue;
    +   png_uint_16 gray;  /* for use in grayscale files */
    +} png_color_16;
    +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
    +{
    +   png_byte red;   /* for use in red green blue files */
    +   png_byte green;
    +   png_byte blue;
    +   png_byte gray;  /* for use in grayscale files */
    +   png_byte alpha; /* for alpha channel files */
    +} png_color_8;
    +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
    + * of sPLT chunks.
    + */
    +typedef struct png_sPLT_entry_struct
    +{
    +   png_uint_16 red;
    +   png_uint_16 green;
    +   png_uint_16 blue;
    +   png_uint_16 alpha;
    +   png_uint_16 frequency;
    +} png_sPLT_entry;
    +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
    + *  is zero-filled.  The frequency member always occupies the full 16 bits.
    + */
    +
    +typedef struct png_sPLT_struct
    +{
    +   png_charp name;           /* palette name */
    +   png_byte depth;           /* depth of palette samples */
    +   png_sPLT_entryp entries;  /* palette entries */
    +   png_int_32 nentries;      /* number of palette entries */
    +} png_sPLT_t;
    +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" 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
    + * 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
    +{
    +   int  compression;       /* compression value:
    +                             -1: tEXt, none
    +                              0: zTXt, deflate
    +                              1: iTXt, none
    +                              2: iTXt, deflate  */
    +   png_charp key;          /* keyword, 1-79 character description of "text" */
    +   png_charp text;         /* comment, may be an empty string (ie "")
    +                              or a NULL pointer */
    +   size_t text_length;     /* length of the text string */
    +   size_t itxt_length;     /* length of the itxt string */
    +   png_charp lang;         /* language code, 0-79 characters
    +                              or a NULL pointer */
    +   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
    +                              chars or a NULL pointer */
    +} png_text;
    +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).
    + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
    +#define PNG_TEXT_COMPRESSION_NONE_WR -3
    +#define PNG_TEXT_COMPRESSION_zTXt_WR -2
    +#define PNG_TEXT_COMPRESSION_NONE    -1
    +#define PNG_TEXT_COMPRESSION_zTXt     0
    +#define PNG_ITXT_COMPRESSION_NONE     1
    +#define PNG_ITXT_COMPRESSION_zTXt     2
    +#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
    +
    +/* png_time is a way to hold the time in an machine independent way.
    + * Two conversions are provided, both from time_t and struct tm.  There
    + * is no portable way to convert to either of these structures, as far
    + * as I know.  If you know of a portable way, send it to me.  As a side
    + * note - PNG has always been Year 2000 compliant!
    + */
    +typedef struct png_time_struct
    +{
    +   png_uint_16 year; /* full year, as in, 1995 */
    +   png_byte month;   /* month of year, 1 - 12 */
    +   png_byte day;     /* day of month, 1 - 31 */
    +   png_byte hour;    /* hour of day, 0 - 23 */
    +   png_byte minute;  /* minute of hour, 0 - 59 */
    +   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
    +} png_time;
    +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]; /* Textual chunk name with '\0' terminator */
    +   png_byte *data;   /* Data, should not be modified on read! */
    +   size_t size;
    +
    +   /* 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 * png_unknown_chunkp;
    +typedef const png_unknown_chunk * png_const_unknown_chunkp;
    +typedef png_unknown_chunk * * png_unknown_chunkpp;
    +#endif
    +
    +/* Flag values for the unknown chunk location byte. */
    +#define PNG_HAVE_IHDR  0x01
    +#define PNG_HAVE_PLTE  0x02
    +#define PNG_AFTER_IDAT 0x08
    +
    +/* 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))
    +#define PNG_SIZE_MAX ((size_t)(-1))
    +
    +/* These are constants for fixed point values encoded in the
    + * PNG specification manner (x100000)
    + */
    +#define PNG_FP_1    100000
    +#define PNG_FP_HALF  50000
    +#define PNG_FP_MAX  ((png_fixed_point)0x7fffffffL)
    +#define PNG_FP_MIN  (-PNG_FP_MAX)
    +
    +/* These describe the color_type field in png_info. */
    +/* color type masks */
    +#define PNG_COLOR_MASK_PALETTE    1
    +#define PNG_COLOR_MASK_COLOR      2
    +#define PNG_COLOR_MASK_ALPHA      4
    +
    +/* color types.  Note that not all combinations are legal */
    +#define PNG_COLOR_TYPE_GRAY 0
    +#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
    +#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
    +#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
    +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
    +/* aliases */
    +#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
    +#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
    +
    +/* This is for compression type. PNG 1.0-1.2 only define the single type. */
    +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
    +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
    +
    +/* This is for filter type. PNG 1.0-1.2 only define the single type. */
    +#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
    +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
    +#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
    +
    +/* These are for the interlacing type.  These values should NOT be changed. */
    +#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
    +#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
    +#define PNG_INTERLACE_LAST        2 /* Not a valid value */
    +
    +/* These are for the oFFs chunk.  These values should NOT be changed. */
    +#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
    +#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
    +#define PNG_OFFSET_LAST           2 /* Not a valid value */
    +
    +/* These are for the pCAL chunk.  These values should NOT be changed. */
    +#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
    +#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
    +#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
    +#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
    +#define PNG_EQUATION_LAST         4 /* Not a valid value */
    +
    +/* These are for the sCAL chunk.  These values should NOT be changed. */
    +#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
    +#define PNG_SCALE_METER           1 /* meters per pixel */
    +#define PNG_SCALE_RADIAN          2 /* radians per pixel */
    +#define PNG_SCALE_LAST            3 /* Not a valid value */
    +
    +/* These are for the pHYs chunk.  These values should NOT be changed. */
    +#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
    +#define PNG_RESOLUTION_METER      1 /* pixels/meter */
    +#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
    +
    +/* These are for the sRGB chunk.  These values should NOT be changed. */
    +#define PNG_sRGB_INTENT_PERCEPTUAL 0
    +#define PNG_sRGB_INTENT_RELATIVE   1
    +#define PNG_sRGB_INTENT_SATURATION 2
    +#define PNG_sRGB_INTENT_ABSOLUTE   3
    +#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
    +
    +/* This is for text chunks */
    +#define PNG_KEYWORD_MAX_LENGTH     79
    +
    +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
    +#define PNG_MAX_PALETTE_LENGTH    256
    +
    +/* These determine if an ancillary chunk's data has been successfully read
    + * from the PNG header, or if the application has filled in the corresponding
    + * data in the info_struct to be written into the output file.  The values
    + * of the PNG_INFO_ defines should NOT be changed.
    + */
    +#define PNG_INFO_gAMA 0x0001U
    +#define PNG_INFO_sBIT 0x0002U
    +#define PNG_INFO_cHRM 0x0004U
    +#define PNG_INFO_PLTE 0x0008U
    +#define PNG_INFO_tRNS 0x0010U
    +#define PNG_INFO_bKGD 0x0020U
    +#define PNG_INFO_hIST 0x0040U
    +#define PNG_INFO_pHYs 0x0080U
    +#define PNG_INFO_oFFs 0x0100U
    +#define PNG_INFO_tIME 0x0200U
    +#define PNG_INFO_pCAL 0x0400U
    +#define PNG_INFO_sRGB 0x0800U  /* GR-P, 0.96a */
    +#define PNG_INFO_iCCP 0x1000U  /* ESR, 1.0.6 */
    +#define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */
    +#define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
    +#define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
    +#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
    +
    +/* This is used for the transformation routines, as some of them
    + * change these values for the row.  It also should enable using
    + * the routines for other purposes.
    + */
    +typedef struct png_row_info_struct
    +{
    +   png_uint_32 width;    /* width of row */
    +   size_t rowbytes;      /* number of bytes in row */
    +   png_byte color_type;  /* color type of row */
    +   png_byte bit_depth;   /* bit depth of row */
    +   png_byte channels;    /* number of channels (1, 2, 3, or 4) */
    +   png_byte pixel_depth; /* bits per pixel (depth * channels) */
    +} png_row_info;
    +
    +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
    + * own.  The png_error_ptr type should match that of user-supplied warning
    + * and error functions, while the png_rw_ptr type should match that of the
    + * user read/write data functions.  Note that the 'write' function must not
    + * modify the buffer it is passed. The 'read' function, on the other hand, is
    + * expected to return the read data in the buffer.
    + */
    +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
    +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t));
    +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
    +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
    +    int));
    +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
    +    int));
    +
    +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
    +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
    +
    +/* The following callback receives png_uint_32 row_number, int pass for the
    + * png_bytep data of the row.  When transforming an interlaced image the
    + * row number is the row number within the sub-image of the interlace pass, so
    + * the value will increase to the height of the sub-image (not the full image)
    + * then reset to 0 for the next pass.
    + *
    + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
    + * find the output pixel (x,y) given an interlaced sub-image pixel
    + * (row,col,pass).  (See below for these macros.)
    + */
    +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
    +    png_uint_32, int));
    +#endif
    +
    +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
    +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    +typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
    +    png_bytep));
    +#endif
    +
    +#ifdef PNG_USER_CHUNKS_SUPPORTED
    +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
    +    png_unknown_chunkp));
    +#endif
    +#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
    +/* not used anywhere */
    +/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */
    +#endif
    +
    +#ifdef PNG_SETJMP_SUPPORTED
    +/* This must match the function definition in , and the application
    + * must include this before png.h to obtain the definition of jmp_buf.  The
    + * function is required to be PNG_NORETURN, but this is not checked.  If the
    + * function does return the application will crash via an abort() or similar
    + * system level call.
    + *
    + * If you get a warning here while building the library you may need to make
    + * changes to ensure that pnglibconf.h records the calling convention used by
    + * your compiler.  This may be very difficult - try using a different compiler
    + * to build the library!
    + */
    +PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
    +#endif
    +
    +/* Transform masks for the high-level interface */
    +#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
    +#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
    +#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
    +#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
    +#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
    +#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
    +#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
    +#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
    +#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
    +#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
    +#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
    +#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
    +#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */
    +/* Added to libpng-1.2.34 */
    +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
    +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
    +/* Added to libpng-1.4.0 */
    +#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */
    +/* Added to libpng-1.5.4 */
    +#define PNG_TRANSFORM_EXPAND_16     0x4000      /* read only */
    +#if INT_MAX >= 0x8000 /* else this might break */
    +#define PNG_TRANSFORM_SCALE_16      0x8000      /* read only */
    +#endif
    +
    +/* Flags for MNG supported features */
    +#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
    +#define PNG_FLAG_MNG_FILTER_64      0x04
    +#define PNG_ALL_MNG_FEATURES        0x05
    +
    +/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
    + * this allowed the zlib default functions to be used on Windows
    + * platforms.  In 1.5 the zlib default malloc (which just calls malloc and
    + * ignores the first argument) should be completely compatible with the
    + * following.
    + */
    +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
    +    png_alloc_size_t));
    +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
    +
    +/* Section 4: exported functions
    + * Here are the function definitions most commonly used.  This is not
    + * the place to find out how to use libpng.  See libpng-manual.txt for the
    + * full explanation, see example.c for the summary.  This just provides
    + * a simple one line description of the use of each function.
    + *
    + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
    + * pngconf.h and in the *.dfn files in the scripts directory.
    + *
    + *   PNG_EXPORT(ordinal, type, name, (args));
    + *
    + *       ordinal:    ordinal that is used while building
    + *                   *.def files. The ordinal value is only
    + *                   relevant when preprocessing png.h with
    + *                   the *.dfn files for building symbol table
    + *                   entries, and are removed by pngconf.h.
    + *       type:       return type of the function
    + *       name:       function name
    + *       args:       function arguments, with types
    + *
    + * When we wish to append attributes to a function prototype we use
    + * the PNG_EXPORTA() macro instead.
    + *
    + *   PNG_EXPORTA(ordinal, type, name, (args), attributes);
    + *
    + *       ordinal, type, name, and args: same as in PNG_EXPORT().
    + *       attributes: function attributes
    + */
    +
    +/* Returns the version number of the library */
    +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
    +
    +/* Tell lib we have already handled the first  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_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
    + * signature, and non-zero otherwise.  Having num_to_check == 0 or
    + * start > 7 will always fail (ie return non-zero).
    + */
    +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
    +    size_t num_to_check));
    +
    +/* Simple signature checking function.  This is the same as calling
    + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
    + */
    +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
    +
    +/* Allocate and initialize png_ptr struct for reading, and any other memory. */
    +PNG_EXPORTA(4, png_structp, 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);
    +
    +/* Allocate and initialize png_ptr struct for writing, and any other memory */
    +PNG_EXPORTA(5, png_structp, 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);
    +
    +PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
    +    (png_const_structrp png_ptr));
    +
    +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
    +    size_t size));
    +
    +/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
    + * match up.
    + */
    +#ifdef PNG_SETJMP_SUPPORTED
    +/* This function returns the jmp_buf built in to *png_ptr.  It must be
    + * supplied with an appropriate 'longjmp' function to use on that jmp_buf
    + * unless the default error function is overridden in which case NULL is
    + * acceptable.  The size of the jmp_buf is checked against the actual size
    + * 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_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))))
    +#else
    +#  define png_jmpbuf(png_ptr) \
    +      (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
    +#endif
    +/* This function should be used by libpng applications in place of
    + * longjmp(png_ptr->jmpbuf, val).  If longjmp_fn() has been set, it
    + * 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_const_structrp png_ptr, int val),
    +    PNG_NORETURN);
    +
    +#ifdef PNG_READ_SUPPORTED
    +/* Reset the compression stream */
    +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) */
    +#ifdef PNG_USER_MEM_SUPPORTED
    +PNG_EXPORTA(11, png_structp, png_create_read_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);
    +PNG_EXPORTA(12, png_structp, 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
    +
    +/* Write the PNG file signature. */
    +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_structrp png_ptr, png_const_bytep
    +    chunk_name, png_const_bytep data, size_t length));
    +
    +/* Write the start of a PNG chunk - length and chunk name. */
    +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_structrp png_ptr,
    +    png_const_bytep data, size_t length));
    +
    +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
    +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_const_structrp png_ptr),
    +    PNG_ALLOCATED);
    +
    +/* 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,
    +    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_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(21, void, png_write_info,
    +    (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_structrp png_ptr, png_inforp info_ptr));
    +#endif
    +
    +#ifdef PNG_TIME_RFC1123_SUPPORTED
    +   /* 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,
    +    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 /* 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_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_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_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_structrp png_ptr));
    +#endif
    +
    +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    +/* Reduce RGB to grayscale. */
    +#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
    +
    +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
    +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
    +    png_colorp palette));
    +#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 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
    + * with the alpha samples.
    + *
    + * 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, 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 re-encode
    + * 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.
    + * image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
    + * (the latter being the two common names for associated alpha color channels).
    + *
    + * 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
    + * correctly undoes the encoding before handling alpha composition.  Use this
    + * choice only if other serious errors in the software or hardware you use
    + * mandate it; the typical serious error is for dark halos to appear around
    + * opaque areas of the composited PNG image because of arithmetic overflow.
    + *
    + * The API function png_set_alpha_mode specifies which of these choices to use
    + * with an enumerated 'mode' value and the gamma of the required output:
    + */
    +#define PNG_ALPHA_PNG           0 /* according to the PNG standard */
    +#define PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
    +#define PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
    +#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
    +#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_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_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.
    + */
    +#define PNG_DEFAULT_sRGB -1       /* sRGB gamma and color space */
    +#define PNG_GAMMA_MAC_18 -2       /* Old Mac '1.8' gamma and color space */
    +#define PNG_GAMMA_sRGB   220000   /* Television standards--matches sRGB gamma */
    +#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
    +#endif
    +
    +/* The following are examples of calls to png_set_alpha_mode to achieve the
    + * required overall gamma correction and, where necessary, alpha
    + * premultiplication.
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
    + *    This is the default libpng handling of the alpha channel - it is not
    + *    pre-multiplied into the color components.  In addition the call states
    + *    that the output is for a sRGB system and causes all PNG files without gAMA
    + *    chunks to be assumed to be encoded using sRGB.
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
    + *    In this case the output is assumed to be something like an sRGB conformant
    + *    display preceded by a power-law lookup table of power 1.45.  This is how
    + *    early Mac systems behaved.
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
    + *    This is the classic Jim Blinn approach and will work in academic
    + *    environments where everything is done by the book.  It has the shortcoming
    + *    of assuming that input PNG data with no gamma information is linear - this
    + *    is unlikely to be correct unless the PNG files where generated locally.
    + *    Most of the time the output precision will be so low as to show
    + *    significant banding in dark areas of the image.
    + *
    + * png_set_expand_16(pp);
    + * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
    + *    This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
    + *    are assumed to have the sRGB encoding if not marked with a gamma value and
    + *    the output is always 16 bits per component.  This permits accurate scaling
    + *    and processing of the data.  If you know that your input PNG files were
    + *    generated locally you might need to replace PNG_DEFAULT_sRGB with the
    + *    correct value for your system.
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
    + *    If you just need to composite the PNG image onto an existing background
    + *    and if you control the code that does this you can use the optimization
    + *    setting.  In this case you just copy completely opaque pixels to the
    + *    output.  For pixels that are not completely transparent (you just skip
    + *    those) you do the composition math using png_composite or png_composite_16
    + *    below then encode the resultant 8-bit or 16-bit values to match the output
    + *    encoding.
    + *
    + * Other cases
    + *    If neither the PNG nor the standard linear encoding work for you because
    + *    of the software or hardware you use then you have a big problem.  The PNG
    + *    case will probably result in halos around the image.  The linear encoding
    + *    will probably result in a washed out, too bright, image (it's actually too
    + *    contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
    + *    substantially reduce the halos.  Alternatively try:
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
    + *    This option will also reduce the halos, but there will be slight dark
    + *    halos round the opaque parts of the image where the background is light.
    + *    In the OPTIMIZED mode the halos will be light halos where the background
    + *    is dark.  Take your pick - the halos are unavoidable unless you can get
    + *    your hardware/software fixed!  (The OPTIMIZED approach is slightly
    + *    faster.)
    + *
    + * 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
    + *    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
    + *    default if it is not already set:
    + *
    + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
    + * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
    + *    The first call sets both the default and the output gamma values, the
    + *    second call overrides the output gamma without changing the default.  This
    + *    is easier than achieving the same effect with png_set_gamma.  You must use
    + *    PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
    + *    fire if more than one call to png_set_alpha_mode and png_set_background is
    + *    made in the same read operation, however multiple calls with PNG_ALPHA_PNG
    + *    are ignored.
    + */
    +
    +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
    +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_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_structrp png_ptr));
    +#endif
    +
    +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
    +/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
    +PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
    +    int flags));
    +/* The values of the PNG_FILLER_ defines should NOT be changed */
    +#  define PNG_FILLER_BEFORE 0
    +#  define PNG_FILLER_AFTER 1
    +/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
    +PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
    +    png_uint_32 filler, int flags));
    +#endif /* READ_FILLER || WRITE_FILLER */
    +
    +#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_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_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_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_structrp png_ptr, png_const_color_8p
    +    true_bits));
    +#endif
    +
    +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
    +    defined(PNG_WRITE_INTERLACING_SUPPORTED)
    +/* Have the code handle the interlacing.  Returns the number of passes.
    + * MUST be called before png_read_update_info or png_start_read_image,
    + * otherwise it will not have the desired effect.  Note that it is still
    + * 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_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_structrp png_ptr));
    +#endif
    +
    +#ifdef PNG_READ_BACKGROUND_SUPPORTED
    +/* Handle alpha and tRNS by replacing with a background color.  Prior to
    + * libpng-1.5.4 this API must not be called before the PNG file header has been
    + * 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_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_structrp png_ptr,
    +    png_const_color_16p background_color, int background_gamma_code,
    +    int need_expand, png_fixed_point background_gamma))
    +#endif
    +#ifdef PNG_READ_BACKGROUND_SUPPORTED
    +#  define PNG_BACKGROUND_GAMMA_UNKNOWN 0
    +#  define PNG_BACKGROUND_GAMMA_SCREEN  1
    +#  define PNG_BACKGROUND_GAMMA_FILE    2
    +#  define PNG_BACKGROUND_GAMMA_UNIQUE  3
    +#endif
    +
    +#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_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_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_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
    +/* The threshold on gamma processing is configurable but hard-wired into the
    + * library.  The following is the floating point variant.
    + */
    +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
    +
    +/* Handle gamma correction. Screen_gamma=(display_exponent).
    + * NOTE: this API simply sets the screen and file gamma values. It will
    + * therefore override the value for gamma in a PNG file if it is called after
    + * the file header has been read - use with care  - call before reading the PNG
    + * file for best results!
    + *
    + * These routines accept the same gamma values as png_set_alpha_mode (described
    + * above).  The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
    + * 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_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_structrp png_ptr, int nrows));
    +/* Flush the current PNG output buffer */
    +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_structrp png_ptr));
    +
    +/* Optional call to update the users info structure */
    +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_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_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_structrp png_ptr, png_bytepp image));
    +#endif
    +
    +/* Write a row of image data */
    +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_structrp png_ptr, png_bytepp row,
    +    png_uint_32 num_rows));
    +
    +/* Write the image data */
    +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_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_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_const_structrp png_ptr,
    +    png_infopp info_ptr_ptr));
    +
    +/* Free any memory associated with the png_struct and the png_info_structs */
    +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
    +    png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
    +
    +/* Free any memory associated with the png_struct and the png_info_structs */
    +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
    +    png_infopp info_ptr_ptr));
    +
    +/* Set the libpng method of handling chunk CRC errors */
    +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
    + * therein.  Note that it is impossible to "discard" data in a critical
    + * chunk.  For versions prior to 0.90, the action was always error/quit,
    + * whereas in version 0.90 and later, the action for CRC errors in ancillary
    + * chunks is warn/discard.  These values should NOT be changed.
    + *
    + *      value                       action:critical     action:ancillary
    + */
    +#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
    +#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
    +#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
    +#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
    +#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
    +#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
    +
    +#ifdef PNG_WRITE_SUPPORTED
    +/* These functions give the user control over the scan-line filtering in
    + * libpng and the compression methods used by zlib.  These functions are
    + * mainly useful for testing, as the defaults should work with most users.
    + * Those users who are tight on memory or want faster performance at the
    + * expense of compression can modify them.  See the compression library
    + * header file (zlib.h) for an explination of the compression functions.
    + */
    +
    +/* 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_structrp png_ptr, int method,
    +    int filters));
    +#endif /* WRITE */
    +
    +/* 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
    + * below, in case they are supplied instead of the #defined constants.
    + * These values should NOT be changed.
    + */
    +#define PNG_NO_FILTERS     0x00
    +#define PNG_FILTER_NONE    0x08
    +#define PNG_FILTER_SUB     0x10
    +#define PNG_FILTER_UP      0x20
    +#define PNG_FILTER_AVG     0x40
    +#define PNG_FILTER_PAETH   0x80
    +#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
    +#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
    +
    +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
    + * These defines should NOT be changed.
    + */
    +#define PNG_FILTER_VALUE_NONE  0
    +#define PNG_FILTER_VALUE_SUB   1
    +#define PNG_FILTER_VALUE_UP    2
    +#define PNG_FILTER_VALUE_AVG   3
    +#define PNG_FILTER_VALUE_PAETH 4
    +#define PNG_FILTER_VALUE_LAST  5
    +
    +#ifdef PNG_WRITE_SUPPORTED
    +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
    +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
    +    int heuristic_method, int num_weights, png_const_doublep filter_weights,
    +    png_const_doublep filter_costs))
    +PNG_FIXED_EXPORT(209, void, 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))
    +#endif /* WRITE_WEIGHTED_FILTER */
    +
    +/* The following are no longer used and will be removed from libpng-1.7: */
    +#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
    +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
    +#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
    +#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
    +
    +/* Set the library compression level.  Currently, valid values range from
    + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
    + * (0 - no compression, 9 - "maximal" compression).  Note that tests have
    + * shown that zlib compression levels 3-6 usually perform as well as level 9
    + * for PNG images, and do considerably fewer caclulations.  In the future,
    + * these values may not correspond directly to the zlib compression levels.
    + */
    +#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
    +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_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_structrp png_ptr,
    +    int window_bits));
    +
    +PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
    +    int method));
    +#endif /* WRITE_CUSTOMIZE_COMPRESSION */
    +
    +#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_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_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_structrp png_ptr, int window_bits));
    +
    +PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
    +    int method));
    +#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
    +#endif /* WRITE */
    +
    +/* These next functions are called for input/output, memory, and error
    + * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
    + * and call standard C I/O routines such as fread(), fwrite(), and
    + * fprintf().  These functions can be made to use other I/O routines
    + * at run time for those applications that need to handle I/O in a
    + * different manner by calling png_set_???_fn().  See libpng-manual.txt for
    + * more information.
    + */
    +
    +#ifdef PNG_STDIO_SUPPORTED
    +/* Initialize the input/output for the PNG file to the default functions. */
    +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
    + * supplied functions.  If no messages are to be printed you must still
    + * write and use replacement functions. The replacement error_fn should
    + * still do a longjmp to the last setjmp location if you are using this
    + * method of error handling.  If error_fn or warning_fn is NULL, the
    + * default function will be used.
    + */
    +
    +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_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.
    + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
    + * output_flush_fn will be ignored (and thus can be NULL).
    + * It is probably a mistake to use NULL for output_flush_fn if
    + * write_data_fn is not also NULL unless you have built libpng with
    + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
    + * default flush function, which uses the standard *FILE structure, will
    + * be used.
    + */
    +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_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_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_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_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_structrp png_ptr));
    +#endif
    +
    +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
    +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_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_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_structrp png_ptr));
    +#endif
    +
    +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
    +/* Return information about the row currently being processed.  Note that these
    + * APIs do not fail but will return unexpected results if called outside a user
    + * transform callback.  Also note that when transforming an interlaced image the
    + * row number is the row number within the sub-image of the interlace pass, so
    + * the value will increase to the height of the sub-image (not the full image)
    + * then reset to 0 for the next pass.
    + *
    + * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
    + * 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_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 occurred; 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 WITH 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(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_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_structrp png_ptr));
    +
    +/* Function to be called when data becomes available */
    +PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
    +    png_inforp info_ptr, png_bytep buffer, 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
    + * remaining, excluding any that libpng has cached internally.  A subsequent
    + * call to png_process_data must supply these bytes again.  If the argument
    + * 'save' is set to true the routine will first save all the pending data and
    + * will always return 0.
    + */
    +PNG_EXPORT(219, 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
    + * input.  Normally it will return 0, but if it returns a non-zero value the
    + * 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_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_const_structrp png_ptr,
    +    png_bytep old_row, png_const_bytep new_row));
    +#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_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_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_const_structrp png_ptr, png_voidp ptr));
    +
    +/* Free data that was allocated internally */
    +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; 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
    +#define PNG_SET_WILL_FREE_DATA 1
    +#define PNG_USER_WILL_FREE_DATA 2
    +/* Flags for png_ptr->free_me and info_ptr->free_me */
    +#define PNG_FREE_HIST 0x0008U
    +#define PNG_FREE_ICCP 0x0010U
    +#define PNG_FREE_SPLT 0x0020U
    +#define PNG_FREE_ROWS 0x0040U
    +#define PNG_FREE_PCAL 0x0080U
    +#define PNG_FREE_SCAL 0x0100U
    +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    +#  define PNG_FREE_UNKN 0x0200U
    +#endif
    +/*      PNG_FREE_LIST 0x0400U   removed in 1.6.0 because it is ignored */
    +#define PNG_FREE_PLTE 0x1000U
    +#define PNG_FREE_TRNS 0x2000U
    +#define PNG_FREE_TEXT 0x4000U
    +#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
    +#define PNG_FREE_ALL  0xffffU
    +#define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
    +
    +#ifdef PNG_USER_MEM_SUPPORTED
    +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
    +    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_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_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_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_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_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. */
    +PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
    +    png_const_charp warning_message));
    +
    +#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_structrp png_ptr, int allowed));
    +#else
    +#  ifdef PNG_ALLOW_BENIGN_ERRORS
    +#    define png_benign_error png_warning
    +#    define png_chunk_benign_error png_chunk_warning
    +#  else
    +#    define png_benign_error png_error
    +#    define png_chunk_benign_error png_chunk_error
    +#  endif
    +#endif
    +
    +/* The png_set_ functions are for storing values in the png_info_struct.
    + * Similarly, the png_get_ calls are used to read values from the
    + * png_info_struct, either storing the parameters in the passed variables, or
    + * setting pointers into the png_info_struct where the data is stored.  The
    + * png_get_ functions return a non-zero value if the data was available
    + * in info_ptr, or return zero and do not change any of the parameters if the
    + * data was not available.
    + *
    + * These functions should be used instead of directly accessing png_info
    + * to avoid problems with future changes in the size and internal layout of
    + * png_info_struct.
    + */
    +/* Returns "flag" if chunk data is valid in info_ptr. */
    +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, 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_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_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_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_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_structrp png_ptr,
    +    png_const_inforp info_ptr));
    +
    +/* Returns image bit_depth. */
    +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_structrp png_ptr,
    +    png_const_inforp info_ptr));
    +
    +/* Returns image filter_type. */
    +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_structrp png_ptr,
    +    png_const_inforp info_ptr));
    +
    +/* Returns image compression_type. */
    +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_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
    +    (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_structrp png_ptr, png_const_inforp info_ptr))
    +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
    +    (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_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
    +    (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_structrp png_ptr,
    +    png_const_inforp info_ptr));
    +#endif
    +
    +#ifdef PNG_bKGD_SUPPORTED
    +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_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_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))
    +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_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
    +
    +#ifdef PNG_cHRM_SUPPORTED
    +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_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_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_eXIf_SUPPORTED
    +PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
    +    png_inforp info_ptr, png_bytep *exif));
    +PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
    +    png_inforp info_ptr, png_bytep exif));
    +
    +PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
    +    png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
    +PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif));
    +#endif
    +
    +#ifdef PNG_gAMA_SUPPORTED
    +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
    +    png_const_inforp info_ptr, double *file_gamma))
    +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
    +    (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_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_structrp png_ptr,
    +    png_inforp info_ptr, png_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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, 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_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, 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,
    + * language, and  translated keywords are NULL pointers, the structure
    + * returned by png_get_text will always contain regular
    + * zero-terminated C strings.  They might be empty strings but
    + * they will never be NULL pointers.
    + */
    +
    +#ifdef PNG_TEXT_SUPPORTED
    +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_structrp png_ptr,
    +    png_inforp info_ptr, png_timep *mod_time));
    +#endif
    +
    +#ifdef PNG_tIME_SUPPORTED
    +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_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_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_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_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_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 WITH 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.
    + */
    +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
    +    int keep, png_const_bytep chunk_list, int num_chunks));
    +#endif /* HANDLE_AS_UNKNOWN */
    +
    +/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
    + * the result is therefore true (non-zero) if special handling is required,
    + * false for the default handling.
    + */
    +PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
    +    png_const_bytep chunk_name));
    +#endif /* SET_UNKNOWN_CHUNKS */
    +
    +#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_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_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. */
    +#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_structrp png_ptr));
    +PNG_EXPORT(181, png_const_charp, png_get_header_ver,
    +    (png_const_structrp png_ptr));
    +PNG_EXPORT(182, png_const_charp, png_get_header_version,
    +    (png_const_structrp png_ptr));
    +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
    +    (png_const_structrp png_ptr));
    +
    +#ifdef PNG_MNG_FEATURES_SUPPORTED
    +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
    +    png_uint_32 mng_features_permitted));
    +#endif
    +
    +/* For use in png_set_keep_unknown, added to version 1.2.6 */
    +#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
    +#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_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_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_structrp png_ptr));
    +PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
    +    (png_const_structrp png_ptr));
    +/* Added in libpng-1.4.0 */
    +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_structrp png_ptr));
    +/* Added in libpng-1.4.1 */
    +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_structrp png_ptr));
    +#endif
    +
    +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
    +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +
    +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +
    +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
    +    (png_const_structrp png_ptr, png_const_inforp info_ptr));
    +
    +PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
    +    (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_const_structrp png_ptr, png_const_inforp info_ptr))
    +#endif
    +
    +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_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_structrp png_ptr,
    +    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
    +    int *unit_type));
    +#  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_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_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 */
    +#  define PNG_IO_READING     0x0001   /* currently reading */
    +#  define PNG_IO_WRITING     0x0002   /* currently writing */
    +#  define PNG_IO_SIGNATURE   0x0010   /* currently at the file signature */
    +#  define PNG_IO_CHUNK_HDR   0x0020   /* currently at the chunk header */
    +#  define PNG_IO_CHUNK_DATA  0x0040   /* currently at the chunk data */
    +#  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 /* 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
    + * interlaced images within the application.
    + */
    +#define PNG_INTERLACE_ADAM7_PASSES 7
    +
    +/* Two macros to return the first row and first column of the original,
    + * 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) (((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
    + * rows or columns in each 8x8 tile of the original image.
    + */
    +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
    +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
    +
    +/* Hence two macros to determine the number of rows or columns in a given
    + * pass of an image given its height or width.  In fact these macros may
    + * return non-zero even though the sub-image is empty, because the other
    + * dimension may be empty for a small image.
    + */
    +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass))
    +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass))
    +
    +/* For the reader row callbacks (both progressive and sequential) it is
    + * 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(y_in, pass) \
    +   (((y_in)<>(((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)
    +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
    +   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
    +
    +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
    +/* With these routines we avoid an integer divide, which will be slower on
    + * most machines.  However, it does take more operations than the corresponding
    + * divide method, so it may be slower on a few RISC systems.  There are two
    + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
    + *
    + * Note that the rounding factors are NOT supposed to be the same!  128 and
    + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
    + * standard method.
    + *
    + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
    + */
    +
    + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
    +
    +#  define png_composite(composite, fg, alpha, bg)        \
    +   {                                                     \
    +      png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
    +          * (png_uint_16)(alpha)                         \
    +          + (png_uint_16)(bg)*(png_uint_16)(255          \
    +          - (png_uint_16)(alpha)) + 128);                \
    +      (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
    +   }
    +
    +#  define png_composite_16(composite, fg, alpha, bg)     \
    +   {                                                     \
    +      png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
    +          * (png_uint_32)(alpha)                         \
    +          + (png_uint_32)(bg)*(65535                     \
    +          - (png_uint_32)(alpha)) + 32768);              \
    +      (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
    +   }
    +
    +#else  /* Standard method using integer division */
    +
    +#  define png_composite(composite, fg, alpha, bg)                      \
    +   (composite) =                                                       \
    +       (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
    +       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
    +       127) / 255))
    +
    +#  define png_composite_16(composite, fg, alpha, bg)                       \
    +   (composite) =                                                           \
    +       (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
    +       (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
    +       32767) / 65535))
    +#endif /* READ_COMPOSITE_NODIV */
    +
    +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
    +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
    +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
    +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_const_structrp png_ptr,
    +    png_const_bytep buf));
    +/* No png_get_int_16 -- may be added if there's a real need for it. */
    +
    +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
    +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
    +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
    +#endif
    +#ifdef PNG_SAVE_INT_32_SUPPORTED
    +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
    +#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.
    + */
    +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
    +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
    +/* No png_save_int_16 -- may be added if there's a real need for it. */
    +#endif
    +
    +#ifdef PNG_USE_READ_MACROS
    +/* Inline macros to do direct reads of bytes from the input buffer.
    + * 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) \
    +   (((png_uint_32)(*(buf)) << 24) + \
    +    ((png_uint_32)(*((buf) + 1)) << 16) + \
    +    ((png_uint_32)(*((buf) + 2)) << 8) + \
    +    ((png_uint_32)(*((buf) + 3))))
    +
    +   /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
    +    * function) incorrectly returned a value of type png_uint_32.
    +    */
    +#  define PNG_get_uint_16(buf) \
    +   ((png_uint_16) \
    +    (((unsigned int)(*(buf)) << 8) + \
    +    ((unsigned int)(*((buf) + 1)))))
    +
    +#  define PNG_get_int_32(buf) \
    +   ((png_int_32)((*(buf) & 0x80) \
    +    ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
    +    : (png_int_32)png_get_uint_32(buf)))
    +
    +/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
    + * but defining a macro name prefixed with PNG_PREFIX.
    + */
    +#  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
    +
    +#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 */
    +
    +/*******************************************************************************
    + * Section 5: 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 accommodate 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, set the
    + *    version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
    + *    (this is REQUIRED, your program may crash if you don't do it.)
    + * 2) Call the appropriate png_image_begin_read... function.
    + * 3) Set the png_image 'format' member to the required sample format.
    + * 4) Allocate a buffer for the image and, if required, the color-map.
    + * 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:
    + */
    +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
    +    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
    +
    +#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 ) 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
    +
    +#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
    +
    +/* 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.
    +    *
    +    * WARNING: this macro overflows for some images with more than one component
    +    * and very large image widths.  libpng will refuse to process an image where
    +    * this macro would overflow.
    +    */
    +
    +#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
    +   (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
    +   /* Return the size, in bytes, of an image buffer given a png_image and a row
    +    * stride - the number of components to leave space for in each row.
    +    *
    +    * WARNING: this macro overflows a 32-bit integer for some large PNG images,
    +    * libpng will refuse to process an image where such an overflow would occur.
    +    */
    +
    +#define PNG_IMAGE_SIZE(image)\
    +   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 that 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, 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
    +/* 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)
    + */
    +#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
    +PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
    +   const char *file, int convert_to_8bit, const void *buffer,
    +   png_int_32 row_stride, const void *colormap));
    +   /* 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*). */
    +#endif /* SIMPLIFIED_WRITE_STDIO */
    +
    +/* With all write APIs if image is in one of the linear formats with 16-bit
    + * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
    + * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
    + * encoded PNG file is written.
    + *
    + * 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.  If row_stride is
    + * zero, libpng will calculate it for you from the image width and number of
    + * channels.
    + *
    + * Note that the write API does not support interlacing, sub-8-bit pixels or
    + * most ancillary chunks.  If you need to write text chunks (e.g. for copyright
    + * notices) you need to use one of the other APIs.
    + */
    +
    +PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
    +   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
    +   const void *buffer, png_int_32 row_stride, const void *colormap));
    +   /* Write the image to the given memory buffer.  The function both writes the
    +    * whole PNG data stream to *memory and updates *memory_bytes with the count
    +    * of bytes written.
    +    *
    +    * 'memory' may be NULL.  In this case *memory_bytes is not read however on
    +    * success the number of bytes which would have been written will still be
    +    * stored in *memory_bytes.  On failure *memory_bytes will contain 0.
    +    *
    +    * If 'memory' is not NULL it must point to memory[*memory_bytes] of
    +    * writeable memory.
    +    *
    +    * If the function returns success memory[*memory_bytes] (if 'memory' is not
    +    * NULL) contains the written PNG data.  *memory_bytes will always be less
    +    * than or equal to the original value.
    +    *
    +    * If the function returns false and *memory_bytes was not changed an error
    +    * occurred during write.  If *memory_bytes was changed, or is not 0 if
    +    * 'memory' was NULL, the write would have succeeded but for the memory
    +    * buffer being too small.  *memory_bytes contains the required number of
    +    * bytes and will be bigger that the original value.
    +    */
    +
    +#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
    +   row_stride, colormap)\
    +   png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
    +         row_stride, colormap)
    +   /* Return the amount of memory in 'size' required to compress this image.
    +    * The png_image structure 'image' must be filled in as in the above
    +    * function and must not be changed before the actual write call, the buffer
    +    * and all other parameters must also be identical to that in the final
    +    * write call.  The 'size' variable need not be initialized.
    +    *
    +    * NOTE: the macro returns true/false, if false is returned 'size' will be
    +    * set to zero and the write failed and probably will fail if tried again.
    +    */
    +
    +/* You can pre-allocate the buffer by making sure it is of sufficient size
    + * regardless of the amount of compression achieved.  The buffer size will
    + * always be bigger than the original image and it will never be filled.  The
    + * following macros are provided to assist in allocating the buffer.
    + */
    +#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
    +   /* The number of uncompressed bytes in the PNG byte encoding of the image;
    +    * uncompressing the PNG IDAT data will give this number of bytes.
    +    *
    +    * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
    +    * macro can because of the extra bytes used in the PNG byte encoding.  You
    +    * need to avoid this macro if your image size approaches 2^30 in width or
    +    * height.  The same goes for the remainder of these macros; they all produce
    +    * bigger numbers than the actual in-memory image size.
    +    */
    +#ifndef PNG_ZLIB_MAX_SIZE
    +#  define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
    +   /* An upper bound on the number of compressed bytes given 'b' uncompressed
    +    * bytes.  This is based on deflateBounds() in zlib; different
    +    * implementations of zlib compression may conceivably produce more data so
    +    * if your zlib implementation is not zlib itself redefine this macro
    +    * appropriately.
    +    */
    +#endif
    +
    +#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
    +   PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
    +   /* An upper bound on the size of the data in the PNG IDAT chunks. */
    +
    +#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
    +   ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
    +    (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
    +    12U+3U*(image).colormap_entries/*PLTE data*/+\
    +    (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
    +    12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
    +    12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
    +   /* A helper for the following macro; if your compiler cannot handle the
    +    * following macro use this one with the result of
    +    * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
    +    * compilers should handle this just fine.)
    +    */
    +
    +#define PNG_IMAGE_PNG_SIZE_MAX(image)\
    +   PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
    +   /* An upper bound on the total length of the PNG data stream for 'image'.
    +    * The result is of type png_alloc_size_t, on 32-bit systems this may
    +    * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
    +    * run out of buffer space but return a corrected size which should work.
    +    */
    +#endif /* SIMPLIFIED_WRITE */
    +/*******************************************************************************
    + *  END OF SIMPLIFIED API
    + ******************************************************************************/
    +#endif /* SIMPLIFIED_{READ|WRITE} */
    +
    +/*******************************************************************************
    + * Section 6: 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 capabilities, 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 */
    +#ifdef PNG_MIPS_MSA_API_SUPPORTED
    +#  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
    +#endif
    +#define PNG_IGNORE_ADLER32 8
    +#ifdef PNG_POWERPC_VSX_API_SUPPORTED
    +#  define PNG_POWERPC_VSX   10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
    +#endif
    +#define PNG_OPTION_NEXT  12 /* Next option - numbers must be even */
    +
    +/* Return values: NOTE: there are four values and 'off' is *not* zero */
    +#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
    +#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.)
    + */
    +#ifdef PNG_EXPORT_LAST_ORDINAL
    +  PNG_EXPORT_LAST_ORDINAL(249);
    +#endif
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif /* PNG_VERSION_INFO_ONLY */
    +/* Do not put anything past this line */
    +#endif /* PNG_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pnginfo.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,295 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pnginfo.h - header file for PNG reference library
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    + /* png_info is a structure that holds the information in a PNG file so
    + * that the application can find out the characteristics of the image.
    + * If you are reading the file, this structure will tell you what is
    + * in the PNG file.  If you are writing the file, fill in the information
    + * you want to put into the PNG file, using png_set_*() functions, then
    + * call png_write_info().
    + *
    + * The names chosen should be very close to the PNG specification, so
    + * consult that document for information about the meaning of each field.
    + *
    + * With libpng < 0.95, it was only possible to directly set and read the
    + * the values in the png_info_struct, which meant that the contents and
    + * order of the values had to remain fixed.  With libpng 0.95 and later,
    + * however, there are now functions that abstract the contents of
    + * png_info_struct from the application, so this makes it easier to use
    + * libpng with dynamic libraries, and even makes it possible to use
    + * libraries that don't have all of the libpng ancillary chunk-handing
    + * functionality.  In libpng-1.5.0 this was moved into a separate private
    + * file that is not visible to applications.
    + *
    + * The following members may have allocated storage attached that should be
    + * cleaned up before the structure is discarded: palette, trans, text,
    + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
    + * splt_palettes, scal_unit, row_pointers, and unknowns.   By default, these
    + * are automatically freed when the info structure is deallocated, if they were
    + * allocated internally by libpng.  This behavior can be changed by means
    + * of the png_data_freer() function.
    + *
    + * More allocation details: all the chunk-reading functions that
    + * change these members go through the corresponding png_set_*
    + * functions.  A function to clear these members is available: see
    + * png_free_data().  The png_set_* functions do not depend on being
    + * able to point info structure members to any of the storage they are
    + * passed (they make their own copies), EXCEPT that the png_set_text
    + * functions use the same storage passed to them in the text_ptr or
    + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
    + * functions do not make their own copies.
    + */
    +#ifndef PNGINFO_H
    +#define PNGINFO_H
    +
    +struct png_info_def
    +{
    +   /* 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) */
    +   size_t rowbytes;         /* bytes needed to hold an untransformed row */
    +   png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
    +   png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
    +   png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
    +   png_byte bit_depth;      /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
    +   png_byte color_type;     /* see PNG_COLOR_TYPE_ below (from IHDR) */
    +   /* The following three should have been named *_method not *_type */
    +   png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
    +   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 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
    +    * are writing, set the valid field to those chunks you want written,
    +    * and initialize the appropriate fields below.
    +    */
    +
    +#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_colorspace colorspace;
    +#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 */
    +#endif
    +
    +#ifdef PNG_TEXT_SUPPORTED
    +   /* The tEXt, and zTXt chunks contain human-readable textual data in
    +    * uncompressed, compressed, and optionally compressed forms, respectively.
    +    * The data in "text" is an array of pointers to uncompressed,
    +    * null-terminated C strings. Each chunk has a keyword that describes the
    +    * textual data contained in that chunk.  Keywords are not required to be
    +    * unique, and the text string may be empty.  Any number of text chunks may
    +    * be in an image.
    +    */
    +   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 /* TEXT */
    +
    +#ifdef PNG_tIME_SUPPORTED
    +   /* The tIME chunk holds the last time the displayed image data was
    +    * modified.  See the png_time struct for the contents of this struct.
    +    */
    +   png_time mod_time;
    +#endif
    +
    +#ifdef PNG_sBIT_SUPPORTED
    +   /* The sBIT chunk specifies the number of significant high-order bits
    +    * in the pixel data.  Values are in the range [1, bit_depth], and are
    +    * only specified for the channels in the pixel data.  The contents of
    +    * the low-order bits is not specified.  Data is valid if
    +    * (valid & PNG_INFO_sBIT) is non-zero.
    +    */
    +   png_color_8 sig_bit; /* significant bits in color channels */
    +#endif
    +
    +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
    +defined(PNG_READ_BACKGROUND_SUPPORTED)
    +   /* The tRNS chunk supplies transparency data for paletted images and
    +    * other image types that don't need a full alpha channel.  There are
    +    * "num_trans" transparency values for a paletted image, stored in the
    +    * same order as the palette colors, starting from index 0.  Values
    +    * for the data are in the range [0, 255], ranging from fully transparent
    +    * to fully opaque, respectively.  For non-paletted images, there is a
    +    * single color specified that should be treated as fully transparent.
    +    * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
    +    */
    +   png_bytep trans_alpha;    /* alpha values for paletted image */
    +   png_color_16 trans_color; /* transparent color for non-palette image */
    +#endif
    +
    +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    +   /* The bKGD chunk gives the suggested image background color if the
    +    * display program does not have its own background color and the image
    +    * is needs to composited onto a background before display.  The colors
    +    * in "background" are normally in the same color space/depth as the
    +    * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
    +    */
    +   png_color_16 background;
    +#endif
    +
    +#ifdef PNG_oFFs_SUPPORTED
    +   /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
    +    * and downwards from the top-left corner of the display, page, or other
    +    * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
    +    * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
    +    */
    +   png_int_32 x_offset; /* x offset on page */
    +   png_int_32 y_offset; /* y offset on page */
    +   png_byte offset_unit_type; /* offset units type */
    +#endif
    +
    +#ifdef PNG_pHYs_SUPPORTED
    +   /* The pHYs chunk gives the physical pixel density of the image for
    +    * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
    +    * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
    +    */
    +   png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
    +   png_uint_32 y_pixels_per_unit; /* vertical pixel density */
    +   png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
    +#endif
    +
    +#ifdef PNG_eXIf_SUPPORTED
    +   int num_exif;  /* Added at libpng-1.6.31 */
    +   png_bytep exif;
    +# ifdef PNG_READ_eXIf_SUPPORTED
    +   png_bytep eXIf_buf;  /* Added at libpng-1.6.32 */
    +# endif
    +#endif
    +
    +#ifdef PNG_hIST_SUPPORTED
    +   /* The hIST chunk contains the relative frequency or importance of the
    +    * various palette entries, so that a viewer can intelligently select a
    +    * reduced-color palette, if required.  Data is an array of "num_palette"
    +    * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
    +    * is non-zero.
    +    */
    +   png_uint_16p hist;
    +#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.
    +    * The integer range [0, 2^bit_depth - 1] maps to the floating-point
    +    * range given by [pcal_X0, pcal_X1], and are further transformed by a
    +    * (possibly non-linear) transformation function given by "pcal_type"
    +    * and "pcal_params" into "pcal_units".  Please see the PNG_EQUATION_
    +    * defines below, and the PNG-Group's PNG extensions document for a
    +    * complete description of the transformations and how they should be
    +    * implemented, and for a description of the ASCII parameter strings.
    +    * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
    +    */
    +   png_charp pcal_purpose;  /* pCAL chunk description string */
    +   png_int_32 pcal_X0;      /* minimum value */
    +   png_int_32 pcal_X1;      /* maximum value */
    +   png_charp pcal_units;    /* Latin-1 string giving physical units */
    +   png_charpp pcal_params;  /* ASCII strings containing parameter values */
    +   png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
    +   png_byte pcal_nparams;   /* number of parameters given in pcal_params */
    +#endif
    +
    +/* New members added in libpng-1.0.6 */
    +   png_uint_32 free_me;     /* flags items libpng is responsible for freeing */
    +
    +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    +   /* Storage for unknown chunks that the library doesn't recognize. */
    +   png_unknown_chunkp unknown_chunks;
    +
    +   /* The type of this field is limited by the type of
    +    * 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;
    +   int         splt_palettes_num; /* Match type returned by png_get API */
    +#endif
    +
    +#ifdef PNG_sCAL_SUPPORTED
    +   /* The sCAL chunk describes the actual physical dimensions of the
    +    * subject matter of the graphic.  The chunk contains a unit specification
    +    * a byte value, and two ASCII strings representing floating-point
    +    * values.  The values are width and height corresponding to one pixel
    +    * in the image.  Data values are valid if (valid & PNG_INFO_sCAL) is
    +    * non-zero.
    +    */
    +   png_byte scal_unit;         /* unit of physical scale */
    +   png_charp scal_s_width;     /* string containing height */
    +   png_charp scal_s_height;    /* string containing width */
    +#endif
    +
    +#ifdef PNG_INFO_IMAGE_SUPPORTED
    +   /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
    +      non-zero */
    +   /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
    +   png_bytepp row_pointers;        /* the image bits */
    +#endif
    +
    +};
    +#endif /* PNGINFO_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,250 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + *
    + * THIS FILE WAS MODIFIED BY ORACLE, INC.
    + */
    +
    +/* pnglibconf.h - library build configuration
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + */
    +/* libpng version 1.6.37 */
    +
    +/* Copyright (c) 2018-2019 Cosmin Truta */
    +/* Copyright (c) 1998-2002,2004,2006-2018 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 */
    +#ifndef PNGLCONF_H
    +#define PNGLCONF_H
    +/* options */
    +#define PNG_16BIT_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_BENIGN_READ_ERRORS_SUPPORTED
    +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
    +#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
    +#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
    +#define PNG_COLORSPACE_SUPPORTED
    +#define PNG_CONSOLE_IO_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_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_INCH_CONVERSIONS_SUPPORTED
    +#define PNG_INFO_IMAGE_SUPPORTED
    +#define PNG_IO_STATE_SUPPORTED
    +#define PNG_MNG_FEATURES_SUPPORTED
    +#define PNG_POINTER_INDEXING_SUPPORTED
    +/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
    +/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
    +#define PNG_PROGRESSIVE_READ_SUPPORTED
    +#define PNG_READ_16BIT_SUPPORTED
    +#define PNG_READ_ALPHA_MODE_SUPPORTED
    +#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
    +#define PNG_READ_BACKGROUND_SUPPORTED
    +#define PNG_READ_BGR_SUPPORTED
    +#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
    +#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
    +/*#undef PNG_READ_COMPRESSED_TEXT_SUPPORTED*/
    +#define PNG_READ_EXPAND_16_SUPPORTED
    +#define PNG_READ_EXPAND_SUPPORTED
    +#define PNG_READ_FILLER_SUPPORTED
    +#define PNG_READ_GAMMA_SUPPORTED
    +#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
    +#define PNG_READ_GRAY_TO_RGB_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_OPT_PLTE_SUPPORTED
    +#define PNG_READ_PACKSWAP_SUPPORTED
    +#define PNG_READ_PACK_SUPPORTED
    +#define PNG_READ_QUANTIZE_SUPPORTED
    +#define PNG_READ_RGB_TO_GRAY_SUPPORTED
    +#define PNG_READ_SCALE_16_TO_8_SUPPORTED
    +#define PNG_READ_SHIFT_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_TRANSFORMS_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
    +/*#undef PNG_READ_eXIf_SUPPORTED*/
    +#define PNG_READ_gAMA_SUPPORTED
    +#define PNG_READ_hIST_SUPPORTED
    +/*#undef PNG_READ_iCCP_SUPPORTED*/
    +/*#undef 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
    +/*#undef PNG_READ_zTXt_SUPPORTED*/
    +/*#undef PNG_SAVE_INT_32_SUPPORTED*/
    +#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
    +#define PNG_SEQUENTIAL_READ_SUPPORTED
    +#define PNG_SETJMP_SUPPORTED
    +/*#undef PNG_SET_OPTION_SUPPORTED*/
    +#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
    +#define PNG_SET_USER_LIMITS_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_STDIO_SUPPORTED*/
    +/*#undef PNG_SIMPLIFIED_WRITE_SUPPORTED*/
    +#define PNG_STDIO_SUPPORTED
    +#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
    +#define PNG_TEXT_SUPPORTED
    +#define PNG_TIME_RFC1123_SUPPORTED
    +#define PNG_UNKNOWN_CHUNKS_SUPPORTED
    +#define PNG_USER_CHUNKS_SUPPORTED
    +#define PNG_USER_LIMITS_SUPPORTED
    +#define PNG_USER_MEM_SUPPORTED
    +#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_COMPRESSION_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_eXIf_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
    +/*#undef PNG_eXIf_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_DEFAULT_READ_MACROS 1
    +#define PNG_GAMMA_THRESHOLD_FIXED 5000
    +#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
    +#define PNG_INFLATE_BUF_SIZE 1024
    +#define PNG_LINKAGE_API extern
    +#define PNG_LINKAGE_CALLBACK extern
    +#define PNG_LINKAGE_DATA extern
    +#define PNG_LINKAGE_FUNCTION extern
    +#define PNG_MAX_GAMMA_8 11
    +#define PNG_QUANTIZE_BLUE_BITS 5
    +#define PNG_QUANTIZE_GREEN_BITS 5
    +#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 1000
    +#define PNG_USER_CHUNK_MALLOC_MAX 8000000
    +#define PNG_USER_HEIGHT_MAX 8000
    +#define PNG_USER_WIDTH_MAX 8000
    +#define PNG_ZBUF_SIZE 8192
    +#define PNG_ZLIB_VERNUM 0 /* unknown */
    +#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 */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngmem.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,312 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngmem.c - stub functions for memory allocation
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file provides a location for all memory allocation.  Users who
    + * need special memory handling are expected to supply replacement
    + * functions for png_malloc() and png_free(), and to use
    + * png_create_read_struct_2() and png_create_write_struct_2() to
    + * identify the replacement functions.
    + */
    +
    +#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);
    +
    +#     ifdef PNG_SETJMP_SUPPORTED
    +         /* We may have a jmp_buf left to deallocate. */
    +         png_free_jmpbuf(&dummy_struct);
    +#     endif
    +   }
    +}
    +
    +/* Allocate memory.  For reasonable files, size should never exceed
    + * 64K.  However, zlib may allocate more than 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.
    + */
    +PNG_FUNCTION(png_voidp,PNGAPI
    +png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
    +{
    +   png_voidp ret;
    +
    +   ret = png_malloc(png_ptr, size);
    +
    +   if (ret != NULL)
    +      memset(ret, 0, size);
    +
    +   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
    +
    +   /* Some compilers complain that this is always true.  However, it
    +    * can be false when integer overflow happens.
    +    */
    +   if (size > 0 && size <= PNG_SIZE_MAX
    +#     ifdef PNG_MAX_MALLOC_64K
    +         && size <= 65536U
    +#     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 = (png_alloc_size_t)nelements; /* known to be > 0 */
    +
    +   if (req <= PNG_SIZE_MAX/element_size)
    +      return png_malloc_base(png_ptr, req * element_size);
    +
    +   /* 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_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
    +{
    +   png_voidp ret;
    +
    +   if (png_ptr == NULL)
    +      return NULL;
    +
    +   ret = png_malloc_base(png_ptr, size);
    +
    +   if (ret == NULL)
    +       png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
    +
    +   return ret;
    +}
    +
    +#ifdef PNG_USER_MEM_SUPPORTED
    +PNG_FUNCTION(png_voidp,PNGAPI
    +png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
    +    PNG_ALLOCATED PNG_DEPRECATED)
    +{
    +   png_voidp ret;
    +
    +   if (png_ptr == NULL)
    +      return NULL;
    +
    +   /* 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)
    +   {
    +      png_voidp ret = png_malloc_base(png_ptr, size);
    +
    +      if (ret != NULL)
    +         return ret;
    +
    +      png_warning(png_ptr, "Out of memory");
    +   }
    +
    +   return NULL;
    +}
    +
    +/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
    + * without taking any action.
    + */
    +void PNGAPI
    +png_free(png_const_structrp 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_constcast(png_structrp,png_ptr), ptr);
    +
    +   else
    +      png_free_default(png_ptr, 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 */
    +
    +   free(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_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
    +  malloc_fn, png_free_ptr free_fn)
    +{
    +   if (png_ptr != NULL)
    +   {
    +      png_ptr->mem_ptr = mem_ptr;
    +      png_ptr->malloc_fn = malloc_fn;
    +      png_ptr->free_fn = free_fn;
    +   }
    +}
    +
    +/* This function returns a pointer to the mem_ptr associated with the user
    + * functions.  The application should free any memory associated with this
    + * pointer before png_write_destroy and png_read_destroy are called.
    + */
    +png_voidp PNGAPI
    +png_get_mem_ptr(png_const_structrp png_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return NULL;
    +
    +   return png_ptr->mem_ptr;
    +}
    +#endif /* USER_MEM */
    +#endif /* READ || WRITE */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1124 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngpread.c - read a png file in push mode
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +#include "pngpriv.h"
    +
    +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    +
    +/* Push model modes */
    +#define PNG_READ_SIG_MODE   0
    +#define PNG_READ_CHUNK_MODE 1
    +#define PNG_READ_IDAT_MODE  2
    +#define PNG_READ_tEXt_MODE  4
    +#define PNG_READ_zTXt_MODE  5
    +#define PNG_READ_DONE_MODE  6
    +#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_structrp png_ptr, png_inforp info_ptr,
    +    png_bytep buffer, size_t buffer_size)
    +{
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   png_push_restore_buffer(png_ptr, buffer, buffer_size);
    +
    +   while (png_ptr->buffer_size)
    +   {
    +      png_process_some_data(png_ptr, info_ptr);
    +   }
    +}
    +
    +size_t PNGAPI
    +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
    +       * have to supply the same data again:
    +       */
    +      if (save != 0)
    +         png_push_save_buffer(png_ptr);
    +      else
    +      {
    +         /* This includes any pending saved bytes: */
    +         size_t remaining = png_ptr->buffer_size;
    +         png_ptr->buffer_size = 0;
    +
    +         /* So subtract the saved buffer size, unless all the data
    +          * is actually 'saved', in which case we just return 0
    +          */
    +         if (png_ptr->save_buffer_size < remaining)
    +            return remaining - png_ptr->save_buffer_size;
    +      }
    +   }
    +
    +   return 0;
    +}
    +
    +png_uint_32 PNGAPI
    +png_process_data_skip(png_structrp png_ptr)
    +{
    +/* TODO: Deprecate and remove this API.
    + * Somewhere the implementation of this seems to have been lost,
    + * or abandoned.  It was only to support some internal back-door access
    + * to png_struct) in libpng-1.4.x.
    + */
    +   png_app_warning(png_ptr,
    +"png_process_data_skip is not implemented in any current version of libpng");
    +   return 0;
    +}
    +
    +/* What we do with the incoming data depends on what we were previously
    + * doing before we ran out of data...
    + */
    +void /* PRIVATE */
    +png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   switch (png_ptr->process_mode)
    +   {
    +      case PNG_READ_SIG_MODE:
    +      {
    +         png_push_read_sig(png_ptr, info_ptr);
    +         break;
    +      }
    +
    +      case PNG_READ_CHUNK_MODE:
    +      {
    +         png_push_read_chunk(png_ptr, info_ptr);
    +         break;
    +      }
    +
    +      case PNG_READ_IDAT_MODE:
    +      {
    +         png_push_read_IDAT(png_ptr);
    +         break;
    +      }
    +
    +      default:
    +      {
    +         png_ptr->buffer_size = 0;
    +         break;
    +      }
    +   }
    +}
    +
    +/* Read any remaining signature bytes from the stream and compare them with
    + * the correct PNG signature.  It is possible that this routine is called
    + * with bytes already read from the signature, either because they have been
    + * checked by the calling application, or because of multiple calls to this
    + * routine.
    + */
    +void /* PRIVATE */
    +png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
    +{
    +   size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
    +   size_t num_to_check = 8 - num_checked;
    +
    +   if (png_ptr->buffer_size < num_to_check)
    +   {
    +      num_to_check = png_ptr->buffer_size;
    +   }
    +
    +   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
    +       num_to_check);
    +   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
    +
    +   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
    +   {
    +      if (num_checked < 4 &&
    +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
    +         png_error(png_ptr, "Not a PNG file");
    +
    +      else
    +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    +   }
    +   else
    +   {
    +      if (png_ptr->sig_bytes >= 8)
    +      {
    +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    +      }
    +   }
    +}
    +
    +void /* PRIVATE */
    +png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
    +{
    +   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
    +    * 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
    +    * end of every chunk (except IDAT, which is handled separately).
    +    */
    +   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    +   {
    +      png_byte chunk_length[4];
    +      png_byte chunk_tag[4];
    +
    +      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, chunk_tag, 4);
    +      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
    +      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    +      png_check_chunk_length(png_ptr, png_ptr->push_length);
    +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    +   }
    +
    +   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 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->process_mode = PNG_READ_IDAT_MODE;
    +
    +      if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    +         if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
    +            if (png_ptr->push_length == 0)
    +               return;
    +
    +      png_ptr->mode |= PNG_HAVE_IDAT;
    +
    +      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
    +         png_benign_error(png_ptr, "Too many IDATs found");
    +   }
    +
    +   if (chunk_name == png_IHDR)
    +   {
    +      if (png_ptr->push_length != 13)
    +         png_error(png_ptr, "Invalid IHDR length");
    +
    +      PNG_PUSH_SAVE_BUFFER_IF_FULL
    +      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
    +   }
    +
    +   else if (chunk_name == png_IEND)
    +   {
    +      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;
    +      png_push_have_end(png_ptr, info_ptr);
    +   }
    +
    +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    +   {
    +      PNG_PUSH_SAVE_BUFFER_IF_FULL
    +      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
    +
    +      if (chunk_name == png_PLTE)
    +         png_ptr->mode |= PNG_HAVE_PLTE;
    +   }
    +#endif
    +
    +   else if (chunk_name == png_PLTE)
    +   {
    +      PNG_PUSH_SAVE_BUFFER_IF_FULL
    +      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    +   }
    +
    +   else if (chunk_name == png_IDAT)
    +   {
    +      png_ptr->idat_size = png_ptr->push_length;
    +      png_ptr->process_mode = PNG_READ_IDAT_MODE;
    +      png_push_have_info(png_ptr, info_ptr);
    +      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;
    +      return;
    +   }
    +
    +#ifdef PNG_READ_gAMA_SUPPORTED
    +   else if (png_ptr->chunk_name == png_gAMA)
    +   {
    +      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_ptr->chunk_name == png_sBIT)
    +   {
    +      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_ptr->chunk_name == png_cHRM)
    +   {
    +      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 (chunk_name == png_sRGB)
    +   {
    +      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_ptr->chunk_name == png_iCCP)
    +   {
    +      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 (chunk_name == png_sPLT)
    +   {
    +      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 (chunk_name == png_tRNS)
    +   {
    +      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 (chunk_name == png_bKGD)
    +   {
    +      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 (chunk_name == png_hIST)
    +   {
    +      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 (chunk_name == png_pHYs)
    +   {
    +      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 (chunk_name == png_oFFs)
    +   {
    +      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 (chunk_name == png_pCAL)
    +   {
    +      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 (chunk_name == png_sCAL)
    +   {
    +      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 (chunk_name == png_tIME)
    +   {
    +      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 (chunk_name == png_tEXt)
    +   {
    +      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 (chunk_name == png_zTXt)
    +   {
    +      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 (chunk_name == png_iTXt)
    +   {
    +      PNG_PUSH_SAVE_BUFFER_IF_FULL
    +      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    +   }
    +#endif
    +
    +   else
    +   {
    +      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 PNGCBAPI
    +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
    +{
    +   png_bytep ptr;
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   ptr = buffer;
    +   if (png_ptr->save_buffer_size != 0)
    +   {
    +      size_t save_size;
    +
    +      if (length < png_ptr->save_buffer_size)
    +         save_size = length;
    +
    +      else
    +         save_size = png_ptr->save_buffer_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 != 0 && png_ptr->current_buffer_size != 0)
    +   {
    +      size_t save_size;
    +
    +      if (length < png_ptr->current_buffer_size)
    +         save_size = length;
    +
    +      else
    +         save_size = png_ptr->current_buffer_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;
    +   }
    +}
    +
    +void /* PRIVATE */
    +png_push_save_buffer(png_structrp png_ptr)
    +{
    +   if (png_ptr->save_buffer_size != 0)
    +   {
    +      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
    +      {
    +         size_t i, istop;
    +         png_bytep sp;
    +         png_bytep dp;
    +
    +         istop = png_ptr->save_buffer_size;
    +         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
    +             i < istop; i++, sp++, dp++)
    +         {
    +            *dp = *sp;
    +         }
    +      }
    +   }
    +   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
    +       png_ptr->save_buffer_max)
    +   {
    +      size_t new_max;
    +      png_bytep old_buffer;
    +
    +      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
    +          (png_ptr->current_buffer_size + 256))
    +      {
    +         png_error(png_ptr, "Potential overflow of save_buffer");
    +      }
    +
    +      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
    +      old_buffer = png_ptr->save_buffer;
    +      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
    +          (size_t)new_max);
    +
    +      if (png_ptr->save_buffer == NULL)
    +      {
    +         png_free(png_ptr, old_buffer);
    +         png_error(png_ptr, "Insufficient memory for save_buffer");
    +      }
    +
    +      if (old_buffer)
    +         memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
    +      else if (png_ptr->save_buffer_size)
    +         png_error(png_ptr, "save_buffer error");
    +      png_free(png_ptr, old_buffer);
    +      png_ptr->save_buffer_max = new_max;
    +   }
    +   if (png_ptr->current_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;
    +   }
    +   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
    +   png_ptr->buffer_size = 0;
    +}
    +
    +void /* PRIVATE */
    +png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
    +    size_t buffer_length)
    +{
    +   png_ptr->current_buffer = buffer;
    +   png_ptr->current_buffer_size = buffer_length;
    +   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
    +   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
    +}
    +
    +void /* PRIVATE */
    +png_push_read_IDAT(png_structrp png_ptr)
    +{
    +   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
    +   {
    +      png_byte chunk_length[4];
    +      png_byte chunk_tag[4];
    +
    +      /* 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, chunk_tag, 4);
    +      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
    +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    +
    +      if (png_ptr->chunk_name != png_IDAT)
    +      {
    +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    +
    +         if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
    +            png_error(png_ptr, "Not enough compressed data");
    +
    +         return;
    +      }
    +
    +      png_ptr->idat_size = png_ptr->push_length;
    +   }
    +
    +   if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
    +   {
    +      size_t save_size = png_ptr->save_buffer_size;
    +      png_uint_32 idat_size = png_ptr->idat_size;
    +
    +      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
    +       * are of different types and we don't know which variable has the fewest
    +       * bits.  Carefully select the smaller and cast it to the type of the
    +       * larger - this cannot overflow.  Do not cast in the following test - it
    +       * will break on either 16-bit or 64-bit platforms.
    +       */
    +      if (idat_size < save_size)
    +         save_size = (size_t)idat_size;
    +
    +      else
    +         idat_size = (png_uint_32)save_size;
    +
    +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    +
    +      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
    +
    +      png_ptr->idat_size -= idat_size;
    +      png_ptr->buffer_size -= save_size;
    +      png_ptr->save_buffer_size -= save_size;
    +      png_ptr->save_buffer_ptr += save_size;
    +   }
    +
    +   if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
    +   {
    +      size_t save_size = png_ptr->current_buffer_size;
    +      png_uint_32 idat_size = png_ptr->idat_size;
    +
    +      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
    +       * are of different types and we don't know which variable has the fewest
    +       * bits.  Carefully select the smaller and cast it to the type of the
    +       * larger - this cannot overflow.
    +       */
    +      if (idat_size < save_size)
    +         save_size = (size_t)idat_size;
    +
    +      else
    +         idat_size = (png_uint_32)save_size;
    +
    +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    +
    +      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
    +
    +      png_ptr->idat_size -= idat_size;
    +      png_ptr->buffer_size -= save_size;
    +      png_ptr->current_buffer_size -= save_size;
    +      png_ptr->current_buffer_ptr += save_size;
    +   }
    +
    +   if (png_ptr->idat_size == 0)
    +   {
    +      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
    +      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_structrp png_ptr, png_bytep buffer,
    +    size_t buffer_length)
    +{
    +   /* The caller checks for a non-zero buffer length. */
    +   if (!(buffer_length > 0) || buffer == NULL)
    +      png_error(png_ptr, "No IDAT data (internal error)");
    +
    +   /* This routine must process all the data it has been given
    +    * before returning, calling the row callback as required to
    +    * 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_ZSTREAM_ENDED) == 0)
    +   {
    +      int ret;
    +
    +      /* We have data for zlib, but we must check that zlib
    +       * has someplace to put the results.  It doesn't matter
    +       * if we don't expect any results -- it may be the input
    +       * data is just the LZ end code.
    +       */
    +      if (!(png_ptr->zstream.avail_out > 0))
    +      {
    +         /* 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;
    +      }
    +
    +      /* Using Z_SYNC_FLUSH here means that an unterminated
    +       * LZ stream (a stream with a missing end code) can still
    +       * be handled, otherwise (Z_NO_FLUSH) a future zlib
    +       * implementation might defer output and therefore
    +       * change the current behavior (see comments in inflate.c
    +       * for why this doesn't happen at present with zlib 1.2.5).
    +       */
    +      ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
    +
    +      /* Check for any failure before proceeding. */
    +      if (ret != Z_OK && ret != Z_STREAM_END)
    +      {
    +         /* Terminate the decompression. */
    +         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.
    +          */
    +         if (png_ptr->row_number >= png_ptr->num_rows ||
    +             png_ptr->pass > 6)
    +            png_warning(png_ptr, "Truncated compressed data in IDAT");
    +
    +         else
    +         {
    +            if (ret == Z_DATA_ERROR)
    +               png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
    +            else
    +               png_error(png_ptr, "Decompression error in IDAT");
    +         }
    +
    +         /* Skip the check on unprocessed input */
    +         return;
    +      }
    +
    +      /* Did inflate output any data? */
    +      if (png_ptr->zstream.next_out != png_ptr->row_buf)
    +      {
    +         /* Is this unexpected data after the last row?
    +          * If it is, artificially terminate the LZ output
    +          * here.
    +          */
    +         if (png_ptr->row_number >= png_ptr->num_rows ||
    +             png_ptr->pass > 6)
    +         {
    +            /* Extra data. */
    +            png_warning(png_ptr, "Extra compressed data in IDAT");
    +            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
    +            png_ptr->zowner = 0;
    +
    +            /* Do no more processing; skip the unprocessed
    +             * input check below.
    +             */
    +            return;
    +         }
    +
    +         /* Do we have a complete row? */
    +         if (png_ptr->zstream.avail_out == 0)
    +            png_push_process_row(png_ptr);
    +      }
    +
    +      /* And check for the end of the stream. */
    +      if (ret == Z_STREAM_END)
    +         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
    +   }
    +
    +   /* All the data should have been processed, if anything
    +    * is left at this point we have bytes of IDAT data
    +    * after the zlib end code.
    +    */
    +   if (png_ptr->zstream.avail_in > 0)
    +      png_warning(png_ptr, "Extra compression data in IDAT");
    +}
    +
    +void /* PRIVATE */
    +png_push_process_row(png_structrp png_ptr)
    +{
    +   /* 1.5.6: row_info moved out of png_struct to a local here. */
    +   png_row_info row_info;
    +
    +   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);
    +
    +   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");
    +   }
    +
    +   /* 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 != 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
    +   /* Expand interlaced rows to full size */
    +   if (png_ptr->interlaced != 0 &&
    +       (png_ptr->transformations & PNG_INTERLACE) != 0)
    +   {
    +      if (png_ptr->pass < 6)
    +         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
    +             png_ptr->transformations);
    +
    +      switch (png_ptr->pass)
    +      {
    +         case 0:
    +         {
    +            int i;
    +            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
    +            }
    +
    +            if (png_ptr->pass == 2) /* Pass 1 might be empty */
    +            {
    +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    +               {
    +                  png_push_have_row(png_ptr, NULL);
    +                  png_read_push_finish_row(png_ptr);
    +               }
    +            }
    +
    +            if (png_ptr->pass == 4 && png_ptr->height <= 4)
    +            {
    +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    +               {
    +                  png_push_have_row(png_ptr, NULL);
    +                  png_read_push_finish_row(png_ptr);
    +               }
    +            }
    +
    +            if (png_ptr->pass == 6 && png_ptr->height <= 4)
    +            {
    +                png_push_have_row(png_ptr, NULL);
    +                png_read_push_finish_row(png_ptr);
    +            }
    +
    +            break;
    +         }
    +
    +         case 1:
    +         {
    +            int i;
    +            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
    +            {
    +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    +               {
    +                  png_push_have_row(png_ptr, NULL);
    +                  png_read_push_finish_row(png_ptr);
    +               }
    +            }
    +
    +            break;
    +         }
    +
    +         case 2:
    +         {
    +            int i;
    +
    +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    +            {
    +               png_push_have_row(png_ptr, NULL);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            if (png_ptr->pass == 4) /* Pass 3 might be empty */
    +            {
    +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    +               {
    +                  png_push_have_row(png_ptr, NULL);
    +                  png_read_push_finish_row(png_ptr);
    +               }
    +            }
    +
    +            break;
    +         }
    +
    +         case 3:
    +         {
    +            int i;
    +
    +            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            if (png_ptr->pass == 4) /* Skip top two generated rows */
    +            {
    +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    +               {
    +                  png_push_have_row(png_ptr, NULL);
    +                  png_read_push_finish_row(png_ptr);
    +               }
    +            }
    +
    +            break;
    +         }
    +
    +         case 4:
    +         {
    +            int i;
    +
    +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    +            {
    +               png_push_have_row(png_ptr, NULL);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            if (png_ptr->pass == 6) /* Pass 5 might be empty */
    +            {
    +               png_push_have_row(png_ptr, NULL);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            break;
    +         }
    +
    +         case 5:
    +         {
    +            int i;
    +
    +            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
    +            {
    +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            if (png_ptr->pass == 6) /* Skip top generated row */
    +            {
    +               png_push_have_row(png_ptr, NULL);
    +               png_read_push_finish_row(png_ptr);
    +            }
    +
    +            break;
    +         }
    +
    +         default:
    +         case 6:
    +         {
    +            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +            png_read_push_finish_row(png_ptr);
    +
    +            if (png_ptr->pass != 6)
    +               break;
    +
    +            png_push_have_row(png_ptr, NULL);
    +            png_read_push_finish_row(png_ptr);
    +         }
    +      }
    +   }
    +   else
    +#endif
    +   {
    +      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    +      png_read_push_finish_row(png_ptr);
    +   }
    +}
    +
    +void /* PRIVATE */
    +png_read_push_finish_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 */
    +   static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
    +
    +   /* Offset to next interlace block */
    +   static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
    +
    +   /* Start of interlace block in the y direction */
    +   static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
    +
    +   /* Offset to next interlace block in the y direction */
    +   static 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
    +   static 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 != 0)
    +   {
    +      png_ptr->row_number = 0;
    +      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
    +
    +      do
    +      {
    +         png_ptr->pass++;
    +         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
    +             (png_ptr->pass == 3 && png_ptr->width < 3) ||
    +             (png_ptr->pass == 5 && png_ptr->width < 2))
    +            png_ptr->pass++;
    +
    +         if (png_ptr->pass > 7)
    +            png_ptr->pass--;
    +
    +         if (png_ptr->pass >= 7)
    +            break;
    +
    +         png_ptr->iwidth = (png_ptr->width +
    +             png_pass_inc[png_ptr->pass] - 1 -
    +             png_pass_start[png_ptr->pass]) /
    +             png_pass_inc[png_ptr->pass];
    +
    +         if ((png_ptr->transformations & PNG_INTERLACE) != 0)
    +            break;
    +
    +         png_ptr->num_rows = (png_ptr->height +
    +             png_pass_yinc[png_ptr->pass] - 1 -
    +             png_pass_ystart[png_ptr->pass]) /
    +             png_pass_yinc[png_ptr->pass];
    +
    +      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
    +   }
    +#endif /* READ_INTERLACING */
    +}
    +
    +void /* PRIVATE */
    +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_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_structrp png_ptr, png_bytep row)
    +{
    +   if (png_ptr->row_fn != NULL)
    +      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
    +          (int)png_ptr->pass);
    +}
    +
    +#ifdef PNG_READ_INTERLACING_SUPPORTED
    +void PNGAPI
    +png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
    +    png_const_bytep new_row)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   /* 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*/);
    +}
    +#endif /* READ_INTERLACING */
    +
    +void PNGAPI
    +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)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->info_fn = info_fn;
    +   png_ptr->row_fn = row_fn;
    +   png_ptr->end_fn = end_fn;
    +
    +   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
    +}
    +
    +png_voidp PNGAPI
    +png_get_progressive_ptr(png_const_structrp png_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return (NULL);
    +
    +   return png_ptr->io_ptr;
    +}
    +#endif /* PROGRESSIVE_READ */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,2180 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngpriv.h - private declarations for use inside libpng
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +/* The symbols declared in this file (including the functions declared
    + * 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.
    + * Although the libpng users are not forbidden to include this header,
    + * they should be well aware of the issues that may arise from doing so.
    + */
    +
    +#ifndef PNGPRIV_H
    +#define PNGPRIV_H
    +
    +/* Feature Test Macros.  The following are defined here to ensure that correctly
    + * implemented libraries reveal the APIs libpng needs to build and hide those
    + * that are not needed and potentially damaging to the compilation.
    + *
    + * Feature Test Macros must be defined before any system header is included (see
    + * POSIX 1003.1 2.8.2 "POSIX Symbols."
    + *
    + * These macros only have an effect if the operating system supports either
    + * POSIX 1003.1 or C99, or both.  On other operating systems (particularly
    + * Windows/Visual Studio) there is no effect; the OS specific tests below are
    + * still required (as of 2011-05-02.)
    + */
    +#ifndef _POSIX_SOURCE
    +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
    +#endif
    +
    +#ifndef PNG_VERSION_INFO_ONLY
    +/* Standard library headers not required by png.h: */
    +#  include 
    +#  include 
    +#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.
    + */
    +#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
    +#  include 
    +
    +   /* 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 */
    +#  ifndef PNG_USER_PRIVATEBUILD
    +#    define PNG_USER_PRIVATEBUILD "Custom libpng build"
    +#  endif
    +#  ifndef PNG_USER_DLLFNAME_POSTFIX
    +#    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 the deprecated
    +    * __ARM_NEON__, so we check both variants.
    +    *
    +    * To disable ARM_NEON optimizations entirely, and skip compiling the
    +    * associated assembler code, pass --enable-arm-neon=no to configure
    +    * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS.
    +    */
    +#  if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
    +   defined(PNG_ALIGNED_MEMORY_SUPPORTED)
    +#     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:
    +          */
    +#        if !defined(__aarch64__)
    +            /* The assembler code currently does not work on ARM64 */
    +#          define PNG_ARM_NEON_IMPLEMENTATION 2
    +#        endif /* __aarch64__ */
    +#     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 */
    +
    +#ifndef PNG_MIPS_MSA_OPT
    +#  if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
    +#     define PNG_MIPS_MSA_OPT 2
    +#  else
    +#     define PNG_MIPS_MSA_OPT 0
    +#  endif
    +#endif
    +
    +#ifndef PNG_POWERPC_VSX_OPT
    +#  if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
    +#     define PNG_POWERPC_VSX_OPT 2
    +#  else
    +#     define PNG_POWERPC_VSX_OPT 0
    +#  endif
    +#endif
    +
    +#ifndef PNG_INTEL_SSE_OPT
    +#   ifdef PNG_INTEL_SSE
    +      /* Only check for SSE if the build configuration has been modified to
    +       * enable SSE optimizations.  This means that these optimizations will
    +       * be off by default.  See contrib/intel for more details.
    +       */
    +#     if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
    +       defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
    +       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
    +#         define PNG_INTEL_SSE_OPT 1
    +#      else
    +#         define PNG_INTEL_SSE_OPT 0
    +#      endif
    +#   else
    +#      define PNG_INTEL_SSE_OPT 0
    +#   endif
    +#endif
    +
    +#if PNG_INTEL_SSE_OPT > 0
    +#   ifndef PNG_INTEL_SSE_IMPLEMENTATION
    +#      if defined(__SSE4_1__) || defined(__AVX__)
    +          /* We are not actually using AVX, but checking for AVX is the best
    +             way we can detect SSE4.1 and SSSE3 on MSVC.
    +          */
    +#         define PNG_INTEL_SSE_IMPLEMENTATION 3
    +#      elif defined(__SSSE3__)
    +#         define PNG_INTEL_SSE_IMPLEMENTATION 2
    +#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
    +       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
    +#         define PNG_INTEL_SSE_IMPLEMENTATION 1
    +#      else
    +#         define PNG_INTEL_SSE_IMPLEMENTATION 0
    +#      endif
    +#   endif
    +
    +#   if PNG_INTEL_SSE_IMPLEMENTATION > 0
    +#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
    +#   endif
    +#else
    +#   define PNG_INTEL_SSE_IMPLEMENTATION 0
    +#endif
    +
    +#if PNG_MIPS_MSA_OPT > 0
    +#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
    +#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
    +#     if defined(__mips_msa)
    +#        if defined(__clang__)
    +#        elif defined(__GNUC__)
    +#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
    +#              define PNG_MIPS_MSA_IMPLEMENTATION 2
    +#           endif /* no GNUC support */
    +#        endif /* __GNUC__ */
    +#     else /* !defined __mips_msa */
    +#        define PNG_MIPS_MSA_IMPLEMENTATION 2
    +#     endif /* __mips_msa */
    +#  endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
    +
    +#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
    +#     define PNG_MIPS_MSA_IMPLEMENTATION 1
    +#  endif
    +#endif /* PNG_MIPS_MSA_OPT > 0 */
    +
    +#if PNG_POWERPC_VSX_OPT > 0
    +#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
    +#  define PNG_POWERPC_VSX_IMPLEMENTATION 1
    +#endif
    +
    +
    +/* Is this a build of a DLL where compilation of the object modules requires
    + * different preprocessor settings to those required for a simple library?  If
    + * so PNG_BUILD_DLL must be set.
    + *
    + * 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) PNG_LINKAGE_DATA type name array
    +#endif
    +
    +#ifndef PNG_INTERNAL_FUNCTION
    +#  define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
    +      PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
    +#endif
    +
    +#ifndef PNG_INTERNAL_CALLBACK
    +#  define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
    +      PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\
    +         PNG_EMPTY attributes)
    +#endif
    +
    +/* If floating or fixed point APIs are disabled they may still be compiled
    + * 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"
    +
    +/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
    +#ifndef PNG_DLL_EXPORT
    +#  define PNG_DLL_EXPORT
    +#endif
    +
    +/* This is a global switch to set the compilation for an installed system
    + * (a release build).  It can be set for testing debug builds to ensure that
    + * they will compile when the build type is switched to RC or STABLE, the
    + * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE.  Set this in CPPFLAGS
    + * with either:
    + *
    + *   -DPNG_RELEASE_BUILD Turns on the release compile path
    + *   -DPNG_RELEASE_BUILD=0 Turns it off
    + * or in your pngusr.h with
    + *   #define PNG_RELEASE_BUILD=1 Turns on the release compile path
    + *   #define PNG_RELEASE_BUILD=0 Turns it off
    + */
    +#ifndef PNG_RELEASE_BUILD
    +#  define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
    +#endif
    +
    +/* SECURITY and SAFETY:
    + *
    + * libpng is built with support for internal limits on image dimensions and
    + * memory usage.  These are documented in scripts/pnglibconf.dfa of the
    + * source and recorded in the machine generated header file pnglibconf.h.
    + */
    +
    +/* If you are running on a machine where you cannot allocate more
    + * than 64K of memory at once, uncomment this.  While libpng will not
    + * normally need that much memory in a chunk (unless you load up a very
    + * large file), zlib needs to know how big of a chunk it can use, and
    + * libpng thus makes sure to check any memory allocation to verify it
    + * will fit into memory.
    + *
    + * zlib provides 'MAXSEG_64K' which, if defined, indicates the
    + * same limit and pngconf.h (already included) sets the limit
    + * if certain operating systems are detected.
    + */
    +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
    +#  define PNG_MAX_MALLOC_64K
    +#endif
    +
    +#ifndef PNG_UNUSED
    +/* Unused formal parameter warnings are silenced using the following macro
    + * which is expected to have no bad effects on performance (optimizing
    + * compilers will probably remove it entirely).  Note that if you replace
    + * it with something other than whitespace, you must include the terminating
    + * semicolon.
    + */
    +#  define PNG_UNUSED(param) (void)param;
    +#endif
    +
    +/* Just a little check that someone hasn't tried to define something
    + * contradictory.
    + */
    +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
    +#  undef PNG_ZBUF_SIZE
    +#  define PNG_ZBUF_SIZE 65536L
    +#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.
    + */
    +#ifdef PNG_WARNINGS_SUPPORTED
    +#  define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
    +#else
    +#  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)
    +#  define png_formatted_warning(pp,p,message) ((void)(pp))
    +#  define PNG_WARNING_PARAMETERS(p)
    +#endif
    +#ifndef PNG_ERROR_TEXT_SUPPORTED
    +#  define png_fixed_error(s1,s2) png_err(s1)
    +#endif
    +
    +/* Some fixed point APIs are still required even if not exported because
    + * they get used by the corresponding floating point APIs.  This magic
    + * deals with this:
    + */
    +#ifdef PNG_FIXED_POINT_SUPPORTED
    +#  define PNGFAPI PNGAPI
    +#else
    +#  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.
    + */
    +
    +/* C allows up-casts from (void*) to any pointer and (const void*) to any
    + * pointer to a const object.  C++ regards this as a type error and requires an
    + * explicit, static, cast and provides the static_cast<> rune to ensure that
    + * const is not cast away.
    + */
    +#ifdef __cplusplus
    +#  define png_voidcast(type, value) static_cast(value)
    +#  define png_constcast(type, value) const_cast(value)
    +#  define png_aligncast(type, value) \
    +   static_cast(static_cast(value))
    +#  define png_aligncastconst(type, value) \
    +   static_cast(static_cast(value))
    +#else
    +#  define png_voidcast(type, value) (value)
    +#  ifdef _WIN64
    +#     ifdef __GNUC__
    +         typedef unsigned long long png_ptruint;
    +#     else
    +         typedef unsigned __int64 png_ptruint;
    +#     endif
    +#  else
    +      typedef unsigned long png_ptruint;
    +#  endif
    +#  define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
    +#  define png_aligncast(type, value) ((void*)(value))
    +#  define png_aligncastconst(type, value) ((const void*)(value))
    +#endif /* __cplusplus */
    +
    +#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
    +    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
    +   /* png.c requires the following ANSI-C constants if the conversion of
    +    * floating point to ASCII is implemented therein:
    +    *
    +    *  DBL_DIG  Maximum number of decimal digits (can be set to any constant)
    +    *  DBL_MIN  Smallest normalized fp number (can be set to an arbitrary value)
    +    *  DBL_MAX  Maximum floating point number (can be set to an arbitrary value)
    +    */
    +#  include 
    +
    +#  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
    +    defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
    +   /* We need to check that  hasn't already been included earlier
    +    * as it seems it doesn't agree with , yet we should really use
    +    *  if possible.
    +    */
    +#    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
    +#      include 
    +#    endif
    +#  else
    +#    include 
    +#  endif
    +#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
    +   /* Amiga SAS/C: We must include builtin FPU functions when compiling using
    +    * MATH=68881
    +    */
    +#    include 
    +#  endif
    +#endif
    +
    +/* This provides the non-ANSI (far) memory allocation routines. */
    +#if defined(__TURBOC__) && defined(__MSDOS__)
    +#  include 
    +#  include 
    +#endif
    +
    +#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
    +    defined(_WIN32) || defined(__WIN32__)
    +#  include   /* 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
    + * functions that are passed far data must be model-independent.
    + */
    +
    +/* Memory model/platform independent fns */
    +#ifndef PNG_ABORT
    +#  ifdef _WINDOWS_
    +#    define PNG_ABORT() ExitProcess(0)
    +#  else
    +#    define PNG_ABORT() abort()
    +#  endif
    +#endif
    +
    +/* 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
    +#  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
    +#     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)\
    +   (((type)((const char*)ptr-(const char*)0) & \
    +   (type)(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 */
    +
    +/* CONSTANTS and UTILITY MACROS
    + * These are used internally by libpng and not exposed in the API
    + */
    +
    +/* Various modes of operation.  Note that after an init, mode is set to
    + * zero automatically when the structure is created.  Three of these
    + * are defined in png.h because they need to be visible to applications
    + * that call png_set_unknown_chunk().
    + */
    +/* #define PNG_HAVE_IHDR            0x01U (defined in png.h) */
    +/* #define PNG_HAVE_PLTE            0x02U (defined in png.h) */
    +#define PNG_HAVE_IDAT               0x04U
    +/* #define PNG_AFTER_IDAT           0x08U (defined in png.h) */
    +#define PNG_HAVE_IEND               0x10U
    +                   /*               0x20U (unused) */
    +                   /*               0x40U (unused) */
    +                   /*               0x80U (unused) */
    +#define PNG_HAVE_CHUNK_HEADER      0x100U
    +#define PNG_WROTE_tIME             0x200U
    +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
    +#define PNG_BACKGROUND_IS_GRAY     0x800U
    +#define PNG_HAVE_PNG_SIGNATURE    0x1000U
    +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
    +                   /*             0x4000U (unused) */
    +#define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
    +
    +/* Flags for the transformations the PNG library does on the image data */
    +#define PNG_BGR                 0x0001U
    +#define PNG_INTERLACE           0x0002U
    +#define PNG_PACK                0x0004U
    +#define PNG_SHIFT               0x0008U
    +#define PNG_SWAP_BYTES          0x0010U
    +#define PNG_INVERT_MONO         0x0020U
    +#define PNG_QUANTIZE            0x0040U
    +#define PNG_COMPOSE             0x0080U    /* Was PNG_BACKGROUND */
    +#define PNG_BACKGROUND_EXPAND   0x0100U
    +#define PNG_EXPAND_16           0x0200U    /* Added to libpng 1.5.2 */
    +#define PNG_16_TO_8             0x0400U    /* Becomes 'chop' in 1.5.4 */
    +#define PNG_RGBA                0x0800U
    +#define PNG_EXPAND              0x1000U
    +#define PNG_GAMMA               0x2000U
    +#define PNG_GRAY_TO_RGB         0x4000U
    +#define PNG_FILLER              0x8000U
    +#define PNG_PACKSWAP           0x10000U
    +#define PNG_SWAP_ALPHA         0x20000U
    +#define PNG_STRIP_ALPHA        0x40000U
    +#define PNG_INVERT_ALPHA       0x80000U
    +#define PNG_USER_TRANSFORM    0x100000U
    +#define PNG_RGB_TO_GRAY_ERR   0x200000U
    +#define PNG_RGB_TO_GRAY_WARN  0x400000U
    +#define PNG_RGB_TO_GRAY       0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
    +#define PNG_ENCODE_ALPHA      0x800000U /* Added to libpng-1.5.4 */
    +#define PNG_ADD_ALPHA        0x1000000U /* Added to libpng-1.2.7 */
    +#define PNG_EXPAND_tRNS      0x2000000U /* Added to libpng-1.2.9 */
    +#define PNG_SCALE_16_TO_8    0x4000000U /* Added to libpng-1.5.4 */
    +                       /*    0x8000000U unused */
    +                       /*   0x10000000U unused */
    +                       /*   0x20000000U unused */
    +                       /*   0x40000000U unused */
    +/* Flags for png_create_struct */
    +#define PNG_STRUCT_PNG   0x0001U
    +#define PNG_STRUCT_INFO  0x0002U
    +
    +/* Flags for the png_ptr->flags rather than declaring a byte for each one */
    +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001U
    +#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002U /* Added to libpng-1.6.0 */
    +                                  /*      0x0004U    unused */
    +#define PNG_FLAG_ZSTREAM_ENDED            0x0008U /* Added to libpng-1.6.0 */
    +                                  /*      0x0010U    unused */
    +                                  /*      0x0020U    unused */
    +#define PNG_FLAG_ROW_INIT                 0x0040U
    +#define PNG_FLAG_FILLER_AFTER             0x0080U
    +#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100U
    +#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
    +#define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
    +#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
    +#define PNG_FLAG_ASSUME_sRGB              0x1000U /* Added to libpng-1.5.4 */
    +#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
    +#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
    +/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
    +/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000U */
    +#define PNG_FLAG_LIBRARY_MISMATCH        0x20000U
    +#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000U
    +#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000U
    +#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000U /* Added to libpng-1.4.0 */
    +#define PNG_FLAG_APP_WARNINGS_WARN      0x200000U /* Added to libpng-1.6.0 */
    +#define PNG_FLAG_APP_ERRORS_WARN        0x400000U /* Added to libpng-1.6.0 */
    +                                  /*    0x800000U    unused */
    +                                  /*   0x1000000U    unused */
    +                                  /*   0x2000000U    unused */
    +                                  /*   0x4000000U    unused */
    +                                  /*   0x8000000U    unused */
    +                                  /*  0x10000000U    unused */
    +                                  /*  0x20000000U    unused */
    +                                  /*  0x40000000U    unused */
    +
    +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
    +                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
    +
    +#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
    +                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
    +
    +#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
    +                                     PNG_FLAG_CRC_CRITICAL_MASK)
    +
    +/* 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 ? \
    +    ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \
    +    (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) )
    +
    +/* This returns the number of trailing bits in the last byte of a row, 0 if the
    + * last byte is completely full of pixels.  It is, in principle, (pixel_bits x
    + * width) % 8, but that would overflow for large 'width'.  The second macro is
    + * the same except that it returns the number of unused bits in the last byte;
    + * (8-TRAILBITS), but 0 when TRAILBITS is 0.
    + *
    + * NOTE: these macros are intended to be self-evidently correct and never
    + * overflow on the assumption that pixel_bits is in the range 0..255.  The
    + * arguments are evaluated only once and they can be signed (e.g. as a result of
    + * the integral promotions).  The result of the expression always has type
    + * (png_uint_32), however the compiler always knows it is in the range 0..7.
    + */
    +#define PNG_TRAILBITS(pixel_bits, width) \
    +    (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
    +
    +#define PNG_PADBITS(pixel_bits, width) \
    +    ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
    +
    +/* PNG_OUT_OF_RANGE returns true if value is outside the range
    + * ideal-delta..ideal+delta.  Each argument is evaluated twice.
    + * "ideal" and "delta" should be constants, normally simple
    + * integers, "value" a variable. Added to libpng-1.2.6 JB
    + */
    +#define PNG_OUT_OF_RANGE(value, ideal, delta) \
    +   ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
    +
    +/* Conversions between fixed and floating point, only defined if
    + * required (to make sure the code doesn't accidentally use float
    + * when it is supposedly disabled.)
    + */
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +/* The floating point conversion can't overflow, though it can and
    + * does lose accuracy relative to the original fixed point value.
    + * In practice this doesn't matter because png_fixed_point only
    + * stores numbers with very low precision.  The png_ptr and s
    + * arguments are unused by default but are there in case error
    + * checking becomes a requirement.
    + */
    +#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
    +
    +/* The fixed point conversion performs range checking and evaluates
    + * its argument multiple times, so must be used with care.  The
    + * range checking uses the PNG specification values for a signed
    + * 32-bit fixed point value except that the values are deliberately
    + * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
    + * (2^31-1) * 100000). 's' is a string that describes the value being
    + * converted.
    + *
    + * NOTE: this macro will raise a png_error if the range check fails,
    + * therefore it is normally only appropriate to use this on values
    + * that come from API calls or other sources where an out of range
    + * error indicates a programming error, not a data error!
    + *
    + * NOTE: by default this is off - the macro is not used - because the
    + * function call saves a lot of code.
    + */
    +#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))
    +#endif
    +/* else the corresponding function is defined below, inside the scope of the
    + * cplusplus test.
    + */
    +#endif
    +
    +/* 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_; 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_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_; 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_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
    +#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
    +#define png_gAMA PNG_U32(103,  65,  77,  65)
    +#define png_gIFg PNG_U32(103,  73,  70, 103)
    +#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) & 0xff), \
    +   ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\
    +   ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \
    +   ((char*)(s))[3]=(char)((c & 0xff)))
    +
    +/* 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 directives 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)(0xff & ((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 */
    +
    +/* 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_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
    +   png_const_charp user_png_ver),PNG_EMPTY);
    +
    +/* 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);
    +
    +/* Function to free memory for zlib.  PNGAPI is disallowed. */
    +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_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
    +    png_bytep data, size_t length),PNG_EMPTY);
    +
    +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
    +    png_bytep buffer, size_t length),PNG_EMPTY);
    +#endif
    +
    +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
    +    png_bytep data, size_t length),PNG_EMPTY);
    +
    +#ifdef PNG_WRITE_FLUSH_SUPPORTED
    +#  ifdef PNG_STDIO_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
    +   PNG_EMPTY);
    +#  endif
    +#endif
    +
    +/* Reset the CRC variable */
    +PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
    +
    +/* Write the "data" buffer to whatever output you are using */
    +PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
    +    png_const_bytep data, size_t length),PNG_EMPTY);
    +
    +/* Read and check the PNG file signature */
    +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_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_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
    +    size_t length),PNG_EMPTY);
    +
    +/* Read bytes into buf, and update png_ptr->crc */
    +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_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_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_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
    +   png_const_bytep ptr, size_t length),PNG_EMPTY);
    +
    +#ifdef PNG_WRITE_FLUSH_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
    +#endif
    +
    +/* Write various chunks */
    +
    +/* Write the IHDR chunk, and update the png_struct with the necessary
    + * information.
    + */
    +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_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
    +   png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
    +
    +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_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
    +
    +#ifdef PNG_WRITE_gAMA_SUPPORTED
    +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_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
    +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_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
    +    int intent),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_eXIf_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
    +    png_bytep exif, int num_exif),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_iCCP_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
    +   png_const_charp name, png_const_bytep profile), PNG_EMPTY);
    +   /* 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_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
    +    png_const_sPLT_tp palette),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_tRNS_SUPPORTED
    +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),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_bKGD_SUPPORTED
    +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_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 */
    +#ifdef PNG_WRITE_tEXt_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
    +   png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_zTXt_SUPPORTED
    +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_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_EMPTY);
    +#endif
    +
    +#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
    +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_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_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_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),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_WRITE_tIME_SUPPORTED
    +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_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_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
    +    PNG_EMPTY);
    +
    +/* Internal use only.   Called before first row of data */
    +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.  '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: 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_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_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
    +    png_bytep row, int pass),PNG_EMPTY);
    +#endif
    +
    +/* 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);
    +
    +#if PNG_ARM_NEON_OPT > 0
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
    +    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
    +    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);
    +#endif
    +
    +#if PNG_MIPS_MSA_OPT > 0
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
    +    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +#endif
    +
    +#if PNG_POWERPC_VSX_OPT > 0
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
    +    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +#endif
    +
    +#if PNG_INTEL_SSE_IMPLEMENTATION > 0
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
    +    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
    +#endif
    +
    +/* Choose the best filter to use and filter the row data */
    +PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
    +    png_row_infop row_info),PNG_EMPTY);
    +
    +#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_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
    +
    +#if ZLIB_VERNUM >= 0x1240
    +PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
    +      PNG_EMPTY);
    +#  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
    +#else /* Zlib < 1.2.4 */
    +#  define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
    +#endif /* Zlib < 1.2.4 */
    +
    +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
    +/* Optional call to update the users info structure */
    +PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
    +    png_inforp info_ptr),PNG_EMPTY);
    +#endif
    +
    +/* Shared transform functions, defined in pngtran.c */
    +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
    +    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
    +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_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_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_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_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,
    + * then calls the appropriate callback for the chunk if it is valid.
    + */
    +
    +/* Decode the IHDR chunk */
    +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_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_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_READ_eXIf_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_READ_gAMA_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_READ_hIST_SUPPORTED
    +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_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_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_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_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_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_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_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_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_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_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_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_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_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
    +#endif
    +
    +PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
    +    png_uint_32 chunk_name),PNG_EMPTY);
    +
    +PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
    +    png_uint_32 chunk_length),PNG_EMPTY);
    +
    +PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
    +    png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
    +   /* 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_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_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_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
    +    PNG_EMPTY);
    +#endif
    +
    +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    +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_save_buffer,(png_structrp png_ptr),
    +    PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
    +    png_bytep buffer, 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, 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_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_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_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 /* PROGRESSIVE_READ */
    +
    +/* 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_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. */
    +#ifdef PNG_READ_iCCP_SUPPORTED
    +PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
    +   png_colorspacerp colorspace, png_const_charp name,
    +   png_uint_32 profile_length), PNG_EMPTY);
    +#endif /* READ_iCCP */
    +PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
    +   png_colorspacerp colorspace, png_const_charp name,
    +   png_uint_32 profile_length,
    +   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
    +
    +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
    +PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
    +   png_const_charp name),PNG_NORETURN);
    +#endif
    +
    +/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
    + * the end.  Always leaves the buffer nul terminated.  Never errors out (and
    + * there is no error code.)
    + */
    +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.
    + */
    +#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
    +/* Utility to dump an unsigned value into a buffer, given a start pointer and
    + * and end pointer (which should point just *beyond* the end of the buffer!)
    + * Returns the pointer to the start of the formatted string.  This utility only
    + * does unsigned values.
    + */
    +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) \
    +   png_format_number(buffer, buffer + (sizeof buffer), format, number)
    +
    +/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
    +#define PNG_NUMBER_BUFFER_SIZE 24
    +
    +/* These are the integer formats currently supported, the name is formed from
    + * the standard printf(3) format string.
    + */
    +#define PNG_NUMBER_FORMAT_u     1 /* chose unsigned API! */
    +#define PNG_NUMBER_FORMAT_02u   2
    +#define PNG_NUMBER_FORMAT_d     1 /* chose signed API! */
    +#define PNG_NUMBER_FORMAT_02d   2
    +#define PNG_NUMBER_FORMAT_x     3
    +#define PNG_NUMBER_FORMAT_02x   4
    +#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
    +#endif
    +
    +#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 /* 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.
    + */
    +typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
    +   PNG_WARNING_PARAMETER_SIZE];
    +
    +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_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_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 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_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
    +   png_charp ascii, size_t size, double fp, unsigned int precision),
    +   PNG_EMPTY);
    +#endif /* FLOATING_POINT */
    +
    +#ifdef PNG_FIXED_POINT_SUPPORTED
    +PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
    +   png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY);
    +#endif /* FIXED_POINT */
    +#endif /* sCAL */
    +
    +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
    +/* An internal API to validate the format of a floating point number.
    + * The result is the index of the next character.  If the number is
    + * not valid it will be the index of a character in the supposed number.
    + *
    + * The format of a number is defined in the PNG extensions specification
    + * and this API is strictly conformant to that spec, not anyone elses!
    + *
    + * The format as a regular expression is:
    + *
    + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
    + *
    + * or:
    + *
    + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
    + *
    + * The complexity is that either integer or fraction must be present and the
    + * fraction is permitted to have no digits only if the integer is present.
    + *
    + * NOTE: The dangling E problem.
    + *   There is a PNG valid floating point number in the following:
    + *
    + *       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
    + *   doesn't matter for PNG sCAL chunk values, but it requires more care
    + *   if the value were ever to be embedded in something more complex.  Use
    + *   ANSI-C strtod if you need the lookahead.
    + */
    +/* State table for the parser. */
    +#define PNG_FP_INTEGER    0  /* before or in integer */
    +#define PNG_FP_FRACTION   1  /* before or in fraction */
    +#define PNG_FP_EXPONENT   2  /* before or in exponent */
    +#define PNG_FP_STATE      3  /* mask for the above */
    +#define PNG_FP_SAW_SIGN   4  /* Saw +/- in current state */
    +#define PNG_FP_SAW_DIGIT  8  /* Saw a digit in current state */
    +#define PNG_FP_SAW_DOT   16  /* Saw a dot in current state */
    +#define PNG_FP_SAW_E     32  /* Saw an E (or e) in current state */
    +#define PNG_FP_SAW_ANY   60  /* Saw any of the above 4 */
    +
    +/* These three values don't affect the parser.  They are set but not used.
    + */
    +#define PNG_FP_WAS_VALID 64  /* Preceding substring is a valid fp number */
    +#define PNG_FP_NEGATIVE 128  /* A negative number, including "-0" */
    +#define PNG_FP_NONZERO  256  /* A non-zero value */
    +#define PNG_FP_STICKY   448  /* The above three flags */
    +
    +/* This is available for the caller to store in 'state' if required.  Do not
    + * call the parser after setting it (the parser sometimes clears it.)
    + */
    +#define PNG_FP_INVALID  512  /* Available for callers as a distinct value */
    +
    +/* Result codes for the parser (boolean - true meants ok, false means
    + * not ok yet.)
    + */
    +#define PNG_FP_MAYBE      0  /* The number may be valid in the future */
    +#define PNG_FP_OK         1  /* The number is valid */
    +
    +/* Tests on the sticky non-zero and negative flags.  To pass these checks
    + * the state must also indicate that the whole number is valid - this is
    + * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
    + * is equivalent to PNG_FP_OK above.)
    + */
    +#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
    +   /* NZ_MASK: the string is valid and a non-zero negative value */
    +#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
    +   /* Z MASK: the string is valid and a non-zero value. */
    +   /* PNG_FP_SAW_DIGIT: the string is valid. */
    +#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
    +#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 index into the string and the state variable (which must
    + * 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+ 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
    + * the parser again (from the start, with state 0) but with a string
    + * 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_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
    +   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
    + * function also returns the state at the end of parsing the number if
    + * it was valid (otherwise it returns 0.)  This can be used for testing
    + * for negative or zero values using the sticky flag.
    + */
    +PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
    +   size_t size),PNG_EMPTY);
    +#endif /* pCAL || sCAL */
    +
    +#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
    + * if there is an overflow.  The result is a boolean - false (0)
    + * for overflow, true (1) if no overflow, in which case *res
    + * holds the result.
    + */
    +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_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_GAMMA_SUPPORTED
    +/* Calculate a reciprocal - used for gamma values.  This returns
    + * 0 if the argument is 0 in order to maintain an undefined value;
    + * there are no warnings.
    + */
    +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.  Only required at present on read.
    + */
    +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
    +/* Internal fixed point gamma correction.  These APIs are called as
    + * required to convert single values - they don't need to be fast,
    + * they are not used when processing image pixel values.
    + *
    + * While the input is an 'unsigned' value it must actually be the
    + * correct bit value - 0..255 or 0..65535 as required.
    + */
    +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
    +
    +/* 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. */
    +   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.
    +    */
    +#  if PNG_ARM_NEON_OPT > 0
    +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
    +   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
    +#endif
    +
    +#if PNG_MIPS_MSA_OPT > 0
    +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
    +   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
    +#endif
    +
    +#  if PNG_INTEL_SSE_IMPLEMENTATION > 0
    +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
    +   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
    +#  endif
    +#endif
    +
    +PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
    +   png_const_charp key, png_bytep new_key), PNG_EMPTY);
    +
    +#if PNG_ARM_NEON_IMPLEMENTATION == 1
    +PNG_INTERNAL_FUNCTION(void,
    +                      png_riffle_palette_neon,
    +                      (png_structrp),
    +                      PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(int,
    +                      png_do_expand_palette_rgba8_neon,
    +                      (png_structrp,
    +                       png_row_infop,
    +                       png_const_bytep,
    +                       const png_bytepp,
    +                       const png_bytepp),
    +                      PNG_EMPTY);
    +PNG_INTERNAL_FUNCTION(int,
    +                      png_do_expand_palette_rgb8_neon,
    +                      (png_structrp,
    +                       png_row_infop,
    +                       png_const_bytep,
    +                       const png_bytepp,
    +                       const png_bytepp),
    +                      PNG_EMPTY);
    +#endif
    +
    +/* Maintainer: Put new private prototypes here ^ */
    +
    +#include "pngdebug.h"
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif /* PNG_VERSION_INFO_ONLY */
    +#endif /* PNGPRIV_H */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngread.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,4253 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngread.c - read a PNG file
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file contains routines that an application calls directly to
    + * read a PNG file or stream.
    + */
    +
    +#include "pngpriv.h"
    +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
    +#  include 
    +#endif
    +
    +#ifdef PNG_READ_SUPPORTED
    +
    +/* Create a PNG structure for reading, and allocate any memory needed. */
    +PNG_FUNCTION(png_structp,PNGAPI
    +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)
    +{
    +#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
    + * needed.
    + */
    +PNG_FUNCTION(png_structp,PNGAPI
    +png_create_read_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)
    +{
    +   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)
    +   {
    +      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_RELEASE_BUILD
    +            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);
    +   }
    +
    +   return png_ptr;
    +}
    +
    +
    +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +/* Read the information before the actual image data.  This has been
    + * changed in v0.90 to allow reading a file that already has the magic
    + * bytes read from the stream.  You can tell libpng how many bytes have
    + * been read from the beginning of the stream (up to the maximum of 8)
    + * via png_set_sig_bytes(), and we will only check the remaining bytes
    + * here.  The application can then have access to the signature bytes we
    + * read if it is determined that this isn't a valid PNG file.
    + */
    +void PNGAPI
    +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)
    +      return;
    +
    +   /* Read and check the PNG file signature. */
    +   png_read_sig(png_ptr, info_ptr);
    +
    +   for (;;)
    +   {
    +      png_uint_32 length = png_read_chunk_header(png_ptr);
    +      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_HAVE_CHUNK_AFTER_IDAT;
    +         png_ptr->mode |= PNG_AFTER_IDAT;
    +      }
    +
    +      /* This should be a binary subdivision search or a hash for
    +       * matching the chunk name rather than a linear search.
    +       */
    +      if (chunk_name == png_IHDR)
    +         png_handle_IHDR(png_ptr, info_ptr, length);
    +
    +      else if (chunk_name == png_IEND)
    +         png_handle_IEND(png_ptr, info_ptr, length);
    +
    +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    +      {
    +         png_handle_unknown(png_ptr, info_ptr, length, keep);
    +
    +         if (chunk_name == png_PLTE)
    +            png_ptr->mode |= PNG_HAVE_PLTE;
    +
    +         else if (chunk_name == png_IDAT)
    +         {
    +            png_ptr->idat_size = 0; /* It has been consumed */
    +            break;
    +         }
    +      }
    +#endif
    +      else if (chunk_name == png_PLTE)
    +         png_handle_PLTE(png_ptr, info_ptr, length);
    +
    +      else if (chunk_name == png_IDAT)
    +      {
    +         png_ptr->idat_size = length;
    +         break;
    +      }
    +
    +#ifdef PNG_READ_bKGD_SUPPORTED
    +      else if (chunk_name == png_bKGD)
    +         png_handle_bKGD(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_cHRM_SUPPORTED
    +      else if (chunk_name == png_cHRM)
    +         png_handle_cHRM(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_eXIf_SUPPORTED
    +      else if (chunk_name == png_eXIf)
    +         png_handle_eXIf(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_gAMA_SUPPORTED
    +      else if (chunk_name == png_gAMA)
    +         png_handle_gAMA(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_hIST_SUPPORTED
    +      else if (chunk_name == png_hIST)
    +         png_handle_hIST(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_oFFs_SUPPORTED
    +      else if (chunk_name == png_oFFs)
    +         png_handle_oFFs(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_pCAL_SUPPORTED
    +      else if (chunk_name == png_pCAL)
    +         png_handle_pCAL(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sCAL_SUPPORTED
    +      else if (chunk_name == png_sCAL)
    +         png_handle_sCAL(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_pHYs_SUPPORTED
    +      else if (chunk_name == png_pHYs)
    +         png_handle_pHYs(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sBIT_SUPPORTED
    +      else if (chunk_name == png_sBIT)
    +         png_handle_sBIT(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sRGB_SUPPORTED
    +      else if (chunk_name == png_sRGB)
    +         png_handle_sRGB(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_iCCP_SUPPORTED
    +      else if (chunk_name == png_iCCP)
    +         png_handle_iCCP(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sPLT_SUPPORTED
    +      else if (chunk_name == png_sPLT)
    +         png_handle_sPLT(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tEXt_SUPPORTED
    +      else if (chunk_name == png_tEXt)
    +         png_handle_tEXt(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tIME_SUPPORTED
    +      else if (chunk_name == png_tIME)
    +         png_handle_tIME(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tRNS_SUPPORTED
    +      else if (chunk_name == png_tRNS)
    +         png_handle_tRNS(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_zTXt_SUPPORTED
    +      else if (chunk_name == png_zTXt)
    +         png_handle_zTXt(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_iTXt_SUPPORTED
    +      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_CHUNK_AS_DEFAULT);
    +   }
    +}
    +#endif /* SEQUENTIAL_READ */
    +
    +/* Optional call to update the users info_ptr structure */
    +void PNGAPI
    +png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
    +{
    +   png_debug(1, "in png_read_update_info");
    +
    +   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
    +/* Initialize palette, background, etc, after transformations
    + * are set, but before any reading takes place.  This allows
    + * the user to obtain a gamma-corrected palette, for example.
    + * If the user doesn't call this, we will do it ourselves.
    + */
    +void PNGAPI
    +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   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
    +            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
    +            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
    +            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
    +            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
    +            *(rp    ) = (png_byte)((red >> 8) & 0xff);
    +            *(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;
    +
    +   png_debug2(1, "in png_read_row (row %lu, pass %d)",
    +       (unsigned long)png_ptr->row_number, png_ptr->pass);
    +
    +   /* 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) != 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) != 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) != 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) != 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) != 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) != 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) != 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.
    +    * 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)
    +      {
    +         case 0:
    +            if (png_ptr->row_number & 0x07)
    +            {
    +               if (dsp_row != NULL)
    +                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +
    +         case 1:
    +            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
    +            {
    +               if (dsp_row != NULL)
    +                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
    +
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +
    +         case 2:
    +            if ((png_ptr->row_number & 0x07) != 4)
    +            {
    +               if (dsp_row != NULL && (png_ptr->row_number & 4))
    +                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
    +
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +
    +         case 3:
    +            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
    +            {
    +               if (dsp_row != NULL)
    +                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
    +
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +
    +         case 4:
    +            if ((png_ptr->row_number & 3) != 2)
    +            {
    +               if (dsp_row != NULL && (png_ptr->row_number & 2))
    +                  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, 1/*display*/);
    +
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +
    +         default:
    +         case 6:
    +            if ((png_ptr->row_number & 1) == 0)
    +            {
    +               png_read_finish_row(png_ptr);
    +               return;
    +            }
    +            break;
    +      }
    +   }
    +#endif
    +
    +   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
    +      png_error(png_ptr, "Invalid attempt to read row data");
    +
    +   /* Fill the row with IDAT data: */
    +   png_ptr->row_buf[0]=255; /* to force error if no data was found */
    +   png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
    +
    +   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
    +   {
    +      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
    +         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
    +             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
    +      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) != 0 &&
    +       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    +   {
    +      /* Intrapixel differencing */
    +      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, &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
    +   /* Expand interlaced rows to full size */
    +   if (png_ptr->interlaced != 0 &&
    +      (png_ptr->transformations & PNG_INTERLACE) != 0)
    +   {
    +      if (png_ptr->pass < 6)
    +         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, 1/*display*/);
    +
    +      if (row != NULL)
    +         png_combine_row(png_ptr, row, 0/*row*/);
    +   }
    +
    +   else
    +#endif
    +   {
    +      if (row != NULL)
    +         png_combine_row(png_ptr, row, -1/*ignored*/);
    +
    +      if (dsp_row != NULL)
    +         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 /* SEQUENTIAL_READ */
    +
    +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +/* Read one or more rows of image data.  If the image is interlaced,
    + * and png_set_interlace_handling() has been called, the rows need to
    + * contain the contents of the rows from the previous pass.  If the
    + * image has alpha or transparency, and png_handle_alpha()[*] has been
    + * called, the rows contents must be initialized to the contents of the
    + * screen.
    + *
    + * "row" holds the actual image, and pixels are placed in it
    + * as they arrive.  If the image is displayed after each pass, it will
    + * appear to "sparkle" in.  "display_row" can be used to display a
    + * "chunky" progressive image, with finer detail added as it becomes
    + * available.  If you do not want this "chunky" display, you may pass
    + * NULL for display_row.  If you do not want the sparkle display, and
    + * you have not called png_handle_alpha(), you may pass NULL for rows.
    + * If you have called png_handle_alpha(), and the image has either an
    + * alpha channel or a transparency chunk, you must provide a buffer for
    + * rows.  In this case, you do not have to provide a display_row buffer
    + * also, but you may.  If the image is not interlaced, or if you have
    + * not called png_set_interlace_handling(), the display_row buffer will
    + * be ignored, so pass NULL to it.
    + *
    + * [*] png_handle_alpha() does not exist yet, as of this version of libpng
    + */
    +
    +void PNGAPI
    +png_read_rows(png_structrp png_ptr, png_bytepp row,
    +    png_bytepp display_row, png_uint_32 num_rows)
    +{
    +   png_uint_32 i;
    +   png_bytepp rp;
    +   png_bytepp dp;
    +
    +   png_debug(1, "in png_read_rows");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   rp = row;
    +   dp = display_row;
    +   if (rp != NULL && dp != NULL)
    +      for (i = 0; i < num_rows; i++)
    +      {
    +         png_bytep rptr = *rp++;
    +         png_bytep dptr = *dp++;
    +
    +         png_read_row(png_ptr, rptr, dptr);
    +      }
    +
    +   else if (rp != NULL)
    +      for (i = 0; i < num_rows; i++)
    +      {
    +         png_bytep rptr = *rp;
    +         png_read_row(png_ptr, rptr, NULL);
    +         rp++;
    +      }
    +
    +   else if (dp != NULL)
    +      for (i = 0; i < num_rows; i++)
    +      {
    +         png_bytep dptr = *dp;
    +         png_read_row(png_ptr, NULL, dptr);
    +         dp++;
    +      }
    +}
    +#endif /* SEQUENTIAL_READ */
    +
    +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +/* Read the entire image.  If the image has an alpha channel or a tRNS
    + * chunk, and you have called png_handle_alpha()[*], you will need to
    + * initialize the image to the current image that PNG will be overlaying.
    + * We set the num_rows again here, in case it was incorrectly set in
    + * png_read_start_row() by a call to png_read_update_info() or
    + * png_start_read_image() if png_set_interlace_handling() wasn't called
    + * prior to either of these functions like it should have been.  You can
    + * only call this function once.  If you desire to have an image for
    + * each pass of a interlaced image, use png_read_rows() instead.
    + *
    + * [*] png_handle_alpha() does not exist yet, as of this version of libpng
    + */
    +void PNGAPI
    +png_read_image(png_structrp png_ptr, png_bytepp image)
    +{
    +   png_uint_32 i, image_height;
    +   int pass, j;
    +   png_bytepp rp;
    +
    +   png_debug(1, "in png_read_image");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +#ifdef PNG_READ_INTERLACING_SUPPORTED
    +   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
    +   {
    +      pass = png_set_interlace_handling(png_ptr);
    +      /* And make sure transforms are initialized. */
    +      png_start_read_image(png_ptr);
    +   }
    +   else
    +   {
    +      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,
    +          * but the caller should do it!
    +          */
    +         png_warning(png_ptr, "Interlace handling should be turned on when "
    +             "using png_read_image");
    +         /* Make sure this is set correctly */
    +         png_ptr->num_rows = png_ptr->height;
    +      }
    +
    +      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
    +       * the above error case.
    +       */
    +      pass = png_set_interlace_handling(png_ptr);
    +   }
    +#else
    +   if (png_ptr->interlaced)
    +      png_error(png_ptr,
    +          "Cannot read interlaced image -- interlace handler disabled");
    +
    +   pass = 1;
    +#endif
    +
    +   image_height=png_ptr->height;
    +
    +   for (j = 0; j < pass; j++)
    +   {
    +      rp = image;
    +      for (i = 0; i < image_height; i++)
    +      {
    +         png_read_row(png_ptr, *rp, NULL);
    +         rp++;
    +      }
    +   }
    +}
    +#endif /* SEQUENTIAL_READ */
    +
    +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +/* Read the end of the PNG file.  Will not read past the end of the
    + * file, will verify the end is accurate, and will read any comments
    + * or time information at the end of the file, if info is not NULL.
    + */
    +void PNGAPI
    +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;
    +
    +   /* 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_uint_32 length = png_read_chunk_header(png_ptr);
    +      png_uint_32 chunk_name = png_ptr->chunk_name;
    +
    +      if (chunk_name != png_IDAT)
    +         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
    +
    +      if (chunk_name == png_IEND)
    +         png_handle_IEND(png_ptr, info_ptr, length);
    +
    +      else if (chunk_name == png_IHDR)
    +         png_handle_IHDR(png_ptr, info_ptr, length);
    +
    +      else if (info_ptr == NULL)
    +         png_crc_finish(png_ptr, length);
    +
    +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    +      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    +      {
    +         if (chunk_name == png_IDAT)
    +         {
    +            if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
    +                || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
    +               png_benign_error(png_ptr, ".Too many IDATs found");
    +         }
    +         png_handle_unknown(png_ptr, info_ptr, length, keep);
    +         if (chunk_name == png_PLTE)
    +            png_ptr->mode |= PNG_HAVE_PLTE;
    +      }
    +#endif
    +
    +      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.  1.6 does not
    +          * always read all the deflate data; specifically it cannot be relied
    +          * upon to read the Adler32 at the end.  If it doesn't ignore IDAT
    +          * chunks which are longer than zero as well:
    +          */
    +         if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
    +             || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
    +            png_benign_error(png_ptr, "..Too many IDATs found");
    +
    +         png_crc_finish(png_ptr, length);
    +      }
    +      else if (chunk_name == png_PLTE)
    +         png_handle_PLTE(png_ptr, info_ptr, length);
    +
    +#ifdef PNG_READ_bKGD_SUPPORTED
    +      else if (chunk_name == png_bKGD)
    +         png_handle_bKGD(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_cHRM_SUPPORTED
    +      else if (chunk_name == png_cHRM)
    +         png_handle_cHRM(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_eXIf_SUPPORTED
    +      else if (chunk_name == png_eXIf)
    +         png_handle_eXIf(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_gAMA_SUPPORTED
    +      else if (chunk_name == png_gAMA)
    +         png_handle_gAMA(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_hIST_SUPPORTED
    +      else if (chunk_name == png_hIST)
    +         png_handle_hIST(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_oFFs_SUPPORTED
    +      else if (chunk_name == png_oFFs)
    +         png_handle_oFFs(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_pCAL_SUPPORTED
    +      else if (chunk_name == png_pCAL)
    +         png_handle_pCAL(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sCAL_SUPPORTED
    +      else if (chunk_name == png_sCAL)
    +         png_handle_sCAL(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_pHYs_SUPPORTED
    +      else if (chunk_name == png_pHYs)
    +         png_handle_pHYs(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sBIT_SUPPORTED
    +      else if (chunk_name == png_sBIT)
    +         png_handle_sBIT(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sRGB_SUPPORTED
    +      else if (chunk_name == png_sRGB)
    +         png_handle_sRGB(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_iCCP_SUPPORTED
    +      else if (chunk_name == png_iCCP)
    +         png_handle_iCCP(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_sPLT_SUPPORTED
    +      else if (chunk_name == png_sPLT)
    +         png_handle_sPLT(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tEXt_SUPPORTED
    +      else if (chunk_name == png_tEXt)
    +         png_handle_tEXt(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tIME_SUPPORTED
    +      else if (chunk_name == png_tIME)
    +         png_handle_tIME(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_tRNS_SUPPORTED
    +      else if (chunk_name == png_tRNS)
    +         png_handle_tRNS(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_zTXt_SUPPORTED
    +      else if (chunk_name == png_zTXt)
    +         png_handle_zTXt(png_ptr, info_ptr, length);
    +#endif
    +
    +#ifdef PNG_READ_iTXt_SUPPORTED
    +      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_CHUNK_AS_DEFAULT);
    +   } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
    +}
    +#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
    +
    +#if defined(PNG_READ_EXPAND_SUPPORTED) && \
    +    defined(PNG_ARM_NEON_IMPLEMENTATION)
    +   png_free(png_ptr, png_ptr->riffled_palette);
    +   png_ptr->riffled_palette = 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_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;
    +
    +   /* 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);
    +}
    +
    +void PNGAPI
    +png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->read_row_fn = read_row_fn;
    +}
    +
    +
    +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +#ifdef PNG_INFO_IMAGE_SUPPORTED
    +void PNGAPI
    +png_read_png(png_structrp png_ptr, png_inforp info_ptr,
    +    int transforms, voidp params)
    +{
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   /* png_read_info() gives us all of the information from the
    +    * PNG file before the first IDAT (image data chunk).
    +    */
    +   png_read_info(png_ptr, info_ptr);
    +   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 ------------------- */
    +   /* 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) != 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
    +
    +   /* 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) != 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
    +
    +   /* Strip alpha bytes from the input data without combining with
    +    * the background (not recommended).
    +    */
    +   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
    +
    +   /* 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) != 0)
    +#ifdef PNG_READ_PACK_SUPPORTED
    +      png_set_packing(png_ptr);
    +#else
    +      png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
    +#endif
    +
    +   /* 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) != 0)
    +#ifdef PNG_READ_PACKSWAP_SUPPORTED
    +      png_set_packswap(png_ptr);
    +#else
    +      png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
    +#endif
    +
    +   /* 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) != 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.
    +    */
    +
    +   /* Invert monochrome files to have 0 as white and 1 as black
    +    */
    +   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
    +
    +   /* 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) != 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
    +      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
    +      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
    +      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
    +      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
    +      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
    +      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 */
    +
    +   /* We use png_read_image and rely on that for interlace handling, but we also
    +    * call png_read_update_info therefore must turn on interlace handling now:
    +    */
    +   (void)png_set_interlace_handling(png_ptr);
    +
    +   /* Optional call to gamma correct and add the background to the palette
    +    * and update info structure.  REQUIRED if you are expecting libpng to
    +    * update the palette for you (i.e., you selected such a transform above).
    +    */
    +   png_read_update_info(png_ptr, info_ptr);
    +
    +   /* -------------- image transformations end here ------------------- */
    +
    +   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
    +   if (info_ptr->row_pointers == NULL)
    +   {
    +      png_uint_32 iptr;
    +
    +      info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
    +          info_ptr->height * (sizeof (png_bytep))));
    +
    +      for (iptr=0; iptrheight; iptr++)
    +         info_ptr->row_pointers[iptr] = NULL;
    +
    +      info_ptr->free_me |= PNG_FREE_ROWS;
    +
    +      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);
    +   info_ptr->valid |= PNG_INFO_IDAT;
    +
    +   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
    +   png_read_end(png_ptr, info_ptr);
    +
    +   PNG_UNUSED(params)
    +}
    +#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;
    +
    +#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    +   png_set_benign_errors(png_ptr, 1/*warn*/);
    +#endif
    +   png_read_info(png_ptr, info_ptr);
    +
    +   /* Do this the fast way; just read directly out of png_struct. */
    +   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_uint_32)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, 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;
    +            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, 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 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;
    +
    +#ifdef __GNUC__
    +      default:
    +         png_error(display->image->opaque->png_ptr,
    +             "unexpected encoding (internal error)");
    +#endif
    +   }
    +
    +   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;
    +   int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
    +       P_LINEAR : P_sRGB;
    +   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);
    +            alpha = PNG_DIV257(alpha);
    +            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
    +         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
    +         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;
    +               /* FALLTHROUGH */
    +
    +            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;
    +               /* FALLTHROUGH */
    +
    +            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;
    +               /* FALLTHROUGH */
    +            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;
    +               /* FALLTHROUGH */
    +            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 (int)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 (int)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 (int)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 (int)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);
    +   png_imagep image = display->image;
    +
    +   png_structrp png_ptr = image->opaque->png_ptr;
    +   png_uint_32 output_format = image->format;
    +   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,
    +             "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; ibit_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 = (unsigned int)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;
    +                  }
    +#ifdef __COVERITY__
    +                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
    +                  * here.
    +                  */
    +                  back_alpha = 255;
    +#else
    +                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
    +#endif
    +               }
    +
    +               /* 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 = (unsigned int)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 = (unsigned int)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,
    +#ifdef __COVERITY__
    +                   /* Coverity claims that output_encoding
    +                    * cannot be 2 (P_LINEAR) here.
    +                    */ 255U,
    +#else
    +                    output_encoding == P_LINEAR ? 65535U : 255U,
    +#endif
    +                    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 = (unsigned int)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 = (unsigned int)make_gray_file_colormap(display);
    +                  data_encoding = P_FILE;
    +               }
    +
    +               else
    +                  cmap_entries = (unsigned int)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 = (unsigned int)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 = (unsigned int)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 = (unsigned int)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;
    +            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 = (unsigned int)png_ptr->num_palette;
    +            if (cmap_entries > 256)
    +               cmap_entries = 256;
    +
    +            if (cmap_entries > (unsigned int)image->colormap_entries)
    +               png_error(png_ptr, "palette color-map: too few entries");
    +
    +            for (i=0; i < cmap_entries; ++i)
    +            {
    +               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*/
    +   }
    +
    +   /* 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)
    +   {
    +      case P_sRGB:
    +         /* Change to 8-bit sRGB */
    +         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
    +         /* FALLTHROUGH */
    +
    +      case P_FILE:
    +         if (png_ptr->bit_depth > 8)
    +            png_set_scale_16(png_ptr);
    +         break;
    +
    +#ifdef __GNUC__
    +      default:
    +         png_error(png_ptr, "bad data option (internal error)");
    +#endif
    +   }
    +
    +   if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
    +      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 = (int)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 (; ylocal_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;
    +
    +      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 = (png_alloc_size_t)display->row_bytes;
    +
    +      while (--passes >= 0)
    +      {
    +         png_uint_32      y = image->height;
    +         png_bytep        row = png_voidcast(png_bytep, display->first_row);
    +
    +         for (; y > 0; --y)
    +         {
    +            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 (; ylocal_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; cimage;
    +   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)
    +   {
    +      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 (; ylocal_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 (; ylocal_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;
    +            unsigned int preserve_alpha = (image->format &
    +                PNG_FORMAT_FLAG_ALPHA) != 0;
    +            unsigned int outchannels = 1U+preserve_alpha;
    +            int swap_alpha = 0;
    +
    +#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
    +               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 (; ylocal_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;
    +
    +#ifdef __GNUC__
    +      default:
    +         png_error(png_ptr, "unexpected bit depth");
    +#endif
    +   }
    +
    +   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 ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
    +      {
    +         mode = PNG_ALPHA_OPTIMIZED;
    +         change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
    +      }
    +
    +      /* If 'do_local_background' is set check for the presence of gamma
    +       * correction; this is part of the work-round for the libpng bug
    +       * described above.
    +       *
    +       * 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_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 ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
    +         info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
    +      }
    +
    +      if (info_ptr->bit_depth == 16)
    +         info_format |= PNG_FORMAT_FLAG_LINEAR;
    +
    +#ifdef PNG_FORMAT_BGR_SUPPORTED
    +      if ((png_ptr->transformations & PNG_BGR) != 0)
    +         info_format |= PNG_FORMAT_FLAG_BGR;
    +#endif
    +
    +#ifdef PNG_FORMAT_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 = (png_alloc_size_t)display->row_bytes;
    +
    +      while (--passes >= 0)
    +      {
    +         png_uint_32      y = image->height;
    +         png_bytep        row = png_voidcast(png_bytep, display->first_row);
    +
    +         for (; y > 0; --y)
    +         {
    +            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)
    +   {
    +      /* Check for row_stride overflow.  This check is not performed on the
    +       * original PNG format because it may not occur in the output PNG format
    +       * and libpng deals with the issues of reading the original.
    +       */
    +      unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
    +
    +      /* The following checks just the 'row_stride' calculation to ensure it
    +       * fits in a signed 32-bit value.  Because channels/components can be
    +       * either 1 or 2 bytes in size the length of a row can still overflow 32
    +       * bits; this is just to verify that the 'row_stride' argument can be
    +       * represented.
    +       */
    +      if (image->width <= 0x7fffffffU/channels) /* no overflow */
    +      {
    +         png_uint_32 check;
    +         png_uint_32 png_row_stride = image->width * channels;
    +
    +         if (row_stride == 0)
    +            row_stride = (png_int_32)/*SAFE*/png_row_stride;
    +
    +         if (row_stride < 0)
    +            check = (png_uint_32)(-row_stride);
    +
    +         else
    +            check = (png_uint_32)row_stride;
    +
    +         /* This verifies 'check', the absolute value of the actual stride
    +          * passed in and detects overflow in the application calculation (i.e.
    +          * if the app did actually pass in a non-zero 'row_stride'.
    +          */
    +         if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
    +         {
    +            /* Now check for overflow of the image buffer calculation; this
    +             * limits the whole image size to 32 bits for API compatibility with
    +             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
    +             *
    +             * The PNG_IMAGE_BUFFER_SIZE macro is:
    +             *
    +             *    (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
    +             *
    +             * And the component size is always 1 or 2, so make sure that the
    +             * number of *bytes* that the application is saying are available
    +             * does actually fit into a 32-bit number.
    +             *
    +             * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
    +             * will be changed to use png_alloc_size_t; bigger images can be
    +             * accommodated on 64-bit systems.
    +             */
    +            if (image->height <=
    +                0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
    +            {
    +               if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
    +                  (image->colormap_entries > 0 && colormap != NULL))
    +               {
    +                  int result;
    +                  png_image_read_control display;
    +
    +                  memset(&display, 0, (sizeof display));
    +                  display.image = image;
    +                  display.buffer = buffer;
    +                  display.row_stride = row_stride;
    +                  display.colormap = colormap;
    +                  display.background = background;
    +                  display.local_row = NULL;
    +
    +                  /* Choose the correct 'end' routine; for the color-map case
    +                   * all the setup has already been done.
    +                   */
    +                  if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
    +                     result =
    +                         png_safe_execute(image,
    +                             png_image_read_colormap, &display) &&
    +                             png_safe_execute(image,
    +                             png_image_read_colormapped, &display);
    +
    +                  else
    +                     result =
    +                        png_safe_execute(image,
    +                            png_image_read_direct, &display);
    +
    +                  png_image_free(image);
    +                  return result;
    +               }
    +
    +               else
    +                  return png_image_error(image,
    +                      "png_image_finish_read[color-map]: no color-map");
    +            }
    +
    +            else
    +               return png_image_error(image,
    +                   "png_image_finish_read: image too large");
    +         }
    +
    +         else
    +            return png_image_error(image,
    +                "png_image_finish_read: invalid argument");
    +      }
    +
    +      else
    +         return png_image_error(image,
    +             "png_image_finish_read: row_stride too large");
    +   }
    +
    +   else if (image != NULL)
    +      return png_image_error(image,
    +          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
    +
    +   return 0;
    +}
    +
    +#endif /* SIMPLIFIED_READ */
    +#endif /* READ */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrio.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrio.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrio.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrio.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,148 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngrio.c - functions for data input
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file provides a location for all input.  Users who need
    + * special handling are expected to write a function that has the same
    + * arguments as this and performs a similar function, but that possibly
    + * has a different input method.  Note that you shouldn't change this
    + * function, but rather write a replacement function and then make
    + * libpng use it at run time with png_set_read_fn(...).
    + */
    +
    +#include "pngpriv.h"
    +
    +#ifdef PNG_READ_SUPPORTED
    +
    +/* Read the data from whatever input you are using.  The default routine
    + * reads from a file pointer.  Note that this routine sometimes gets called
    + * with very small lengths, so you should implement some kind of simple
    + * buffering if you are using unbuffered reads.  This should never be asked
    + * to read more than 64K on a 16-bit machine.
    + */
    +void /* PRIVATE */
    +png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
    +{
    +   png_debug1(4, "reading %d bytes", (int)length);
    +
    +   if (png_ptr->read_data_fn != NULL)
    +      (*(png_ptr->read_data_fn))(png_ptr, data, length);
    +
    +   else
    +      png_error(png_ptr, "Call to NULL read function");
    +}
    +
    +#ifdef PNG_STDIO_SUPPORTED
    +/* This is the function that does the actual reading of data.  If you are
    + * not reading from a standard C stream, you should create a replacement
    + * read_data function and use it at run time with png_set_read_fn(), rather
    + * than changing the library.
    + */
    +void PNGCBAPI
    +png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
    +{
    +   size_t check;
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   /* fread() returns 0 on error, so it is OK to store this in a size_t
    +    * instead of an int, which is what fread() actually returns.
    +    */
    +   check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
    +
    +   if (check != length)
    +      png_error(png_ptr, "Read Error");
    +}
    +#endif
    +
    +/* This function allows the application to supply a new input function
    + * for libpng if standard C streams aren't being used.
    + *
    + * This function takes as its arguments:
    + *
    + * png_ptr      - pointer to a png input data structure
    + *
    + * io_ptr       - pointer to user supplied structure containing info about
    + *                the input functions.  May be NULL.
    + *
    + * read_data_fn - pointer to a new input function that takes as its
    + *                arguments a pointer to a png_struct, a pointer to
    + *                a location where input data can be stored, and a 32-bit
    + *                unsigned int that is the number of bytes to be read.
    + *                To exit and output any fatal error messages the new write
    + *                function should call png_error(png_ptr, "Error msg").
    + *                May be NULL, in which case libpng's default function will
    + *                be used.
    + */
    +void PNGAPI
    +png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
    +    png_rw_ptr read_data_fn)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->io_ptr = io_ptr;
    +
    +#ifdef PNG_STDIO_SUPPORTED
    +   if (read_data_fn != NULL)
    +      png_ptr->read_data_fn = read_data_fn;
    +
    +   else
    +      png_ptr->read_data_fn = png_default_read_data;
    +#else
    +   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)
    +   {
    +      png_ptr->write_data_fn = NULL;
    +      png_warning(png_ptr,
    +          "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 /* READ */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrtran.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,5072 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngrtran.c - transforms the data in a row for PNG readers
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file contains functions optionally called by an application
    + * in order to tell libpng how to handle data when reading a PNG.
    + * Transformations that are used in both reading and writing are
    + * in pngtrans.c.
    + */
    +
    +#include "pngpriv.h"
    +
    +#ifdef PNG_ARM_NEON_IMPLEMENTATION
    +#  if PNG_ARM_NEON_IMPLEMENTATION == 1
    +#    define PNG_ARM_NEON_INTRINSICS_AVAILABLE
    +#    if defined(_MSC_VER) && defined(_M_ARM64)
    +#      include 
    +#    else
    +#      include 
    +#    endif
    +#  endif
    +#endif
    +
    +#ifdef PNG_READ_SUPPORTED
    +
    +/* Set the action on getting a CRC error for an ancillary or critical chunk. */
    +void PNGAPI
    +png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
    +{
    +   png_debug(1, "in png_set_crc_action");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   /* Tell libpng how we react to CRC errors in critical chunks */
    +   switch (crit_action)
    +   {
    +      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
    +         break;
    +
    +      case PNG_CRC_WARN_USE:                               /* Warn/use data */
    +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
    +         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
    +         break;
    +
    +      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
    +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
    +         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
    +                           PNG_FLAG_CRC_CRITICAL_IGNORE;
    +         break;
    +
    +      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
    +         png_warning(png_ptr,
    +             "Can't discard critical data on CRC error");
    +         /* FALLTHROUGH */
    +      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
    +
    +      case PNG_CRC_DEFAULT:
    +      default:
    +         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
    +         break;
    +   }
    +
    +   /* Tell libpng how we react to CRC errors in ancillary chunks */
    +   switch (ancil_action)
    +   {
    +      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
    +         break;
    +
    +      case PNG_CRC_WARN_USE:                              /* Warn/use data */
    +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
    +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
    +         break;
    +
    +      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
    +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
    +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
    +                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
    +         break;
    +
    +      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
    +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
    +         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
    +         break;
    +
    +      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
    +
    +      case PNG_CRC_DEFAULT:
    +      default:
    +         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
    +         break;
    +   }
    +}
    +
    +#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_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_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
    +      return;
    +
    +   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
    +   {
    +      png_warning(png_ptr, "Application must supply a known background gamma");
    +      return;
    +   }
    +
    +   png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
    +   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +
    +   png_ptr->background = *background_color;
    +   png_ptr->background_gamma = background_gamma;
    +   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
    +   if (need_expand != 0)
    +      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
    +   else
    +      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
    +}
    +
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +void PNGAPI
    +png_set_background(png_structrp png_ptr,
    +    png_const_color_16p background_color, int background_gamma_code,
    +    int need_expand, double background_gamma)
    +{
    +   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
    +      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
    +}
    +#  endif /* FLOATING_POINT */
    +#endif /* READ_BACKGROUND */
    +
    +/* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
    + * one that pngrtran does first (scale) happens.  This is necessary to allow the
    + * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
    + */
    +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
    +void PNGAPI
    +png_set_scale_16(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_scale_16");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= PNG_SCALE_16_TO_8;
    +}
    +#endif
    +
    +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
    +/* Chop 16-bit depth files to 8-bit depth */
    +void PNGAPI
    +png_set_strip_16(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_strip_16");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= PNG_16_TO_8;
    +}
    +#endif
    +
    +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
    +void PNGAPI
    +png_set_strip_alpha(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_strip_alpha");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= PNG_STRIP_ALPHA;
    +}
    +#endif
    +
    +#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
    +static png_fixed_point
    +translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
    +    int is_screen)
    +{
    +   /* Check for flag values.  The main reason for having the old Mac value as a
    +    * flag is that it is pretty near impossible to work out what the correct
    +    * value is from Apple documentation - a working Mac system is needed to
    +    * discover the value!
    +    */
    +   if (output_gamma == PNG_DEFAULT_sRGB ||
    +      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
    +   {
    +      /* If there is no sRGB support this just sets the gamma to the standard
    +       * sRGB value.  (This is a side effect of using this function!)
    +       */
    +#     ifdef PNG_READ_sRGB_SUPPORTED
    +         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
    +#     else
    +         PNG_UNUSED(png_ptr)
    +#     endif
    +      if (is_screen != 0)
    +         output_gamma = PNG_GAMMA_sRGB;
    +      else
    +         output_gamma = PNG_GAMMA_sRGB_INVERSE;
    +   }
    +
    +   else if (output_gamma == PNG_GAMMA_MAC_18 ||
    +      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
    +   {
    +      if (is_screen != 0)
    +         output_gamma = PNG_GAMMA_MAC_OLD;
    +      else
    +         output_gamma = PNG_GAMMA_MAC_INVERSE;
    +   }
    +
    +   return output_gamma;
    +}
    +
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +static png_fixed_point
    +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
    +    * means the fixed point constants work just fine with the floating point
    +    * API.  The alternative would just lead to undetected errors and spurious
    +    * bug reports.  Negative values fail inside the _fixed API unless they
    +    * correspond to the flag values.
    +    */
    +   if (output_gamma > 0 && output_gamma < 128)
    +      output_gamma *= PNG_FP_1;
    +
    +   /* This preserves -1 and -2 exactly: */
    +   output_gamma = floor(output_gamma + .5);
    +
    +   if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
    +      png_fixed_error(png_ptr, "gamma value");
    +
    +   return (png_fixed_point)output_gamma;
    +}
    +#  endif
    +#endif /* READ_ALPHA_MODE || READ_GAMMA */
    +
    +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
    +void PNGFAPI
    +png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
    +    png_fixed_point output_gamma)
    +{
    +   int compose = 0;
    +   png_fixed_point file_gamma;
    +
    +   png_debug(1, "in png_set_alpha_mode");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
    +
    +   /* Validate the value to ensure it is in a reasonable range. The value
    +    * is expected to be 1 or greater, but this range test allows for some
    +    * viewing correction values.  The intent is to weed out users of this API
    +    * who use the inverse of the gamma value accidentally!  Since some of these
    +    * values are reasonable this may have to be changed:
    +    *
    +    * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit
    +    * gamma of 36, and its reciprocal.)
    +    */
    +   if (output_gamma < 1000 || output_gamma > 10000000)
    +      png_error(png_ptr, "output gamma out of expected range");
    +
    +   /* The default file gamma is the inverse of the output gamma; the output
    +    * gamma may be changed below so get the file value first:
    +    */
    +   file_gamma = png_reciprocal(output_gamma);
    +
    +   /* There are really 8 possibilities here, composed of any combination
    +    * of:
    +    *
    +    *    premultiply the color channels
    +    *    do not encode non-opaque pixels
    +    *    encode the alpha as well as the color channels
    +    *
    +    * The differences disappear if the input/output ('screen') gamma is 1.0,
    +    * because then the encoding is a no-op and there is only the choice of
    +    * premultiplying the color channels or not.
    +    *
    +    * png_set_alpha_mode and png_set_background interact because both use
    +    * png_compose to do the work.  Calling both is only useful when
    +    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
    +    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
    +    */
    +   switch (mode)
    +   {
    +      case PNG_ALPHA_PNG:        /* default: png standard */
    +         /* No compose, but it may be set by png_set_background! */
    +         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +         break;
    +
    +      case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
    +         compose = 1;
    +         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +         /* The output is linear: */
    +         output_gamma = PNG_FP_1;
    +         break;
    +
    +      case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
    +         compose = 1;
    +         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
    +         /* output_gamma records the encoding of opaque pixels! */
    +         break;
    +
    +      case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
    +         compose = 1;
    +         png_ptr->transformations |= PNG_ENCODE_ALPHA;
    +         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +         break;
    +
    +      default:
    +         png_error(png_ptr, "invalid alpha mode");
    +   }
    +
    +   /* Only set the default gamma if the file gamma has not been set (this has
    +    * the side effect that the gamma in a second call to png_set_alpha_mode will
    +    * be ignored.)
    +    */
    +   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;
    +
    +   /* Finally, if pre-multiplying, set the background fields to achieve the
    +    * desired result.
    +    */
    +   if (compose != 0)
    +   {
    +      /* And obtain alpha pre-multiplication by composing on black: */
    +      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) != 0)
    +         png_error(png_ptr,
    +             "conflicting calls to set alpha mode and background");
    +
    +      png_ptr->transformations |= PNG_COMPOSE;
    +   }
    +}
    +
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +void PNGAPI
    +png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
    +{
    +   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
    +       output_gamma));
    +}
    +#  endif
    +#endif
    +
    +#ifdef PNG_READ_QUANTIZE_SUPPORTED
    +/* Dither file to 8-bit.  Supply a palette, the current number
    + * of elements in the palette, the maximum number of elements
    + * allowed, and a histogram if possible.  If the current number
    + * of colors is greater than the maximum number, the palette will be
    + * modified to fit in the maximum number.  "full_quantize" indicates
    + * whether we need a quantizing cube set up for RGB images, or if we
    + * simply are reducing the number of colors in a paletted image.
    + */
    +
    +typedef struct png_dsort_struct
    +{
    +   struct png_dsort_struct * next;
    +   png_byte left;
    +   png_byte right;
    +} png_dsort;
    +typedef png_dsort *   png_dsortp;
    +typedef png_dsort * * png_dsortpp;
    +
    +void PNGAPI
    +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_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= PNG_QUANTIZE;
    +
    +   if (full_quantize == 0)
    +   {
    +      int i;
    +
    +      png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
    +          (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
    +      for (i = 0; i < num_palette; i++)
    +         png_ptr->quantize_index[i] = (png_byte)i;
    +   }
    +
    +   if (num_palette > maximum_colors)
    +   {
    +      if (histogram != NULL)
    +      {
    +         /* This is easy enough, just throw out the least used colors.
    +          * Perhaps not the best solution, but good enough.
    +          */
    +
    +         int i;
    +
    +         /* Initialize an array to sort colors */
    +         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
    +             (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
    +
    +         /* Initialize the quantize_sort array */
    +         for (i = 0; i < num_palette; i++)
    +            png_ptr->quantize_sort[i] = (png_byte)i;
    +
    +         /* Find the least used palette entries by starting a
    +          * bubble sort, and running it until we have sorted
    +          * out enough colors.  Note that we don't care about
    +          * sorting all the colors, just finding which are
    +          * least used.
    +          */
    +
    +         for (i = num_palette - 1; i >= maximum_colors; i--)
    +         {
    +            int done; /* To stop early if the list is pre-sorted */
    +            int j;
    +
    +            done = 1;
    +            for (j = 0; j < i; j++)
    +            {
    +               if (histogram[png_ptr->quantize_sort[j]]
    +                   < histogram[png_ptr->quantize_sort[j + 1]])
    +               {
    +                  png_byte t;
    +
    +                  t = png_ptr->quantize_sort[j];
    +                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
    +                  png_ptr->quantize_sort[j + 1] = t;
    +                  done = 0;
    +               }
    +            }
    +
    +            if (done != 0)
    +               break;
    +         }
    +
    +         /* Swap the palette around, and set up a table, if necessary */
    +         if (full_quantize != 0)
    +         {
    +            int j = num_palette;
    +
    +            /* Put all the useful colors within the max, but don't
    +             * move the others.
    +             */
    +            for (i = 0; i < maximum_colors; i++)
    +            {
    +               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
    +               {
    +                  do
    +                     j--;
    +                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
    +
    +                  palette[i] = palette[j];
    +               }
    +            }
    +         }
    +         else
    +         {
    +            int j = num_palette;
    +
    +            /* Move all the used colors inside the max limit, and
    +             * develop a translation table.
    +             */
    +            for (i = 0; i < maximum_colors; i++)
    +            {
    +               /* Only move the colors we need to */
    +               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
    +               {
    +                  png_color tmp_color;
    +
    +                  do
    +                     j--;
    +                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
    +
    +                  tmp_color = palette[j];
    +                  palette[j] = palette[i];
    +                  palette[i] = tmp_color;
    +                  /* Indicate where the color went */
    +                  png_ptr->quantize_index[j] = (png_byte)i;
    +                  png_ptr->quantize_index[i] = (png_byte)j;
    +               }
    +            }
    +
    +            /* Find closest color for those colors we are not using */
    +            for (i = 0; i < num_palette; i++)
    +            {
    +               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
    +               {
    +                  int min_d, k, min_k, d_index;
    +
    +                  /* Find the closest color to one we threw out */
    +                  d_index = png_ptr->quantize_index[i];
    +                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
    +                  for (k = 1, min_k = 0; k < maximum_colors; k++)
    +                  {
    +                     int d;
    +
    +                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
    +
    +                     if (d < min_d)
    +                     {
    +                        min_d = d;
    +                        min_k = k;
    +                     }
    +                  }
    +                  /* Point to closest color */
    +                  png_ptr->quantize_index[i] = (png_byte)min_k;
    +               }
    +            }
    +         }
    +         png_free(png_ptr, png_ptr->quantize_sort);
    +         png_ptr->quantize_sort = NULL;
    +      }
    +      else
    +      {
    +         /* This is much harder to do simply (and quickly).  Perhaps
    +          * we need to go through a median cut routine, but those
    +          * don't always behave themselves with only a few colors
    +          * as input.  So we will just find the closest two colors,
    +          * and throw out one of them (chosen somewhat randomly).
    +          * [We don't understand this at all, so if someone wants to
    +          *  work on improving it, be our guest - AED, GRP]
    +          */
    +         int i;
    +         int max_d;
    +         int num_new_palette;
    +         png_dsortp t;
    +         png_dsortpp hash;
    +
    +         t = NULL;
    +
    +         /* Initialize palette index arrays */
    +         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
    +             (png_alloc_size_t)((png_uint_32)num_palette *
    +             (sizeof (png_byte))));
    +         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
    +             (png_alloc_size_t)((png_uint_32)num_palette *
    +             (sizeof (png_byte))));
    +
    +         /* Initialize the sort array */
    +         for (i = 0; i < num_palette; i++)
    +         {
    +            png_ptr->index_to_palette[i] = (png_byte)i;
    +            png_ptr->palette_to_index[i] = (png_byte)i;
    +         }
    +
    +         hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
    +             (sizeof (png_dsortp))));
    +
    +         num_new_palette = num_palette;
    +
    +         /* Initial wild guess at how far apart the farthest pixel
    +          * pair we will be eliminating will be.  Larger
    +          * numbers mean more areas will be allocated, Smaller
    +          * numbers run the risk of not saving enough data, and
    +          * having to do this all over again.
    +          *
    +          * I have not done extensive checking on this number.
    +          */
    +         max_d = 96;
    +
    +         while (num_new_palette > maximum_colors)
    +         {
    +            for (i = 0; i < num_new_palette - 1; i++)
    +            {
    +               int j;
    +
    +               for (j = i + 1; j < num_new_palette; j++)
    +               {
    +                  int d;
    +
    +                  d = PNG_COLOR_DIST(palette[i], palette[j]);
    +
    +                  if (d <= max_d)
    +                  {
    +
    +                     t = (png_dsortp)png_malloc_warn(png_ptr,
    +                         (png_alloc_size_t)(sizeof (png_dsort)));
    +
    +                     if (t == NULL)
    +                         break;
    +
    +                     t->next = hash[d];
    +                     t->left = (png_byte)i;
    +                     t->right = (png_byte)j;
    +                     hash[d] = t;
    +                  }
    +               }
    +               if (t == NULL)
    +                  break;
    +            }
    +
    +            if (t != NULL)
    +            for (i = 0; i <= max_d; i++)
    +            {
    +               if (hash[i] != NULL)
    +               {
    +                  png_dsortp p;
    +
    +                  for (p = hash[i]; p; p = p->next)
    +                  {
    +                     if ((int)png_ptr->index_to_palette[p->left]
    +                         < num_new_palette &&
    +                         (int)png_ptr->index_to_palette[p->right]
    +                         < num_new_palette)
    +                     {
    +                        int j, next_j;
    +
    +                        if (num_new_palette & 0x01)
    +                        {
    +                           j = p->left;
    +                           next_j = p->right;
    +                        }
    +                        else
    +                        {
    +                           j = p->right;
    +                           next_j = p->left;
    +                        }
    +
    +                        num_new_palette--;
    +                        palette[png_ptr->index_to_palette[j]]
    +                            = palette[num_new_palette];
    +                        if (full_quantize == 0)
    +                        {
    +                           int k;
    +
    +                           for (k = 0; k < num_palette; k++)
    +                           {
    +                              if (png_ptr->quantize_index[k] ==
    +                                  png_ptr->index_to_palette[j])
    +                                 png_ptr->quantize_index[k] =
    +                                     png_ptr->index_to_palette[next_j];
    +
    +                              if ((int)png_ptr->quantize_index[k] ==
    +                                  num_new_palette)
    +                                 png_ptr->quantize_index[k] =
    +                                     png_ptr->index_to_palette[j];
    +                           }
    +                        }
    +
    +                        png_ptr->index_to_palette[png_ptr->palette_to_index
    +                            [num_new_palette]] = png_ptr->index_to_palette[j];
    +
    +                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
    +                            = png_ptr->palette_to_index[num_new_palette];
    +
    +                        png_ptr->index_to_palette[j] =
    +                            (png_byte)num_new_palette;
    +
    +                        png_ptr->palette_to_index[num_new_palette] =
    +                            (png_byte)j;
    +                     }
    +                     if (num_new_palette <= maximum_colors)
    +                        break;
    +                  }
    +                  if (num_new_palette <= maximum_colors)
    +                     break;
    +               }
    +            }
    +
    +            for (i = 0; i < 769; i++)
    +            {
    +               if (hash[i] != NULL)
    +               {
    +                  png_dsortp p = hash[i];
    +                  while (p)
    +                  {
    +                     t = p->next;
    +                     png_free(png_ptr, p);
    +                     p = t;
    +                  }
    +               }
    +               hash[i] = 0;
    +            }
    +            max_d += 96;
    +         }
    +         png_free(png_ptr, hash);
    +         png_free(png_ptr, png_ptr->palette_to_index);
    +         png_free(png_ptr, png_ptr->index_to_palette);
    +         png_ptr->palette_to_index = NULL;
    +         png_ptr->index_to_palette = NULL;
    +      }
    +      num_palette = maximum_colors;
    +   }
    +   if (png_ptr->palette == NULL)
    +   {
    +      png_ptr->palette = palette;
    +   }
    +   png_ptr->num_palette = (png_uint_16)num_palette;
    +
    +   if (full_quantize != 0)
    +   {
    +      int i;
    +      png_bytep distance;
    +      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
    +          PNG_QUANTIZE_BLUE_BITS;
    +      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
    +      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
    +      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
    +      size_t num_entries = ((size_t)1 << total_bits);
    +
    +      png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
    +          (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
    +
    +      distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
    +          (sizeof (png_byte))));
    +
    +      memset(distance, 0xff, num_entries * (sizeof (png_byte)));
    +
    +      for (i = 0; i < num_palette; i++)
    +      {
    +         int ir, ig, ib;
    +         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
    +         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
    +         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
    +
    +         for (ir = 0; ir < num_red; ir++)
    +         {
    +            /* int dr = abs(ir - r); */
    +            int dr = ((ir > r) ? ir - r : r - ir);
    +            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
    +                PNG_QUANTIZE_GREEN_BITS));
    +
    +            for (ig = 0; ig < num_green; ig++)
    +            {
    +               /* int dg = abs(ig - g); */
    +               int dg = ((ig > g) ? ig - g : g - ig);
    +               int dt = dr + dg;
    +               int dm = ((dr > dg) ? dr : dg);
    +               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
    +
    +               for (ib = 0; ib < num_blue; ib++)
    +               {
    +                  int d_index = index_g | ib;
    +                  /* int db = abs(ib - b); */
    +                  int db = ((ib > b) ? ib - b : b - ib);
    +                  int dmax = ((dm > db) ? dm : db);
    +                  int d = dmax + dt + db;
    +
    +                  if (d < (int)distance[d_index])
    +                  {
    +                     distance[d_index] = (png_byte)d;
    +                     png_ptr->palette_lookup[d_index] = (png_byte)i;
    +                  }
    +               }
    +            }
    +         }
    +      }
    +
    +      png_free(png_ptr, distance);
    +   }
    +}
    +#endif /* READ_QUANTIZE */
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +void PNGFAPI
    +png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
    +    png_fixed_point file_gamma)
    +{
    +   png_debug(1, "in png_set_gamma_fixed");
    +
    +   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*/);
    +
    +   /* 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
    +    * disabled in background handling.  There is no evidence (so far) that this
    +    * was being used; however, png_set_background itself accepted and must still
    +    * 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) 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");
    +
    +   /* 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->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_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 */
    +#endif /* READ_GAMMA */
    +
    +#ifdef PNG_READ_EXPAND_SUPPORTED
    +/* Expand paletted images to RGB, expand grayscale images of
    + * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
    + * to alpha channels.
    + */
    +void PNGAPI
    +png_set_expand(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_expand");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    +}
    +
    +/* GRR 19990627:  the following three functions currently are identical
    + *  to png_set_expand().  However, it is entirely reasonable that someone
    + *  might wish to expand an indexed image to RGB but *not* expand a single,
    + *  fully transparent palette entry to a full alpha channel--perhaps instead
    + *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
    + *  the transparent color with a particular RGB value, or drop tRNS entirely.
    + *  IOW, a future version of the library may make the transformations flag
    + *  a bit more fine-grained, with separate bits for each of these three
    + *  functions.
    + *
    + *  More to the point, these functions make it obvious what libpng will be
    + *  doing, whereas "expand" can (and does) mean any number of things.
    + *
    + *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
    + *  to expand only the sample depth but not to expand the tRNS to alpha
    + *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
    + */
    +
    +/* Expand paletted images to RGB. */
    +void PNGAPI
    +png_set_palette_to_rgb(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_palette_to_rgb");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    +}
    +
    +/* Expand grayscale images of less than 8-bit depth to 8 bits. */
    +void PNGAPI
    +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_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= PNG_EXPAND;
    +}
    +
    +/* Expand tRNS chunks to alpha channels. */
    +void PNGAPI
    +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);
    +}
    +#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_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_expand_16");
    +
    +   if (png_rtran_ok(png_ptr, 0) == 0)
    +      return;
    +
    +   png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
    +}
    +#endif
    +
    +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    +void PNGAPI
    +png_set_gray_to_rgb(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_gray_to_rgb");
    +
    +   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_structrp png_ptr, int error_action,
    +    png_fixed_point red, png_fixed_point green)
    +{
    +   png_debug(1, "in png_set_rgb_to_gray");
    +
    +   /* 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)
    +   {
    +      case PNG_ERROR_ACTION_NONE:
    +         png_ptr->transformations |= PNG_RGB_TO_GRAY;
    +         break;
    +
    +      case PNG_ERROR_ACTION_WARN:
    +         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
    +         break;
    +
    +      case PNG_ERROR_ACTION_ERROR:
    +         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
    +         break;
    +
    +      default:
    +         png_error(png_ptr, "invalid error action to rgb_to_gray");
    +   }
    +
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +#ifdef PNG_READ_EXPAND_SUPPORTED
    +      png_ptr->transformations |= PNG_EXPAND;
    +#else
    +   {
    +      /* 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; */
    +   }
    +#endif
    +   {
    +      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
    +      {
    +         png_uint_16 red_int, green_int;
    +
    +         /* 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_coefficients_set = 1;
    +      }
    +
    +      else
    +      {
    +         if (red >= 0 && green >= 0)
    +            png_app_warning(png_ptr,
    +                "ignoring out of range rgb_to_gray coefficients");
    +
    +         /* Use the defaults, from the cHRM chunk if set, else the historical
    +          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
    +          * 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_red_coeff   = 6968;
    +            png_ptr->rgb_to_gray_green_coeff = 23434;
    +            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
    +         }
    +      }
    +   }
    +}
    +
    +#ifdef PNG_FLOATING_POINT_SUPPORTED
    +/* Convert a RGB image to a grayscale of the same width.  This allows us,
    + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
    + */
    +
    +void PNGAPI
    +png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
    +    double green)
    +{
    +   png_set_rgb_to_gray_fixed(png_ptr, error_action,
    +       png_fixed(png_ptr, red, "rgb to gray red coefficient"),
    +      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
    +}
    +#endif /* FLOATING POINT */
    +
    +#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_structrp png_ptr, png_user_transform_ptr
    +    read_user_transform_fn)
    +{
    +   png_debug(1, "in png_set_read_user_transform_fn");
    +
    +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
    +   png_ptr->transformations |= PNG_USER_TRANSFORM;
    +   png_ptr->read_user_transform_fn = read_user_transform_fn;
    +#endif
    +}
    +#endif
    +
    +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +/* In the case of gamma transformations only do transformations on images where
    + * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
    + * slows things down slightly, and also needlessly introduces small errors.
    + */
    +static int /* PRIVATE */
    +png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
    +{
    +   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
    +    * correction as a difference of the overall transform from 1.0
    +    *
    +    * We want to compare the threshold with s*f - 1, if we get
    +    * overflow here it is because of wacky gamma values so we
    +    * turn on processing anyway.
    +    */
    +   png_fixed_point gtest;
    +   return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) ||
    +       png_gamma_significant(gtest);
    +}
    +#endif
    +
    +/* Initialize everything needed for the read.  This includes modifying
    + * the palette.
    + */
    +
    +/* 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_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
    +    * take care to only make changes that are invariant with respect to the
    +    * palette expansion, or only do them if there is no expansion.
    +    *
    +    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
    +    * to 0.)
    +    */
    +   int input_has_alpha = 0;
    +   int input_has_transparency = 0;
    +
    +   if (png_ptr->num_trans > 0)
    +   {
    +      int i;
    +
    +      /* Ignore if all the entries are opaque (unlikely!) */
    +      for (i=0; inum_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 == 0)
    +   {
    +      /* Any alpha means background and associative alpha processing is
    +       * 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 == 0)
    +         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
    +   }
    +
    +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
    +   /* png_set_background handling - deals with the complexity of whether the
    +    * background color is in the file format or the screen format in the case
    +    * where an 'expand' will happen.
    +    */
    +
    +   /* 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) != 0 &&
    +       (png_ptr->transformations & PNG_EXPAND) != 0)
    +   {
    +      {
    +         png_ptr->background.red   =
    +             png_ptr->palette[png_ptr->background.index].red;
    +         png_ptr->background.green =
    +             png_ptr->palette[png_ptr->background.index].green;
    +         png_ptr->background.blue  =
    +             png_ptr->palette[png_ptr->background.index].blue;
    +
    +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
    +         if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
    +         {
    +            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
    +                */
    +               int i, istop = png_ptr->num_trans;
    +
    +               for (i = 0; i < istop; i++)
    +                  png_ptr->trans_alpha[i] =
    +                      (png_byte)(255 - png_ptr->trans_alpha[i]);
    +            }
    +         }
    +#endif /* READ_INVERT_ALPHA */
    +      }
    +   } /* background expand and (therefore) no alpha association. */
    +#endif /* READ_EXPAND && READ_BACKGROUND */
    +}
    +
    +static void /* PRIVATE */
    +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
    +    * background and alpha mode stuff if there isn't.
    +    */
    +   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
    +   int input_has_transparency = png_ptr->num_trans > 0;
    +
    +   /* If no alpha we can optimize. */
    +   if (input_has_alpha == 0)
    +   {
    +      /* Any alpha means background and associative alpha processing is
    +       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
    +       * and ENCODE_ALPHA are irrelevant.
    +       */
    +#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
    +         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +#     endif
    +
    +      if (input_has_transparency == 0)
    +         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
    +   }
    +
    +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
    +   /* png_set_background handling - deals with the complexity of whether the
    +    * background color is in the file format or the screen format in the case
    +    * where an 'expand' will happen.
    +    */
    +
    +   /* 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) != 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:
    +               gray *= 0xff;
    +               trans_gray *= 0xff;
    +               break;
    +
    +            case 2:
    +               gray *= 0x55;
    +               trans_gray *= 0x55;
    +               break;
    +
    +            case 4:
    +               gray *= 0x11;
    +               trans_gray *= 0x11;
    +               break;
    +
    +            default:
    +
    +            case 8:
    +               /* FALLTHROUGH */ /*  (Already 8 bits) */
    +
    +            case 16:
    +               /* 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 /* READ_EXPAND && READ_BACKGROUND */
    +}
    +
    +void /* PRIVATE */
    +png_init_read_transformations(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_init_read_transformations");
    +
    +   /* This internal function is called from png_read_start_row in pngrutil.c
    +    * and it is called before the 'rowbytes' calculation is done, so the code
    +    * in here can change or update the transformations flags.
    +    *
    +    * First do updates that do not depend on the details of the PNG image data
    +    * being processed.
    +    */
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
    +    * png_set_alpha_mode and this is another source for a default file gamma so
    +    * the test needs to be performed later - here.  In addition prior to 1.5.4
    +    * the tests were repeated for the PALETTE color type here - this is no
    +    * longer necessary (and doesn't seem to have been necessary before.)
    +    */
    +   {
    +      /* The following temporary indicates if overall gamma correction is
    +       * required.
    +       */
    +      int gamma_correction = 0;
    +
    +      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->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->colorspace.gamma);
    +      }
    +
    +      else if (png_ptr->screen_gamma != 0)
    +         /* The converse - assume the file matches the screen, note that this
    +          * perhaps undesirable default can (from 1.5.4) be changed by calling
    +          * png_set_alpha_mode (even if the alpha handling mode isn't required
    +          * or isn't changed from the default.)
    +          */
    +         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
    +          * are both assumed to be linear and there is no way to introduce a
    +          * third gamma value other than png_set_background with 'UNIQUE', and,
    +          * prior to 1.5.4
    +          */
    +         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
    +       * composition may independently cause gamma correction because it needs
    +       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
    +       * hasn't been specified.)  In any case this flag may get turned off in
    +       * the code immediately below if the transform can be handled outside the
    +       * row loop.
    +       */
    +      if (gamma_correction != 0)
    +         png_ptr->transformations |= PNG_GAMMA;
    +
    +      else
    +         png_ptr->transformations &= ~PNG_GAMMA;
    +   }
    +#endif
    +
    +   /* Certain transformations have the effect of preventing other
    +    * transformations that happen afterward in png_do_read_transformations;
    +    * resolve the interdependencies here.  From the code of
    +    * png_do_read_transformations the order is:
    +    *
    +    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
    +    *  2) PNG_STRIP_ALPHA (if no compose)
    +    *  3) PNG_RGB_TO_GRAY
    +    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
    +    *  5) PNG_COMPOSE
    +    *  6) PNG_GAMMA
    +    *  7) PNG_STRIP_ALPHA (if compose)
    +    *  8) PNG_ENCODE_ALPHA
    +    *  9) PNG_SCALE_16_TO_8
    +    * 10) PNG_16_TO_8
    +    * 11) PNG_QUANTIZE (converts to palette)
    +    * 12) PNG_EXPAND_16
    +    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
    +    * 14) PNG_INVERT_MONO
    +    * 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) != 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
    +       * the alpha handling.  It has the side effect negating the effect of
    +       * PNG_EXPAND_tRNS too:
    +       */
    +      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
    +         PNG_EXPAND_tRNS);
    +      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +
    +      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
    +       * so transparency information would remain just so long as it wasn't
    +       * expanded.  This produces unexpected API changes if the set of things
    +       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
    +       * documentation - which says ask for what you want, accept what you
    +       * get.)  This makes the behavior consistent from 1.5.4:
    +       */
    +      png_ptr->num_trans = 0;
    +   }
    +#endif /* STRIP_ALPHA supported, no COMPOSE */
    +
    +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
    +   /* 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) == 0)
    +   {
    +      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    +      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    +   }
    +#endif
    +
    +#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.
    +    *
    +    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
    +    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
    +    * background color might actually be gray yet not be flagged as such.
    +    * This is not a problem for the current code, which uses
    +    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
    +    * png_do_gray_to_rgb() transformation.
    +    *
    +    * TODO: this code needs to be revised to avoid the complexity and
    +    * interdependencies.  The color type of the background should be recorded in
    +    * 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) != 0)
    +   {
    +      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
    +       * the file was grayscale the background value is gray.
    +       */
    +      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
    +         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
    +   }
    +
    +   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) != 0)
    +      {
    +         if (png_ptr->background.red == png_ptr->background.green &&
    +             png_ptr->background.red == png_ptr->background.blue)
    +         {
    +            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
    +            png_ptr->background.gray = png_ptr->background.red;
    +         }
    +      }
    +   }
    +#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)
    +    * can be optimized inside the palette.  This is particularly true of the
    +    * composite (background and alpha) stuff, which can be pretty much all done
    +    * in the palette even if the result is expanded to RGB or gray afterward.
    +    *
    +    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
    +    * earlier and the palette stuff is actually handled on the first row.  This
    +    * leads to the reported bug that the palette returned by png_get_PLTE is not
    +    * updated.
    +    */
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      png_init_palette_transformations(png_ptr);
    +
    +   else
    +      png_init_rgb_transformations(png_ptr);
    +
    +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
    +   defined(PNG_READ_EXPAND_16_SUPPORTED)
    +   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
    +       * application will supply a 16-bit value so reduce it here.
    +       *
    +       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
    +       * present, so that case is ok (until do_expand_16 is moved.)
    +       *
    +       * 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_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 /* 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
    +    * allows pre-multiplication of the alpha channel to be implemented as
    +    * compositing on black.  This is probably sub-optimal and has been done in
    +    * 1.5.4 betas simply to enable external critique and testing (i.e. to
    +    * implement the new API quickly, without lots of internal changes.)
    +    */
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +#  ifdef PNG_READ_BACKGROUND_SUPPORTED
    +      /* Includes ALPHA_MODE */
    +      png_ptr->background_1 = png_ptr->background;
    +#  endif
    +
    +   /* This needs to change - in the palette image case a whole set of tables are
    +    * built when it would be quicker to just calculate the correct value for
    +    * each palette entry directly.  Also, the test is too tricky - why check
    +    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
    +    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
    +    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
    +    * the gamma tables will not be built even if composition is required on a
    +    * gamma encoded value.
    +    *
    +    * In 1.5.4 this is addressed below by an additional check on the individual
    +    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
    +    * tables.
    +    */
    +   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) != 0)
    +#  endif
    +        )) || ((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) != 0)
    +      {
    +         /* 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.
    +             */
    +            png_color back, back_1;
    +            png_colorp palette = png_ptr->palette;
    +            int num_palette = png_ptr->num_palette;
    +            int i;
    +            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
    +            {
    +
    +               back.red = png_ptr->gamma_table[png_ptr->background.red];
    +               back.green = png_ptr->gamma_table[png_ptr->background.green];
    +               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
    +
    +               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
    +               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
    +               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
    +            }
    +            else
    +            {
    +               png_fixed_point g, gs;
    +
    +               switch (png_ptr->background_gamma_type)
    +               {
    +                  case PNG_BACKGROUND_GAMMA_SCREEN:
    +                     g = (png_ptr->screen_gamma);
    +                     gs = PNG_FP_1;
    +                     break;
    +
    +                  case PNG_BACKGROUND_GAMMA_FILE:
    +                     g = png_reciprocal(png_ptr->colorspace.gamma);
    +                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
    +                         png_ptr->screen_gamma);
    +                     break;
    +
    +                  case PNG_BACKGROUND_GAMMA_UNIQUE:
    +                     g = png_reciprocal(png_ptr->background_gamma);
    +                     gs = png_reciprocal2(png_ptr->background_gamma,
    +                         png_ptr->screen_gamma);
    +                     break;
    +                  default:
    +                     g = PNG_FP_1;    /* back_1 */
    +                     gs = PNG_FP_1;   /* back */
    +                     break;
    +               }
    +
    +               if (png_gamma_significant(gs) != 0)
    +               {
    +                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
    +                      gs);
    +                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
    +                      gs);
    +                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
    +                      gs);
    +               }
    +
    +               else
    +               {
    +                  back.red   = (png_byte)png_ptr->background.red;
    +                  back.green = (png_byte)png_ptr->background.green;
    +                  back.blue  = (png_byte)png_ptr->background.blue;
    +               }
    +
    +               if (png_gamma_significant(g) != 0)
    +               {
    +                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
    +                      g);
    +                  back_1.green = png_gamma_8bit_correct(
    +                      png_ptr->background.green, g);
    +                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
    +                      g);
    +               }
    +
    +               else
    +               {
    +                  back_1.red   = (png_byte)png_ptr->background.red;
    +                  back_1.green = (png_byte)png_ptr->background.green;
    +                  back_1.blue  = (png_byte)png_ptr->background.blue;
    +               }
    +            }
    +
    +            for (i = 0; i < num_palette; i++)
    +            {
    +               if (i < (int)png_ptr->num_trans &&
    +                   png_ptr->trans_alpha[i] != 0xff)
    +               {
    +                  if (png_ptr->trans_alpha[i] == 0)
    +                  {
    +                     palette[i] = back;
    +                  }
    +                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
    +                  {
    +                     png_byte v, w;
    +
    +                     v = png_ptr->gamma_to_1[palette[i].red];
    +                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
    +                     palette[i].red = png_ptr->gamma_from_1[w];
    +
    +                     v = png_ptr->gamma_to_1[palette[i].green];
    +                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
    +                     palette[i].green = png_ptr->gamma_from_1[w];
    +
    +                     v = png_ptr->gamma_to_1[palette[i].blue];
    +                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
    +                     palette[i].blue = png_ptr->gamma_from_1[w];
    +                  }
    +               }
    +               else
    +               {
    +                  palette[i].red = png_ptr->gamma_table[palette[i].red];
    +                  palette[i].green = png_ptr->gamma_table[palette[i].green];
    +                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
    +               }
    +            }
    +
    +            /* Prevent the transformations being done again.
    +             *
    +             * NOTE: this is highly dubious; it removes the transformations in
    +             * place.  This seems inconsistent with the general treatment of the
    +             * transformations elsewhere.
    +             */
    +            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
    +         } /* color_type == PNG_COLOR_TYPE_PALETTE */
    +
    +         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
    +         else /* color_type != PNG_COLOR_TYPE_PALETTE */
    +         {
    +            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)
    +            {
    +               case PNG_BACKGROUND_GAMMA_SCREEN:
    +                  g = png_ptr->screen_gamma;
    +                  /* gs = PNG_FP_1; */
    +                  break;
    +
    +               case PNG_BACKGROUND_GAMMA_FILE:
    +                  g = png_reciprocal(png_ptr->colorspace.gamma);
    +                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
    +                      png_ptr->screen_gamma);
    +                  break;
    +
    +               case PNG_BACKGROUND_GAMMA_UNIQUE:
    +                  g = png_reciprocal(png_ptr->background_gamma);
    +                  gs = png_reciprocal2(png_ptr->background_gamma,
    +                      png_ptr->screen_gamma);
    +                  break;
    +
    +               default:
    +                  png_error(png_ptr, "invalid background gamma type");
    +            }
    +
    +            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 */
    +               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
    +            {
    +               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
    +               png_ptr->background_1.red = png_ptr->background_1.green
    +                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
    +
    +               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 /* 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.
    +          */
    +         for (i = 0; i < num_palette; i++)
    +         {
    +            palette[i].red = png_ptr->gamma_table[palette[i].red];
    +            palette[i].green = png_ptr->gamma_table[palette[i].green];
    +            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
    +         }
    +
    +         /* Done the gamma correction. */
    +         png_ptr->transformations &= ~PNG_GAMMA;
    +      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
    +   }
    +#ifdef PNG_READ_BACKGROUND_SUPPORTED
    +   else
    +#endif
    +#endif /* READ_GAMMA */
    +
    +#ifdef PNG_READ_BACKGROUND_SUPPORTED
    +   /* No GAMMA transformation (see the hanging else 4 lines above) */
    +   if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
    +       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
    +   {
    +      int i;
    +      int istop = (int)png_ptr->num_trans;
    +      png_color back;
    +      png_colorp palette = png_ptr->palette;
    +
    +      back.red   = (png_byte)png_ptr->background.red;
    +      back.green = (png_byte)png_ptr->background.green;
    +      back.blue  = (png_byte)png_ptr->background.blue;
    +
    +      for (i = 0; i < istop; i++)
    +      {
    +         if (png_ptr->trans_alpha[i] == 0)
    +         {
    +            palette[i] = back;
    +         }
    +
    +         else if (png_ptr->trans_alpha[i] != 0xff)
    +         {
    +            /* The png_composite() macro is defined in png.h */
    +            png_composite(palette[i].red, palette[i].red,
    +                png_ptr->trans_alpha[i], back.red);
    +
    +            png_composite(palette[i].green, palette[i].green,
    +                png_ptr->trans_alpha[i], back.green);
    +
    +            png_composite(palette[i].blue, palette[i].blue,
    +                png_ptr->trans_alpha[i], back.blue);
    +         }
    +      }
    +
    +      png_ptr->transformations &= ~PNG_COMPOSE;
    +   }
    +#endif /* READ_BACKGROUND */
    +
    +#ifdef PNG_READ_SHIFT_SUPPORTED
    +   if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
    +       (png_ptr->transformations & PNG_EXPAND) == 0 &&
    +       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
    +   {
    +      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 meaningful 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; ipalette[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; ipalette[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; ipalette[i].blue;
    +
    +            component >>= shift;
    +            png_ptr->palette[i].blue = (png_byte)component;
    +         }
    +   }
    +#endif /* READ_SHIFT */
    +}
    +
    +/* Modify the info structure to reflect the transformations.  The
    + * info should be updated so a PNG file could be written with it,
    + * assuming the transformations result in valid PNG data.
    + */
    +void /* PRIVATE */
    +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) != 0)
    +   {
    +      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      {
    +         /* This check must match what actually happens in
    +          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
    +          * it is all opaque we must do the same (at present it does not.)
    +          */
    +         if (png_ptr->num_trans > 0)
    +            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    +
    +         else
    +            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
    +
    +         info_ptr->bit_depth = 8;
    +         info_ptr->num_trans = 0;
    +
    +         if (png_ptr->palette == NULL)
    +            png_error (png_ptr, "Palette is NULL in indexed image");
    +      }
    +      else
    +      {
    +         if (png_ptr->num_trans != 0)
    +         {
    +            if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
    +               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
    +         }
    +         if (info_ptr->bit_depth < 8)
    +            info_ptr->bit_depth = 8;
    +
    +         info_ptr->num_trans = 0;
    +      }
    +   }
    +#endif
    +
    +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
    +   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
    +   /* The following is almost certainly wrong unless the background value is in
    +    * the screen space!
    +    */
    +   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
    +      info_ptr->background = png_ptr->background;
    +#endif
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
    +    * 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->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) != 0)
    +            info_ptr->bit_depth = 8;
    +#     endif
    +
    +#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
    +         if ((png_ptr->transformations & PNG_16_TO_8) != 0)
    +            info_ptr->bit_depth = 8;
    +#     endif
    +
    +#  else
    +      /* No 16-bit support: force chopping 16-bit input down to 8, in this case
    +       * the app program can chose if both APIs are available by setting the
    +       * correct scaling to use.
    +       */
    +#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
    +         /* For compatibility with previous versions use the strip method by
    +          * default.  This code works because if PNG_SCALE_16_TO_8 is already
    +          * set the code below will do that in preference to the chop.
    +          */
    +         png_ptr->transformations |= PNG_16_TO_8;
    +         info_ptr->bit_depth = 8;
    +#     else
    +
    +#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
    +            png_ptr->transformations |= PNG_SCALE_16_TO_8;
    +            info_ptr->bit_depth = 8;
    +#        else
    +
    +            CONFIGURATION ERROR: you must enable at least one 16 to 8 method
    +#        endif
    +#    endif
    +#endif /* !READ_16BIT */
    +   }
    +
    +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    +   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) != 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) != 0)
    +   {
    +      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
    +          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
    +          png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
    +      {
    +         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_READ_EXPAND_16_SUPPORTED
    +   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) != 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) != 0)
    +      info_ptr->channels = 3;
    +
    +   else
    +      info_ptr->channels = 1;
    +
    +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
    +   if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
    +   {
    +      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) != 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) != 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) != 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) != 0)
    +   {
    +      if (png_ptr->user_transform_depth != 0)
    +         info_ptr->bit_depth = png_ptr->user_transform_depth;
    +
    +      if (png_ptr->user_transform_channels != 0)
    +         info_ptr->channels = png_ptr->user_transform_channels;
    +   }
    +#endif
    +
    +   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
    +       info_ptr->bit_depth);
    +
    +   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
    +
    +   /* Adding in 1.5.4: cache the above value in png_struct so that we can later
    +    * check in png_rowbytes that the user buffer won't get overwritten.  Note
    +    * that the field is not always set - if png_read_update_info isn't called
    +    * the application has to either not do any transforms or get the calculation
    +    * right itself.
    +    */
    +   png_ptr->info_rowbytes = info_ptr->rowbytes;
    +
    +#ifndef PNG_READ_EXPAND_SUPPORTED
    +   if (png_ptr != NULL)
    +      return;
    +#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
    + * a bit depth of 1, you would end up with bytes that only contained
    + * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
    + * png_do_shift() after this.
    + */
    +static void
    +png_do_unpack(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_unpack");
    +
    +   if (row_info->bit_depth < 8)
    +   {
    +      png_uint_32 i;
    +      png_uint_32 row_width=row_info->width;
    +
    +      switch (row_info->bit_depth)
    +      {
    +         case 1:
    +         {
    +            png_bytep sp = row + (size_t)((row_width - 1) >> 3);
    +            png_bytep dp = row + (size_t)row_width - 1;
    +            png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *dp = (png_byte)((*sp >> shift) & 0x01);
    +
    +               if (shift == 7)
    +               {
    +                  shift = 0;
    +                  sp--;
    +               }
    +
    +               else
    +                  shift++;
    +
    +               dp--;
    +            }
    +            break;
    +         }
    +
    +         case 2:
    +         {
    +
    +            png_bytep sp = row + (size_t)((row_width - 1) >> 2);
    +            png_bytep dp = row + (size_t)row_width - 1;
    +            png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *dp = (png_byte)((*sp >> shift) & 0x03);
    +
    +               if (shift == 6)
    +               {
    +                  shift = 0;
    +                  sp--;
    +               }
    +
    +               else
    +                  shift += 2;
    +
    +               dp--;
    +            }
    +            break;
    +         }
    +
    +         case 4:
    +         {
    +            png_bytep sp = row + (size_t)((row_width - 1) >> 1);
    +            png_bytep dp = row + (size_t)row_width - 1;
    +            png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *dp = (png_byte)((*sp >> shift) & 0x0f);
    +
    +               if (shift == 4)
    +               {
    +                  shift = 0;
    +                  sp--;
    +               }
    +
    +               else
    +                  shift = 4;
    +
    +               dp--;
    +            }
    +            break;
    +         }
    +
    +         default:
    +            break;
    +      }
    +      row_info->bit_depth = 8;
    +      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
    +      row_info->rowbytes = row_width * row_info->channels;
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_SHIFT_SUPPORTED
    +/* Reverse the effects of png_do_shift.  This routine merely shifts the
    + * pixels back to their significant bits values.  Thus, if you have
    + * a row of bit depth 8, but only 5 are significant, this will shift
    + * the values back to 0 through 31.
    + */
    +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");
    +
    +   /* 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 bit_depth = row_info->bit_depth;
    +
    +      if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
    +      {
    +         shift[channels++] = bit_depth - sig_bits->red;
    +         shift[channels++] = bit_depth - sig_bits->green;
    +         shift[channels++] = bit_depth - sig_bits->blue;
    +      }
    +
    +      else
    +      {
    +         shift[channels++] = bit_depth - sig_bits->gray;
    +      }
    +
    +      if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
    +      {
    +         shift[channels++] = bit_depth - sig_bits->alpha;
    +      }
    +
    +      {
    +         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;
    +      }
    +
    +      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 = row;
    +            png_bytep bp_end = bp + row_info->rowbytes;
    +
    +            while (bp < bp_end)
    +            {
    +               int b = (*bp >> 1) & 0x55;
    +               *bp++ = (png_byte)b;
    +            }
    +            break;
    +         }
    +
    +         case 4:
    +         /* Must be 4bpp gray */
    +         /* assert(channels == 1) */
    +         {
    +            png_bytep bp = row;
    +            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)
    +            {
    +               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_bytep bp_end = bp + row_info->rowbytes;
    +            int channel = 0;
    +
    +            while (bp < bp_end)
    +            {
    +               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_bytep bp_end = bp + row_info->rowbytes;
    +            int channel = 0;
    +
    +            while (bp < bp_end)
    +            {
    +               int value = (bp[0] << 8) + bp[1];
    +
    +               value >>= shift[channel];
    +               if (++channel >= channels)
    +                  channel = 0;
    +               *bp++ = (png_byte)(value >> 8);
    +               *bp++ = (png_byte)value;
    +            }
    +            break;
    +         }
    +#endif
    +      }
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
    +/* Scale rows of bit depth 16 down to 8 accurately */
    +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");
    +
    +   if (row_info->bit_depth == 16)
    +   {
    +      png_bytep sp = row; /* source */
    +      png_bytep dp = row; /* destination */
    +      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
    +
    +      while (sp < ep)
    +      {
    +         /* The input is an array of 16-bit components, these must be scaled to
    +          * 8 bits each.  For a 16-bit value V the required value (from the PNG
    +          * specification) is:
    +          *
    +          *    (V * 255) / 65535
    +          *
    +          * This reduces to round(V / 257), or floor((V + 128.5)/257)
    +          *
    +          * Represent V as the two byte value vhi.vlo.  Make a guess that the
    +          * result is the top byte of V, vhi, then the correction to this value
    +          * is:
    +          *
    +          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
    +          *          = floor(((vlo-vhi) + 128.5) / 257)
    +          *
    +          * This can be approximated using integer arithmetic (and a signed
    +          * shift):
    +          *
    +          *    error = (vlo-vhi+128) >> 8;
    +          *
    +          * The approximate differs from the exact answer only when (vlo-vhi) is
    +          * 128; it then gives a correction of +1 when the exact correction is
    +          * 0.  This gives 128 errors.  The exact answer (correct for all 16-bit
    +          * input values) is:
    +          *
    +          *    error = (vlo-vhi+128)*65535 >> 24;
    +          *
    +          * An alternative arithmetic calculation which also gives no errors is:
    +          *
    +          *    (V * 255 + 32895) >> 16
    +          */
    +
    +         png_int_32 tmp = *sp++; /* must be signed! */
    +         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
    +         *dp++ = (png_byte)tmp;
    +      }
    +
    +      row_info->bit_depth = 8;
    +      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
    +      row_info->rowbytes = row_info->width * row_info->channels;
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
    +static void
    +/* Simply discard the low byte.  This was the default behavior prior
    + * to libpng-1.5.4.
    + */
    +png_do_chop(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_chop");
    +
    +   if (row_info->bit_depth == 16)
    +   {
    +      png_bytep sp = row; /* source */
    +      png_bytep dp = row; /* destination */
    +      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
    +
    +      while (sp < ep)
    +      {
    +         *dp++ = *sp;
    +         sp += 2; /* skip low byte */
    +      }
    +
    +      row_info->bit_depth = 8;
    +      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
    +      row_info->rowbytes = row_info->width * row_info->channels;
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
    +static void
    +png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
    +{
    +   png_uint_32 row_width = row_info->width;
    +
    +   png_debug(1, "in png_do_read_swap_alpha");
    +
    +   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +   {
    +      /* This converts from RGBA to ARGB */
    +      if (row_info->bit_depth == 8)
    +      {
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_byte save;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            save = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = save;
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      /* This converts from RRGGBBAA to AARRGGBB */
    +      else
    +      {
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_byte save[2];
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            save[0] = *(--sp);
    +            save[1] = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = save[0];
    +            *(--dp) = save[1];
    +         }
    +      }
    +#endif
    +   }
    +
    +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    +   {
    +      /* This converts from GA to AG */
    +      if (row_info->bit_depth == 8)
    +      {
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_byte save;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            save = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = save;
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      /* This converts from GGAA to AAGG */
    +      else
    +      {
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_byte save[2];
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            save[0] = *(--sp);
    +            save[1] = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = save[0];
    +            *(--dp) = save[1];
    +         }
    +      }
    +#endif
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
    +static void
    +png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
    +{
    +   png_uint_32 row_width;
    +   png_debug(1, "in png_do_read_invert_alpha");
    +
    +   row_width = row_info->width;
    +   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         /* This inverts the alpha channel in RGBA */
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +
    +/*          This does nothing:
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            We can replace it with:
    +*/
    +            sp-=3;
    +            dp=sp;
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      /* This inverts the alpha channel in RRGGBBAA */
    +      else
    +      {
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +
    +/*          This does nothing:
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +            We can replace it with:
    +*/
    +            sp-=6;
    +            dp=sp;
    +         }
    +      }
    +#endif
    +   }
    +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         /* This inverts the alpha channel in GA */
    +         png_bytep sp = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +            *(--dp) = *(--sp);
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      else
    +      {
    +         /* This inverts the alpha channel in GGAA */
    +         png_bytep sp  = row + row_info->rowbytes;
    +         png_bytep dp = sp;
    +         png_uint_32 i;
    +
    +         for (i = 0; i < row_width; i++)
    +         {
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +            *(--dp) = (png_byte)(255 - *(--sp));
    +/*
    +            *(--dp) = *(--sp);
    +            *(--dp) = *(--sp);
    +*/
    +            sp-=2;
    +            dp=sp;
    +         }
    +      }
    +#endif
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_FILLER_SUPPORTED
    +/* Add filler channel if we have RGB color */
    +static void
    +png_do_read_filler(png_row_infop row_info, png_bytep row,
    +    png_uint_32 filler, png_uint_32 flags)
    +{
    +   png_uint_32 i;
    +   png_uint_32 row_width = row_info->width;
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +   png_byte hi_filler = (png_byte)(filler>>8);
    +#endif
    +   png_byte lo_filler = (png_byte)filler;
    +
    +   png_debug(1, "in png_do_read_filler");
    +
    +   if (
    +       row_info->color_type == PNG_COLOR_TYPE_GRAY)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
    +         {
    +            /* This changes the data from G to GX */
    +            png_bytep sp = row + (size_t)row_width;
    +            png_bytep dp =  sp + (size_t)row_width;
    +            for (i = 1; i < row_width; i++)
    +            {
    +               *(--dp) = lo_filler;
    +               *(--dp) = *(--sp);
    +            }
    +            *(--dp) = lo_filler;
    +            row_info->channels = 2;
    +            row_info->pixel_depth = 16;
    +            row_info->rowbytes = row_width * 2;
    +         }
    +
    +         else
    +         {
    +            /* This changes the data from G to XG */
    +            png_bytep sp = row + (size_t)row_width;
    +            png_bytep dp = sp  + (size_t)row_width;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(--dp) = *(--sp);
    +               *(--dp) = lo_filler;
    +            }
    +            row_info->channels = 2;
    +            row_info->pixel_depth = 16;
    +            row_info->rowbytes = row_width * 2;
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      else if (row_info->bit_depth == 16)
    +      {
    +         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
    +         {
    +            /* This changes the data from GG to GGXX */
    +            png_bytep sp = row + (size_t)row_width * 2;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 1; i < row_width; i++)
    +            {
    +               *(--dp) = lo_filler;
    +               *(--dp) = hi_filler;
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +            }
    +            *(--dp) = lo_filler;
    +            *(--dp) = hi_filler;
    +            row_info->channels = 2;
    +            row_info->pixel_depth = 32;
    +            row_info->rowbytes = row_width * 4;
    +         }
    +
    +         else
    +         {
    +            /* This changes the data from GG to XXGG */
    +            png_bytep sp = row + (size_t)row_width * 2;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = lo_filler;
    +               *(--dp) = hi_filler;
    +            }
    +            row_info->channels = 2;
    +            row_info->pixel_depth = 32;
    +            row_info->rowbytes = row_width * 4;
    +         }
    +      }
    +#endif
    +   } /* COLOR_TYPE == GRAY */
    +   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
    +         {
    +            /* This changes the data from RGB to RGBX */
    +            png_bytep sp = row + (size_t)row_width * 3;
    +            png_bytep dp = sp  + (size_t)row_width;
    +            for (i = 1; i < row_width; i++)
    +            {
    +               *(--dp) = lo_filler;
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +            }
    +            *(--dp) = lo_filler;
    +            row_info->channels = 4;
    +            row_info->pixel_depth = 32;
    +            row_info->rowbytes = row_width * 4;
    +         }
    +
    +         else
    +         {
    +            /* This changes the data from RGB to XRGB */
    +            png_bytep sp = row + (size_t)row_width * 3;
    +            png_bytep dp = sp + (size_t)row_width;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = lo_filler;
    +            }
    +            row_info->channels = 4;
    +            row_info->pixel_depth = 32;
    +            row_info->rowbytes = row_width * 4;
    +         }
    +      }
    +
    +#ifdef PNG_READ_16BIT_SUPPORTED
    +      else if (row_info->bit_depth == 16)
    +      {
    +         if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
    +         {
    +            /* This changes the data from RRGGBB to RRGGBBXX */
    +            png_bytep sp = row + (size_t)row_width * 6;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 1; i < row_width; i++)
    +            {
    +               *(--dp) = lo_filler;
    +               *(--dp) = hi_filler;
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +            }
    +            *(--dp) = lo_filler;
    +            *(--dp) = hi_filler;
    +            row_info->channels = 4;
    +            row_info->pixel_depth = 64;
    +            row_info->rowbytes = row_width * 8;
    +         }
    +
    +         else
    +         {
    +            /* This changes the data from RRGGBB to XXRRGGBB */
    +            png_bytep sp = row + (size_t)row_width * 6;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = *(--sp);
    +               *(--dp) = lo_filler;
    +               *(--dp) = hi_filler;
    +            }
    +
    +            row_info->channels = 4;
    +            row_info->pixel_depth = 64;
    +            row_info->rowbytes = row_width * 8;
    +         }
    +      }
    +#endif
    +   } /* COLOR_TYPE == RGB */
    +}
    +#endif
    +
    +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    +/* Expand grayscale files to RGB, with or without alpha */
    +static void
    +png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
    +{
    +   png_uint_32 i;
    +   png_uint_32 row_width = row_info->width;
    +
    +   png_debug(1, "in png_do_gray_to_rgb");
    +
    +   if (row_info->bit_depth >= 8 &&
    +       (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
    +   {
    +      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +            /* This changes G to RGB */
    +            png_bytep sp = row + (size_t)row_width - 1;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(dp--) = *sp;
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp--);
    +            }
    +         }
    +
    +         else
    +         {
    +            /* This changes GG to RRGGBB */
    +            png_bytep sp = row + (size_t)row_width * 2 - 1;
    +            png_bytep dp = sp  + (size_t)row_width * 4;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp - 1);
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp - 1);
    +               *(dp--) = *(sp--);
    +               *(dp--) = *(sp--);
    +            }
    +         }
    +      }
    +
    +      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +            /* This changes GA to RGBA */
    +            png_bytep sp = row + (size_t)row_width * 2 - 1;
    +            png_bytep dp = sp  + (size_t)row_width * 2;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(dp--) = *(sp--);
    +               *(dp--) = *sp;
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp--);
    +            }
    +         }
    +
    +         else
    +         {
    +            /* This changes GGAA to RRGGBBAA */
    +            png_bytep sp = row + (size_t)row_width * 4 - 1;
    +            png_bytep dp = sp  + (size_t)row_width * 4;
    +            for (i = 0; i < row_width; i++)
    +            {
    +               *(dp--) = *(sp--);
    +               *(dp--) = *(sp--);
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp - 1);
    +               *(dp--) = *sp;
    +               *(dp--) = *(sp - 1);
    +               *(dp--) = *(sp--);
    +               *(dp--) = *(sp--);
    +            }
    +         }
    +      }
    +      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);
    +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    +/* Reduce RGB files to grayscale, with or without alpha
    + * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
    + *   (THIS LINK IS DEAD June 2008 but
    + * versions dated 1998 through November 2002 have been archived at
    + * https://web.archive.org/web/20000816232553/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
    + *
    + *  which can be expressed with integers as
    + *
    + *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
    + *
    + * Poynton's current link (as of January 2003 through July 2011):
    + * 
    + * has changed the numbers slightly:
    + *
    + *     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 coefficients 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.
    + */
    +static int
    +png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
    +{
    +   int rgb_error = 0;
    +
    +   png_debug(1, "in png_do_rgb_to_gray");
    +
    +   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 = 32768 - rc - gc;
    +      png_uint_32 row_width = row_info->width;
    +      int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
    +
    +      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)
    +         {
    +            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)
    +               {
    +                  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;
    +               png_byte hi,lo;
    +
    +               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
    +               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
    +               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
    +
    +               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
    +                     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 + 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
    +#endif
    +         {
    +            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, gray16;
    +               png_byte hi,lo;
    +
    +               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
    +               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
    +               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
    +
    +               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)
    +               {
    +                  *(dp++) = *(sp++);
    +                  *(dp++) = *(sp++);
    +               }
    +            }
    +         }
    +      }
    +
    +      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 *
    +          row_info->bit_depth);
    +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    +   }
    +   return rgb_error;
    +}
    +#endif
    +
    +#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.
    + */
    +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;
    +   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
    +   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
    +   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
    +   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 shift;
    +
    +   png_debug(1, "in png_do_compose");
    +
    +   switch (row_info->color_type)
    +   {
    +      case PNG_COLOR_TYPE_GRAY:
    +      {
    +         switch (row_info->bit_depth)
    +         {
    +            case 1:
    +            {
    +               sp = row;
    +               shift = 7;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  if ((png_uint_16)((*sp >> shift) & 0x01)
    +                     == png_ptr->trans_color.gray)
    +                  {
    +                     unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
    +                     tmp |=
    +                         (unsigned int)(png_ptr->background.gray << shift);
    +                     *sp = (png_byte)(tmp & 0xff);
    +                  }
    +
    +                  if (shift == 0)
    +                  {
    +                     shift = 7;
    +                     sp++;
    +                  }
    +
    +                  else
    +                     shift--;
    +               }
    +               break;
    +            }
    +
    +            case 2:
    +            {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +               if (gamma_table != NULL)
    +               {
    +                  sp = row;
    +                  shift = 6;
    +                  for (i = 0; i < row_width; i++)
    +                  {
    +                     if ((png_uint_16)((*sp >> shift) & 0x03)
    +                         == png_ptr->trans_color.gray)
    +                     {
    +                        unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
    +                        tmp |=
    +                           (unsigned int)png_ptr->background.gray << shift;
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     else
    +                     {
    +                        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 |= (unsigned int)(g << shift);
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     if (shift == 0)
    +                     {
    +                        shift = 6;
    +                        sp++;
    +                     }
    +
    +                     else
    +                        shift -= 2;
    +                  }
    +               }
    +
    +               else
    +#endif
    +               {
    +                  sp = row;
    +                  shift = 6;
    +                  for (i = 0; i < row_width; i++)
    +                  {
    +                     if ((png_uint_16)((*sp >> shift) & 0x03)
    +                         == png_ptr->trans_color.gray)
    +                     {
    +                        unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
    +                        tmp |=
    +                            (unsigned int)png_ptr->background.gray << shift;
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     if (shift == 0)
    +                     {
    +                        shift = 6;
    +                        sp++;
    +                     }
    +
    +                     else
    +                        shift -= 2;
    +                  }
    +               }
    +               break;
    +            }
    +
    +            case 4:
    +            {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +               if (gamma_table != NULL)
    +               {
    +                  sp = row;
    +                  shift = 4;
    +                  for (i = 0; i < row_width; i++)
    +                  {
    +                     if ((png_uint_16)((*sp >> shift) & 0x0f)
    +                         == png_ptr->trans_color.gray)
    +                     {
    +                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
    +                        tmp |=
    +                           (unsigned int)(png_ptr->background.gray << shift);
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     else
    +                     {
    +                        unsigned int p = (*sp >> shift) & 0x0f;
    +                        unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
    +                           0x0f;
    +                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
    +                        tmp |= (unsigned int)(g << shift);
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     if (shift == 0)
    +                     {
    +                        shift = 4;
    +                        sp++;
    +                     }
    +
    +                     else
    +                        shift -= 4;
    +                  }
    +               }
    +
    +               else
    +#endif
    +               {
    +                  sp = row;
    +                  shift = 4;
    +                  for (i = 0; i < row_width; i++)
    +                  {
    +                     if ((png_uint_16)((*sp >> shift) & 0x0f)
    +                         == png_ptr->trans_color.gray)
    +                     {
    +                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
    +                        tmp |=
    +                           (unsigned int)(png_ptr->background.gray << shift);
    +                        *sp = (png_byte)(tmp & 0xff);
    +                     }
    +
    +                     if (shift == 0)
    +                     {
    +                        shift = 4;
    +                        sp++;
    +                     }
    +
    +                     else
    +                        shift -= 4;
    +                  }
    +               }
    +               break;
    +            }
    +
    +            case 8:
    +            {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +               if (gamma_table != NULL)
    +               {
    +                  sp = row;
    +                  for (i = 0; i < row_width; i++, sp++)
    +                  {
    +                     if (*sp == png_ptr->trans_color.gray)
    +                        *sp = (png_byte)png_ptr->background.gray;
    +
    +                     else
    +                        *sp = gamma_table[*sp];
    +                  }
    +               }
    +               else
    +#endif
    +               {
    +                  sp = row;
    +                  for (i = 0; i < row_width; i++, sp++)
    +                  {
    +                     if (*sp == png_ptr->trans_color.gray)
    +                        *sp = (png_byte)png_ptr->background.gray;
    +                  }
    +               }
    +               break;
    +            }
    +
    +            case 16:
    +            {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +               if (gamma_16 != NULL)
    +               {
    +                  sp = row;
    +                  for (i = 0; i < row_width; i++, sp += 2)
    +                  {
    +                     png_uint_16 v;
    +
    +                     v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +
    +                     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);
    +                     }
    +
    +                     else
    +                     {
    +                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
    +                        *sp = (png_byte)((v >> 8) & 0xff);
    +                        *(sp + 1) = (png_byte)(v & 0xff);
    +                     }
    +                  }
    +               }
    +               else
    +#endif
    +               {
    +                  sp = row;
    +                  for (i = 0; i < row_width; i++, sp += 2)
    +                  {
    +                     png_uint_16 v;
    +
    +                     v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +
    +                     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);
    +                     }
    +                  }
    +               }
    +               break;
    +            }
    +
    +            default:
    +               break;
    +         }
    +         break;
    +      }
    +
    +      case PNG_COLOR_TYPE_RGB:
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_table != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 3)
    +               {
    +                  if (*sp == png_ptr->trans_color.red &&
    +                      *(sp + 1) == png_ptr->trans_color.green &&
    +                      *(sp + 2) == png_ptr->trans_color.blue)
    +                  {
    +                     *sp = (png_byte)png_ptr->background.red;
    +                     *(sp + 1) = (png_byte)png_ptr->background.green;
    +                     *(sp + 2) = (png_byte)png_ptr->background.blue;
    +                  }
    +
    +                  else
    +                  {
    +                     *sp = gamma_table[*sp];
    +                     *(sp + 1) = gamma_table[*(sp + 1)];
    +                     *(sp + 2) = gamma_table[*(sp + 2)];
    +                  }
    +               }
    +            }
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 3)
    +               {
    +                  if (*sp == png_ptr->trans_color.red &&
    +                      *(sp + 1) == png_ptr->trans_color.green &&
    +                      *(sp + 2) == png_ptr->trans_color.blue)
    +                  {
    +                     *sp = (png_byte)png_ptr->background.red;
    +                     *(sp + 1) = (png_byte)png_ptr->background.green;
    +                     *(sp + 2) = (png_byte)png_ptr->background.blue;
    +                  }
    +               }
    +            }
    +         }
    +         else /* if (row_info->bit_depth == 16) */
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_16 != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 6)
    +               {
    +                  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +
    +                  png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
    +                      + *(sp + 3));
    +
    +                  png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
    +                      + *(sp + 5));
    +
    +                  if (r == png_ptr->trans_color.red &&
    +                      g == png_ptr->trans_color.green &&
    +                      b == png_ptr->trans_color.blue)
    +                  {
    +                     /* 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 + 5) = (png_byte)(png_ptr->background.blue & 0xff);
    +                  }
    +
    +                  else
    +                  {
    +                     png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
    +                     *sp = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(v & 0xff);
    +
    +                     v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
    +                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 3) = (png_byte)(v & 0xff);
    +
    +                     v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
    +                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 5) = (png_byte)(v & 0xff);
    +                  }
    +               }
    +            }
    +
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 6)
    +               {
    +                  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +
    +                  png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
    +                      + *(sp + 3));
    +
    +                  png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
    +                      + *(sp + 5));
    +
    +                  if (r == png_ptr->trans_color.red &&
    +                      g == png_ptr->trans_color.green &&
    +                      b == png_ptr->trans_color.blue)
    +                  {
    +                     *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 + 5) = (png_byte)(png_ptr->background.blue & 0xff);
    +                  }
    +               }
    +            }
    +         }
    +         break;
    +      }
    +
    +      case PNG_COLOR_TYPE_GRAY_ALPHA:
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
    +                gamma_table != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 2)
    +               {
    +                  png_uint_16 a = *(sp + 1);
    +
    +                  if (a == 0xff)
    +                     *sp = gamma_table[*sp];
    +
    +                  else if (a == 0)
    +                  {
    +                     /* Background is already in screen gamma */
    +                     *sp = (png_byte)png_ptr->background.gray;
    +                  }
    +
    +                  else
    +                  {
    +                     png_byte v, w;
    +
    +                     v = gamma_to_1[*sp];
    +                     png_composite(w, v, a, png_ptr->background_1.gray);
    +                     if (optimize == 0)
    +                        w = gamma_from_1[w];
    +                     *sp = w;
    +                  }
    +               }
    +            }
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 2)
    +               {
    +                  png_byte a = *(sp + 1);
    +
    +                  if (a == 0)
    +                     *sp = (png_byte)png_ptr->background.gray;
    +
    +                  else if (a < 0xff)
    +                     png_composite(*sp, *sp, a, png_ptr->background.gray);
    +               }
    +            }
    +         }
    +         else /* if (png_ptr->bit_depth == 16) */
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
    +                gamma_16_to_1 != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 4)
    +               {
    +                  png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
    +                      + *(sp + 3));
    +
    +                  if (a == (png_uint_16)0xffff)
    +                  {
    +                     png_uint_16 v;
    +
    +                     v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
    +                     *sp = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(v & 0xff);
    +                  }
    +
    +                  else if (a == 0)
    +                  {
    +                     /* Background is already in screen gamma */
    +                     *sp = (png_byte)((png_ptr->background.gray >> 8)
    +                             & 0xff);
    +                     *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
    +                  }
    +
    +                  else
    +                  {
    +                     png_uint_16 g, v, w;
    +
    +                     g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
    +                     png_composite_16(v, g, a, png_ptr->background_1.gray);
    +                     if (optimize != 0)
    +                        w = v;
    +                     else
    +                        w = gamma_16_from_1[(v & 0xff) >>
    +                            gamma_shift][v >> 8];
    +                     *sp = (png_byte)((w >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(w & 0xff);
    +                  }
    +               }
    +            }
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 4)
    +               {
    +                  png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
    +                      + *(sp + 3));
    +
    +                  if (a == 0)
    +                  {
    +                     *sp = (png_byte)((png_ptr->background.gray >> 8)
    +                             & 0xff);
    +                     *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
    +                  }
    +
    +                  else if (a < 0xffff)
    +                  {
    +                     png_uint_16 g, v;
    +
    +                     g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +                     png_composite_16(v, g, a, png_ptr->background.gray);
    +                     *sp = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(v & 0xff);
    +                  }
    +               }
    +            }
    +         }
    +         break;
    +      }
    +
    +      case PNG_COLOR_TYPE_RGB_ALPHA:
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
    +                gamma_table != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 4)
    +               {
    +                  png_byte a = *(sp + 3);
    +
    +                  if (a == 0xff)
    +                  {
    +                     *sp = gamma_table[*sp];
    +                     *(sp + 1) = gamma_table[*(sp + 1)];
    +                     *(sp + 2) = gamma_table[*(sp + 2)];
    +                  }
    +
    +                  else if (a == 0)
    +                  {
    +                     /* Background is already in screen gamma */
    +                     *sp = (png_byte)png_ptr->background.red;
    +                     *(sp + 1) = (png_byte)png_ptr->background.green;
    +                     *(sp + 2) = (png_byte)png_ptr->background.blue;
    +                  }
    +
    +                  else
    +                  {
    +                     png_byte v, w;
    +
    +                     v = gamma_to_1[*sp];
    +                     png_composite(w, v, a, png_ptr->background_1.red);
    +                     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 == 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 == 0) w = gamma_from_1[w];
    +                     *(sp + 2) = w;
    +                  }
    +               }
    +            }
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 4)
    +               {
    +                  png_byte a = *(sp + 3);
    +
    +                  if (a == 0)
    +                  {
    +                     *sp = (png_byte)png_ptr->background.red;
    +                     *(sp + 1) = (png_byte)png_ptr->background.green;
    +                     *(sp + 2) = (png_byte)png_ptr->background.blue;
    +                  }
    +
    +                  else if (a < 0xff)
    +                  {
    +                     png_composite(*sp, *sp, a, png_ptr->background.red);
    +
    +                     png_composite(*(sp + 1), *(sp + 1), a,
    +                         png_ptr->background.green);
    +
    +                     png_composite(*(sp + 2), *(sp + 2), a,
    +                         png_ptr->background.blue);
    +                  }
    +               }
    +            }
    +         }
    +         else /* if (row_info->bit_depth == 16) */
    +         {
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +            if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
    +                gamma_16_to_1 != NULL)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 8)
    +               {
    +                  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
    +                      << 8) + (png_uint_16)(*(sp + 7)));
    +
    +                  if (a == (png_uint_16)0xffff)
    +                  {
    +                     png_uint_16 v;
    +
    +                     v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
    +                     *sp = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(v & 0xff);
    +
    +                     v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
    +                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 3) = (png_byte)(v & 0xff);
    +
    +                     v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
    +                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 5) = (png_byte)(v & 0xff);
    +                  }
    +
    +                  else if (a == 0)
    +                  {
    +                     /* 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 + 5) = (png_byte)(png_ptr->background.blue & 0xff);
    +                  }
    +
    +                  else
    +                  {
    +                     png_uint_16 v, w;
    +
    +                     v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
    +                     png_composite_16(w, v, a, png_ptr->background_1.red);
    +                     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 == 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 == 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);
    +                  }
    +               }
    +            }
    +
    +            else
    +#endif
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++, sp += 8)
    +               {
    +                  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
    +                      << 8) + (png_uint_16)(*(sp + 7)));
    +
    +                  if (a == 0)
    +                  {
    +                     *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 + 5) = (png_byte)(png_ptr->background.blue & 0xff);
    +                  }
    +
    +                  else if (a < 0xffff)
    +                  {
    +                     png_uint_16 v;
    +
    +                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
    +                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
    +                         + *(sp + 3));
    +                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
    +                         + *(sp + 5));
    +
    +                     png_composite_16(v, r, a, png_ptr->background.red);
    +                     *sp = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 1) = (png_byte)(v & 0xff);
    +
    +                     png_composite_16(v, g, a, png_ptr->background.green);
    +                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 3) = (png_byte)(v & 0xff);
    +
    +                     png_composite_16(v, b, a, png_ptr->background.blue);
    +                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
    +                     *(sp + 5) = (png_byte)(v & 0xff);
    +                  }
    +               }
    +            }
    +         }
    +         break;
    +      }
    +
    +      default:
    +         break;
    +   }
    +}
    +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +/* Gamma correct the image, avoiding the alpha channel.  Make sure
    + * you do this after you deal with the transparency issue on grayscale
    + * or RGB images. If your bit depth is 8, use gamma_table, if it
    + * is 16, use gamma_16_table and gamma_shift.  Build these with
    + * build_gamma_table().
    + */
    +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;
    +   int gamma_shift = png_ptr->gamma_shift;
    +
    +   png_bytep sp;
    +   png_uint_32 i;
    +   png_uint_32 row_width=row_info->width;
    +
    +   png_debug(1, "in png_do_gamma");
    +
    +   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
    +       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
    +   {
    +      switch (row_info->color_type)
    +      {
    +         case PNG_COLOR_TYPE_RGB:
    +         {
    +            if (row_info->bit_depth == 8)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +               }
    +            }
    +
    +            else /* if (row_info->bit_depth == 16) */
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  png_uint_16 v;
    +
    +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +
    +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +
    +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +               }
    +            }
    +            break;
    +         }
    +
    +         case PNG_COLOR_TYPE_RGB_ALPHA:
    +         {
    +            if (row_info->bit_depth == 8)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +
    +                  sp++;
    +               }
    +            }
    +
    +            else /* if (row_info->bit_depth == 16) */
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +
    +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +
    +                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 4;
    +               }
    +            }
    +            break;
    +         }
    +
    +         case PNG_COLOR_TYPE_GRAY_ALPHA:
    +         {
    +            if (row_info->bit_depth == 8)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  *sp = gamma_table[*sp];
    +                  sp += 2;
    +               }
    +            }
    +
    +            else /* if (row_info->bit_depth == 16) */
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 4;
    +               }
    +            }
    +            break;
    +         }
    +
    +         case PNG_COLOR_TYPE_GRAY:
    +         {
    +            if (row_info->bit_depth == 2)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i += 4)
    +               {
    +                  int a = *sp & 0xc0;
    +                  int b = *sp & 0x30;
    +                  int c = *sp & 0x0c;
    +                  int d = *sp & 0x03;
    +
    +                  *sp = (png_byte)(
    +                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
    +                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
    +                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
    +                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
    +                  sp++;
    +               }
    +            }
    +
    +            if (row_info->bit_depth == 4)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i += 2)
    +               {
    +                  int msb = *sp & 0xf0;
    +                  int lsb = *sp & 0x0f;
    +
    +                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
    +                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
    +                  sp++;
    +               }
    +            }
    +
    +            else if (row_info->bit_depth == 8)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  *sp = gamma_table[*sp];
    +                  sp++;
    +               }
    +            }
    +
    +            else if (row_info->bit_depth == 16)
    +            {
    +               sp = row;
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
    +                  *sp = (png_byte)((v >> 8) & 0xff);
    +                  *(sp + 1) = (png_byte)(v & 0xff);
    +                  sp += 2;
    +               }
    +            }
    +            break;
    +         }
    +
    +         default:
    +            break;
    +      }
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
    +/* Encode the alpha channel to the output gamma (the input channel is always
    + * linear.)  Called only with color types that have an alpha channel.  Needs the
    + * from_1 tables.
    + */
    +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) != 0)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         png_bytep table = png_ptr->gamma_from_1;
    +
    +         if (table != NULL)
    +         {
    +            int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
    +
    +            /* The alpha channel is the last component: */
    +            row += step - 1;
    +
    +            for (; row_width > 0; --row_width, row += step)
    +               *row = table[*row];
    +
    +            return;
    +         }
    +      }
    +
    +      else if (row_info->bit_depth == 16)
    +      {
    +         png_uint_16pp table = png_ptr->gamma_16_from_1;
    +         int gamma_shift = png_ptr->gamma_shift;
    +
    +         if (table != NULL)
    +         {
    +            int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
    +
    +            /* The alpha channel is the last component: */
    +            row += step - 2;
    +
    +            for (; row_width > 0; --row_width, row += step)
    +            {
    +               png_uint_16 v;
    +
    +               v = table[*(row + 1) >> gamma_shift][*row];
    +               *row = (png_byte)((v >> 8) & 0xff);
    +               *(row + 1) = (png_byte)(v & 0xff);
    +            }
    +
    +            return;
    +         }
    +      }
    +   }
    +
    +   /* Only get to here if called with a weird row_info; no harm has been done,
    +    * so just issue a warning.
    +    */
    +   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
    +}
    +#endif
    +
    +#ifdef PNG_READ_EXPAND_SUPPORTED
    +/* Expands a palette row to an RGB or RGBA row depending
    + * upon whether you supply trans and num_trans.
    + */
    +static void
    +png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
    +    png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
    +    int num_trans)
    +{
    +   int shift, value;
    +   png_bytep sp, dp;
    +   png_uint_32 i;
    +   png_uint_32 row_width=row_info->width;
    +
    +   png_debug(1, "in png_do_expand_palette");
    +
    +   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
    +   {
    +      if (row_info->bit_depth < 8)
    +      {
    +         switch (row_info->bit_depth)
    +         {
    +            case 1:
    +            {
    +               sp = row + (size_t)((row_width - 1) >> 3);
    +               dp = row + (size_t)row_width - 1;
    +               shift = 7 - (int)((row_width + 7) & 0x07);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  if ((*sp >> shift) & 0x01)
    +                     *dp = 1;
    +
    +                  else
    +                     *dp = 0;
    +
    +                  if (shift == 7)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift++;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            case 2:
    +            {
    +               sp = row + (size_t)((row_width - 1) >> 2);
    +               dp = row + (size_t)row_width - 1;
    +               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  value = (*sp >> shift) & 0x03;
    +                  *dp = (png_byte)value;
    +                  if (shift == 6)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift += 2;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            case 4:
    +            {
    +               sp = row + (size_t)((row_width - 1) >> 1);
    +               dp = row + (size_t)row_width - 1;
    +               shift = (int)((row_width & 0x01) << 2);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  value = (*sp >> shift) & 0x0f;
    +                  *dp = (png_byte)value;
    +                  if (shift == 4)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift += 4;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            default:
    +               break;
    +         }
    +         row_info->bit_depth = 8;
    +         row_info->pixel_depth = 8;
    +         row_info->rowbytes = row_width;
    +      }
    +
    +      if (row_info->bit_depth == 8)
    +      {
    +         {
    +            if (num_trans > 0)
    +            {
    +               sp = row + (size_t)row_width - 1;
    +               dp = row + ((size_t)row_width << 2) - 1;
    +
    +               i = 0;
    +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
    +               if (png_ptr->riffled_palette != NULL)
    +               {
    +                  /* The RGBA optimization works with png_ptr->bit_depth == 8
    +                   * but sometimes row_info->bit_depth has been changed to 8.
    +                   * In these cases, the palette hasn't been riffled.
    +                   */
    +                  i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row,
    +                      &sp, &dp);
    +               }
    +#else
    +               PNG_UNUSED(png_ptr)
    +#endif
    +
    +               for (; i < row_width; i++)
    +               {
    +                  if ((int)(*sp) >= num_trans)
    +                     *dp-- = 0xff;
    +                  else
    +                     *dp-- = trans_alpha[*sp];
    +                  *dp-- = palette[*sp].blue;
    +                  *dp-- = palette[*sp].green;
    +                  *dp-- = palette[*sp].red;
    +                  sp--;
    +               }
    +               row_info->bit_depth = 8;
    +               row_info->pixel_depth = 32;
    +               row_info->rowbytes = row_width * 4;
    +               row_info->color_type = 6;
    +               row_info->channels = 4;
    +            }
    +
    +            else
    +            {
    +               sp = row + (size_t)row_width - 1;
    +               dp = row + (size_t)(row_width * 3) - 1;
    +               i = 0;
    +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
    +               i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row,
    +                   &sp, &dp);
    +#else
    +               PNG_UNUSED(png_ptr)
    +#endif
    +
    +               for (; i < row_width; i++)
    +               {
    +                  *dp-- = palette[*sp].blue;
    +                  *dp-- = palette[*sp].green;
    +                  *dp-- = palette[*sp].red;
    +                  sp--;
    +               }
    +
    +               row_info->bit_depth = 8;
    +               row_info->pixel_depth = 24;
    +               row_info->rowbytes = row_width * 3;
    +               row_info->color_type = 2;
    +               row_info->channels = 3;
    +            }
    +         }
    +      }
    +   }
    +}
    +
    +/* If the bit depth < 8, it is expanded to 8.  Also, if the already
    + * expanded transparency value is supplied, an alpha channel is built.
    + */
    +static void
    +png_do_expand(png_row_infop row_info, png_bytep row,
    +    png_const_color_16p trans_color)
    +{
    +   int shift, value;
    +   png_bytep sp, dp;
    +   png_uint_32 i;
    +   png_uint_32 row_width=row_info->width;
    +
    +   png_debug(1, "in png_do_expand");
    +
    +   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    +   {
    +      unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
    +
    +      if (row_info->bit_depth < 8)
    +      {
    +         switch (row_info->bit_depth)
    +         {
    +            case 1:
    +            {
    +               gray = (gray & 0x01) * 0xff;
    +               sp = row + (size_t)((row_width - 1) >> 3);
    +               dp = row + (size_t)row_width - 1;
    +               shift = 7 - (int)((row_width + 7) & 0x07);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  if ((*sp >> shift) & 0x01)
    +                     *dp = 0xff;
    +
    +                  else
    +                     *dp = 0;
    +
    +                  if (shift == 7)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift++;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            case 2:
    +            {
    +               gray = (gray & 0x03) * 0x55;
    +               sp = row + (size_t)((row_width - 1) >> 2);
    +               dp = row + (size_t)row_width - 1;
    +               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  value = (*sp >> shift) & 0x03;
    +                  *dp = (png_byte)(value | (value << 2) | (value << 4) |
    +                     (value << 6));
    +                  if (shift == 6)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift += 2;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            case 4:
    +            {
    +               gray = (gray & 0x0f) * 0x11;
    +               sp = row + (size_t)((row_width - 1) >> 1);
    +               dp = row + (size_t)row_width - 1;
    +               shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
    +               for (i = 0; i < row_width; i++)
    +               {
    +                  value = (*sp >> shift) & 0x0f;
    +                  *dp = (png_byte)(value | (value << 4));
    +                  if (shift == 4)
    +                  {
    +                     shift = 0;
    +                     sp--;
    +                  }
    +
    +                  else
    +                     shift = 4;
    +
    +                  dp--;
    +               }
    +               break;
    +            }
    +
    +            default:
    +               break;
    +         }
    +
    +         row_info->bit_depth = 8;
    +         row_info->pixel_depth = 8;
    +         row_info->rowbytes = row_width;
    +      }
    +
    +      if (trans_color != NULL)
    +      {
    +         if (row_info->bit_depth == 8)
    +         {
    +            gray = gray & 0xff;
    +            sp = row + (size_t)row_width - 1;
    +            dp = row + ((size_t)row_width << 1) - 1;
    +
    +            for (i = 0; i < row_width; i++)
    +            {
    +               if ((*sp & 0xffU) == gray)
    +                  *dp-- = 0;
    +
    +               else
    +                  *dp-- = 0xff;
    +
    +               *dp-- = *sp--;
    +            }
    +         }
    +
    +         else if (row_info->bit_depth == 16)
    +         {
    +            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++)
    +            {
    +               if ((*(sp - 1) & 0xffU) == gray_high &&
    +                   (*(sp) & 0xffU) == gray_low)
    +               {
    +                  *dp-- = 0;
    +                  *dp-- = 0;
    +               }
    +
    +               else
    +               {
    +                  *dp-- = 0xff;
    +                  *dp-- = 0xff;
    +               }
    +
    +               *dp-- = *sp--;
    +               *dp-- = *sp--;
    +            }
    +         }
    +
    +         row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
    +         row_info->channels = 2;
    +         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
    +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
    +             row_width);
    +      }
    +   }
    +   else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
    +       trans_color != NULL)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         png_byte red = (png_byte)(trans_color->red & 0xff);
    +         png_byte green = (png_byte)(trans_color->green & 0xff);
    +         png_byte blue = (png_byte)(trans_color->blue & 0xff);
    +         sp = row + (size_t)row_info->rowbytes - 1;
    +         dp = row + ((size_t)row_width << 2) - 1;
    +         for (i = 0; i < row_width; i++)
    +         {
    +            if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
    +               *dp-- = 0;
    +
    +            else
    +               *dp-- = 0xff;
    +
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +         }
    +      }
    +      else if (row_info->bit_depth == 16)
    +      {
    +         png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
    +         png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
    +         png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
    +         png_byte red_low = (png_byte)(trans_color->red & 0xff);
    +         png_byte green_low = (png_byte)(trans_color->green & 0xff);
    +         png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
    +         sp = row + row_info->rowbytes - 1;
    +         dp = row + ((size_t)row_width << 3) - 1;
    +         for (i = 0; i < row_width; i++)
    +         {
    +            if (*(sp - 5) == red_high &&
    +                *(sp - 4) == red_low &&
    +                *(sp - 3) == green_high &&
    +                *(sp - 2) == green_low &&
    +                *(sp - 1) == blue_high &&
    +                *(sp    ) == blue_low)
    +            {
    +               *dp-- = 0;
    +               *dp-- = 0;
    +            }
    +
    +            else
    +            {
    +               *dp-- = 0xff;
    +               *dp-- = 0xff;
    +            }
    +
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +            *dp-- = *sp--;
    +         }
    +      }
    +      row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    +      row_info->channels = 4;
    +      row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
    +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_EXPAND_16_SUPPORTED
    +/* 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.
    + */
    +static void
    +png_do_expand_16(png_row_infop row_info, png_bytep row)
    +{
    +   if (row_info->bit_depth == 8 &&
    +      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
    +   {
    +      /* The row have a sequence of bytes containing [0..255] and we need
    +       * to turn it into another row containing [0..65535], to do this we
    +       * calculate:
    +       *
    +       *  (input / 255) * 65535
    +       *
    +       *  Which happens to be exactly input * 257 and this can be achieved
    +       *  simply by byte replication in place (copying backwards).
    +       */
    +      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
    +      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
    +      while (dp > sp)
    +      {
    +         dp[-2] = dp[-1] = *--sp; dp -= 2;
    +      }
    +
    +      row_info->rowbytes *= 2;
    +      row_info->bit_depth = 16;
    +      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_QUANTIZE_SUPPORTED
    +static void
    +png_do_quantize(png_row_infop row_info, png_bytep row,
    +    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
    +{
    +   png_bytep sp, dp;
    +   png_uint_32 i;
    +   png_uint_32 row_width=row_info->width;
    +
    +   png_debug(1, "in png_do_quantize");
    +
    +   if (row_info->bit_depth == 8)
    +   {
    +      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
    +      {
    +         int r, g, b, p;
    +         sp = row;
    +         dp = row;
    +         for (i = 0; i < row_width; i++)
    +         {
    +            r = *sp++;
    +            g = *sp++;
    +            b = *sp++;
    +
    +            /* This looks real messy, but the compiler will reduce
    +             * it down to a reasonable formula.  For example, with
    +             * 5 bits per color, we get:
    +             * p = (((r >> 3) & 0x1f) << 10) |
    +             *    (((g >> 3) & 0x1f) << 5) |
    +             *    ((b >> 3) & 0x1f);
    +             */
    +            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
    +                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
    +                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
    +                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
    +                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
    +                (PNG_QUANTIZE_BLUE_BITS)) |
    +                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
    +                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
    +
    +            *dp++ = palette_lookup[p];
    +         }
    +
    +         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
    +         row_info->channels = 1;
    +         row_info->pixel_depth = row_info->bit_depth;
    +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    +      }
    +
    +      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
    +         palette_lookup != NULL)
    +      {
    +         int r, g, b, p;
    +         sp = row;
    +         dp = row;
    +         for (i = 0; i < row_width; i++)
    +         {
    +            r = *sp++;
    +            g = *sp++;
    +            b = *sp++;
    +            sp++;
    +
    +            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
    +                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
    +                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
    +                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
    +                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
    +                (PNG_QUANTIZE_BLUE_BITS)) |
    +                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
    +                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
    +
    +            *dp++ = palette_lookup[p];
    +         }
    +
    +         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
    +         row_info->channels = 1;
    +         row_info->pixel_depth = row_info->bit_depth;
    +         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    +      }
    +
    +      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
    +         quantize_lookup)
    +      {
    +         sp = row;
    +
    +         for (i = 0; i < row_width; i++, sp++)
    +         {
    +            *sp = quantize_lookup[*sp];
    +         }
    +      }
    +   }
    +}
    +#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_transformations(png_structrp png_ptr, png_row_infop row_info)
    +{
    +   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.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)
    +      {
    +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
    +         if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8))
    +         {
    +            if (png_ptr->riffled_palette == NULL)
    +            {
    +               /* Initialize the accelerated palette expansion. */
    +               png_ptr->riffled_palette =
    +                   (png_bytep)png_malloc(png_ptr, 256 * 4);
    +               png_riffle_palette_neon(png_ptr);
    +            }
    +         }
    +#endif
    +         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 != 0 &&
    +             (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
    +            png_do_expand(row_info, png_ptr->row_buf + 1,
    +                &(png_ptr->trans_color));
    +
    +         else
    +            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) != 0 &&
    +       ((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 */
    +                /*  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 /* READ_TRANSFORMS */
    +#endif /* READ */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngrutil.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,4709 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngrutil.c - utilities to read a PNG file
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * This file contains routines that are only called from within
    + * libpng itself during the course of reading an image.
    + */
    +
    +#include "pngpriv.h"
    +
    +#ifdef PNG_READ_SUPPORTED
    +
    +png_uint_32 PNGAPI
    +png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
    +{
    +   png_uint_32 uval = png_get_uint_32(buf);
    +
    +   if (uval > PNG_UINT_31_MAX)
    +      png_error(png_ptr, "PNG unsigned integer out of range");
    +
    +   return (uval);
    +}
    +
    +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
    +/* The following is a variation on the above for use with the fixed
    + * point values used for gAMA and cHRM.  Instead of png_error it
    + * issues a warning and returns (-1) - an invalid value because both
    + * gAMA and cHRM use *unsigned* integers for fixed point values.
    + */
    +#define PNG_FIXED_ERROR (-1)
    +
    +static png_fixed_point /* PRIVATE */
    +png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
    +{
    +   png_uint_32 uval = png_get_uint_32(buf);
    +
    +   if (uval <= PNG_UINT_31_MAX)
    +      return (png_fixed_point)uval; /* known to be in range */
    +
    +   /* The caller can turn off the warning by passing NULL. */
    +   if (png_ptr != NULL)
    +      png_warning(png_ptr, "PNG fixed point integer out of range");
    +
    +   return PNG_FIXED_ERROR;
    +}
    +#endif
    +
    +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
    +/* NOTE: the read macros will obscure these definitions, so that if
    + * PNG_USE_READ_MACROS is set the library will not use them internally,
    + * but the APIs will still be available externally.
    + *
    + * The parentheses around "PNGAPI function_name" in the following three
    + * functions are necessary because they allow the macros to co-exist with
    + * these (unused but exported) functions.
    + */
    +
    +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
    +png_uint_32 (PNGAPI
    +png_get_uint_32)(png_const_bytep buf)
    +{
    +   png_uint_32 uval =
    +       ((png_uint_32)(*(buf    )) << 24) +
    +       ((png_uint_32)(*(buf + 1)) << 16) +
    +       ((png_uint_32)(*(buf + 2)) <<  8) +
    +       ((png_uint_32)(*(buf + 3))      ) ;
    +
    +   return uval;
    +}
    +
    +/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
    + * data is stored in the PNG file in two's complement format and there
    + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
    + * the following code does a two's complement to native conversion.
    + */
    +png_int_32 (PNGAPI
    +png_get_int_32)(png_const_bytep buf)
    +{
    +   png_uint_32 uval = png_get_uint_32(buf);
    +   if ((uval & 0x80000000) == 0) /* non-negative */
    +      return (png_int_32)uval;
    +
    +   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
    +   if ((uval & 0x80000000) == 0) /* no overflow */
    +      return -(png_int_32)uval;
    +   /* The following has to be safe; this function only gets called on PNG data
    +    * and if we get here that data is invalid.  0 is the most safe value and
    +    * if not then an attacker would surely just generate a PNG with 0 instead.
    +    */
    +   return 0;
    +}
    +
    +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
    +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
    +    * 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.)
    +    */
    +   unsigned int val =
    +       ((unsigned int)(*buf) << 8) +
    +       ((unsigned int)(*(buf + 1)));
    +
    +   return (png_uint_16)val;
    +}
    +
    +#endif /* READ_INT_FUNCTIONS */
    +
    +/* Read and check the PNG file signature */
    +void /* PRIVATE */
    +png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
    +{
    +   size_t num_checked, num_to_check;
    +
    +   /* Exit if the user application does not expect a signature. */
    +   if (png_ptr->sig_bytes >= 8)
    +      return;
    +
    +   num_checked = png_ptr->sig_bytes;
    +   num_to_check = 8 - num_checked;
    +
    +#ifdef PNG_IO_STATE_SUPPORTED
    +   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
    +#endif
    +
    +   /* The signature must be serialized in a single I/O call. */
    +   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) != 0)
    +   {
    +      if (num_checked < 4 &&
    +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
    +         png_error(png_ptr, "Not a PNG file");
    +      else
    +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    +   }
    +   if (num_checked < 3)
    +      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
    +}
    +
    +/* Read the chunk header (length + type name).
    + * Put the type name into png_ptr->chunk_name, and return the length.
    + */
    +png_uint_32 /* PRIVATE */
    +png_read_chunk_header(png_structrp png_ptr)
    +{
    +   png_byte buf[8];
    +   png_uint_32 length;
    +
    +#ifdef PNG_IO_STATE_SUPPORTED
    +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
    +#endif
    +
    +   /* Read the length and the chunk name.
    +    * This must be performed in a single I/O call.
    +    */
    +   png_read_data(png_ptr, buf, 8);
    +   length = png_get_uint_31(png_ptr, buf);
    +
    +   /* Put the chunk name into png_ptr->chunk_name. */
    +   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, buf + 4, 4);
    +
    +   /* Check to see if chunk name is valid. */
    +   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    +
    +   /* Check for too-large chunk length */
    +   png_check_chunk_length(png_ptr, length);
    +
    +#ifdef PNG_IO_STATE_SUPPORTED
    +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
    +#endif
    +
    +   return length;
    +}
    +
    +/* Read data, and (optionally) run it through the CRC. */
    +void /* PRIVATE */
    +png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_read_data(png_ptr, buf, length);
    +   png_calculate_crc(png_ptr, buf, length);
    +}
    +
    +/* Optionally skip data and then check the CRC.  Depending on whether we
    + * 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_structrp png_ptr, png_uint_32 skip)
    +{
    +   /* 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_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 (png_crc_error(png_ptr) != 0)
    +   {
    +      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_error(png_ptr, "CRC error");
    +
    +      return (1);
    +   }
    +
    +   return (0);
    +}
    +
    +/* Compare the CRC stored in the PNG file with that calculated by libpng from
    + * the data it has read thus far.
    + */
    +int /* PRIVATE */
    +png_crc_error(png_structrp png_ptr)
    +{
    +   png_byte crc_bytes[4];
    +   png_uint_32 crc;
    +   int need_crc = 1;
    +
    +   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 */
    +   {
    +      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
    +         need_crc = 0;
    +   }
    +
    +#ifdef PNG_IO_STATE_SUPPORTED
    +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
    +#endif
    +
    +   /* The chunk CRC must be serialized in a single I/O call. */
    +   png_read_data(png_ptr, crc_bytes, 4);
    +
    +   if (need_crc != 0)
    +   {
    +      crc = png_get_uint_32(crc_bytes);
    +      return ((int)(crc != png_ptr->crc));
    +   }
    +
    +   else
    +      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)
    +      {
    +         memset(buffer, 0, new_size); /* just in case */
    +         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 " 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_RELEASE_BUILD
    +      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 ZLIB_VERNUM >= 0x1240
    +      int window_bits = 0;
    +
    +# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
    +      if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
    +          PNG_OPTION_ON)
    +      {
    +         window_bits = 15;
    +         png_ptr->zstream_start = 0; /* fixed window size */
    +      }
    +
    +      else
    +      {
    +         png_ptr->zstream_start = 1;
    +      }
    +# endif
    +
    +#endif /* ZLIB_VERNUM >= 0x1240 */
    +
    +      /* 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 ZLIB_VERNUM >= 0x1240
    +         ret = inflateReset2(&png_ptr->zstream, window_bits);
    +#else
    +         ret = inflateReset(&png_ptr->zstream);
    +#endif
    +      }
    +
    +      else
    +      {
    +#if ZLIB_VERNUM >= 0x1240
    +         ret = inflateInit2(&png_ptr->zstream, window_bits);
    +#else
    +         ret = inflateInit(&png_ptr->zstream);
    +#endif
    +
    +         if (ret == Z_OK)
    +            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
    +      }
    +
    +#if ZLIB_VERNUM >= 0x1290 && \
    +   defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
    +      if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
    +         /* Turn off validation of the ADLER32 checksum in IDAT chunks */
    +         ret = inflateValidate(&png_ptr->zstream, 0);
    +#endif
    +
    +      if (ret == Z_OK)
    +         png_ptr->zowner = owner;
    +
    +      else
    +         png_zstream_error(png_ptr, ret);
    +
    +      return ret;
    +   }
    +
    +#ifdef window_bits
    +# undef window_bits
    +#endif
    +}
    +
    +#if ZLIB_VERNUM >= 0x1240
    +/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
    + * in this case some zlib versions skip validation of the CINFO field and, in
    + * certain circumstances, libpng may end up displaying an invalid image, in
    + * contrast to implementations that call zlib in the normal way (e.g. libpng
    + * 1.5).
    + */
    +int /* PRIVATE */
    +png_zlib_inflate(png_structrp png_ptr, int flush)
    +{
    +   if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
    +   {
    +      if ((*png_ptr->zstream.next_in >> 4) > 7)
    +      {
    +         png_ptr->zstream.msg = "invalid window size (libpng)";
    +         return Z_DATA_ERROR;
    +      }
    +
    +      png_ptr->zstream_start = 0;
    +   }
    +
    +   return inflate(&png_ptr->zstream, flush);
    +}
    +#endif /* Zlib >= 1.2.4 */
    +
    +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
    +#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
    +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
    + * allow the caller to do multiple calls if required.  If the 'finish' flag is
    + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
    + * 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)
    +{
    +   if (png_ptr->zowner == owner) /* Else not claimed */
    +   {
    +      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.
    +       */
    +      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
    +      {
    +         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)
    +         {
    +            /* 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);
    +         }
    +
    +         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 = PNG_INFLATE(png_ptr, 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.
    +       */
    +      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!
    +       */
    +      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
    +      return Z_STREAM_ERROR;
    +   }
    +}
    +
    +/*
    + * 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_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_malloc_max > 0 &&
    +       png_ptr->user_chunk_malloc_max < limit)
    +      limit = png_ptr->user_chunk_malloc_max;
    +# elif PNG_USER_CHUNK_MALLOC_MAX > 0
    +   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
    +      limit = PNG_USER_CHUNK_MALLOC_MAX;
    +# endif
    +
    +   if (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)
    +               {
    +                  memset(text, 0, buffer_size);
    +
    +                  ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
    +                      png_ptr->read_buffer + prefix_size, &lzsize,
    +                      text + prefix_size, newlength);
    +
    +                  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);
    +
    +                  /* 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);
    +               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_zTXt || READ_iTXt */
    +#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 = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
    +             Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
    +      }
    +      while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
    +
    +      *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_iCCP */
    +
    +/* Read and check the IDHR chunk */
    +
    +void /* PRIVATE */
    +png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_byte buf[13];
    +   png_uint_32 width, height;
    +   int bit_depth, color_type, compression_type, filter_type;
    +   int interlace_type;
    +
    +   png_debug(1, "in png_handle_IHDR");
    +
    +   if ((png_ptr->mode & PNG_HAVE_IHDR) != 0)
    +      png_chunk_error(png_ptr, "out of place");
    +
    +   /* Check the length */
    +   if (length != 13)
    +      png_chunk_error(png_ptr, "invalid");
    +
    +   png_ptr->mode |= PNG_HAVE_IHDR;
    +
    +   png_crc_read(png_ptr, buf, 13);
    +   png_crc_finish(png_ptr, 0);
    +
    +   width = png_get_uint_31(png_ptr, buf);
    +   height = png_get_uint_31(png_ptr, buf + 4);
    +   bit_depth = buf[8];
    +   color_type = buf[9];
    +   compression_type = buf[10];
    +   filter_type = buf[11];
    +   interlace_type = buf[12];
    +
    +   /* Set internal variables */
    +   png_ptr->width = width;
    +   png_ptr->height = height;
    +   png_ptr->bit_depth = (png_byte)bit_depth;
    +   png_ptr->interlaced = (png_byte)interlace_type;
    +   png_ptr->color_type = (png_byte)color_type;
    +#ifdef PNG_MNG_FEATURES_SUPPORTED
    +   png_ptr->filter_type = (png_byte)filter_type;
    +#endif
    +   png_ptr->compression_type = (png_byte)compression_type;
    +
    +   /* Find number of channels */
    +   switch (png_ptr->color_type)
    +   {
    +      default: /* invalid, png_set_IHDR calls png_error */
    +      case PNG_COLOR_TYPE_GRAY:
    +      case PNG_COLOR_TYPE_PALETTE:
    +         png_ptr->channels = 1;
    +         break;
    +
    +      case PNG_COLOR_TYPE_RGB:
    +         png_ptr->channels = 3;
    +         break;
    +
    +      case PNG_COLOR_TYPE_GRAY_ALPHA:
    +         png_ptr->channels = 2;
    +         break;
    +
    +      case PNG_COLOR_TYPE_RGB_ALPHA:
    +         png_ptr->channels = 4;
    +         break;
    +   }
    +
    +   /* Set up other useful info */
    +   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);
    +   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
    +   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
    +       color_type, interlace_type, compression_type, filter_type);
    +}
    +
    +/* Read and check the palette */
    +void /* PRIVATE */
    +png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_color palette[PNG_MAX_PALETTE_LENGTH];
    +   int max_palette_length, num, i;
    +#ifdef PNG_POINTER_INDEXING_SUPPORTED
    +   png_colorp pal_ptr;
    +#endif
    +
    +   png_debug(1, "in png_handle_PLTE");
    +
    +   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)
    +   {
    +      /* 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;
    +   }
    +
    +   png_ptr->mode |= PNG_HAVE_PLTE;
    +
    +   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
    +      return;
    +   }
    +
    +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    +   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      return;
    +   }
    +#endif
    +
    +   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_chunk_benign_error(png_ptr, "invalid");
    +
    +      else
    +         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;
    +
    +   /* If the palette has 256 or fewer entries but is too large for the bit
    +    * depth, we don't issue an error, to preserve the behavior of previous
    +    * libpng versions. We silently truncate the unused extra palette entries
    +    * here.
    +    */
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      max_palette_length = (1 << png_ptr->bit_depth);
    +   else
    +      max_palette_length = PNG_MAX_PALETTE_LENGTH;
    +
    +   if (num > max_palette_length)
    +      num = max_palette_length;
    +
    +#ifdef PNG_POINTER_INDEXING_SUPPORTED
    +   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
    +   {
    +      png_byte buf[3];
    +
    +      png_crc_read(png_ptr, buf, 3);
    +      pal_ptr->red = buf[0];
    +      pal_ptr->green = buf[1];
    +      pal_ptr->blue = buf[2];
    +   }
    +#else
    +   for (i = 0; i < num; i++)
    +   {
    +      png_byte buf[3];
    +
    +      png_crc_read(png_ptr, buf, 3);
    +      /* Don't depend upon png_color being any order */
    +      palette[i].red = buf[0];
    +      palette[i].green = buf[1];
    +      palette[i].blue = buf[2];
    +   }
    +#endif
    +
    +   /* If we actually need the PLTE chunk (ie for a paletted image), we do
    +    * whatever the normal CRC configuration tells us.  However, if we
    +    * have an RGB image, the PLTE can be considered ancillary, so
    +    * we will act as though it is.
    +    */
    +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +#endif
    +   {
    +      png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
    +   }
    +
    +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    +   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) == 0)
    +      {
    +         if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0)
    +            return;
    +
    +         else
    +            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) == 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->num_trans > 0 ||
    +       (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
    +   {
    +      /* 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_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) == 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_chunk_benign_error(png_ptr, "invalid");
    +
    +   PNG_UNUSED(info_ptr)
    +}
    +
    +#ifdef PNG_READ_gAMA_SUPPORTED
    +void /* PRIVATE */
    +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) == 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 != 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;
    +   }
    +
    +   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;
    +
    +   for (i=0; i sample_depth)
    +      {
    +         png_chunk_benign_error(png_ptr, "invalid");
    +         return;
    +      }
    +   }
    +
    +   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
    +   {
    +      png_ptr->sig_bit.red = buf[0];
    +      png_ptr->sig_bit.green = buf[1];
    +      png_ptr->sig_bit.blue = buf[2];
    +      png_ptr->sig_bit.alpha = buf[3];
    +   }
    +
    +   else
    +   {
    +      png_ptr->sig_bit.gray = buf[0];
    +      png_ptr->sig_bit.red = buf[0];
    +      png_ptr->sig_bit.green = buf[0];
    +      png_ptr->sig_bit.blue = buf[0];
    +      png_ptr->sig_bit.alpha = buf[1];
    +   }
    +
    +   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
    +}
    +#endif
    +
    +#ifdef PNG_READ_cHRM_SUPPORTED
    +void /* PRIVATE */
    +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_byte buf[32];
    +   png_xy xy;
    +
    +   png_debug(1, "in png_handle_cHRM");
    +
    +   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 != 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 keyword must be at least one character and there is a
    +    * terminator (0) byte and the compression method byte, and the
    +    * 'zlib' datastream is at least 11 bytes.
    +    */
    +   if (length < 14)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "too short");
    +      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;
    +   }
    +
    +   /* 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)
    +   {
    +      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;
    +
    +      /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
    +       * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
    +       */
    +      if (length < 11)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         png_chunk_benign_error(png_ptr, "too short");
    +         return;
    +      }
    +
    +      keyword_length = 0;
    +      while (keyword_length < 80 && keyword_length < read_length &&
    +         keyword[keyword_length] != 0)
    +         ++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]={0};
    +               Byte local_buffer[PNG_INFLATE_BUF_SIZE];
    +               png_alloc_size_t size = (sizeof profile_header);
    +
    +               png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
    +               png_ptr->zstream.avail_in = read_length;
    +               (void)png_inflate_read(png_ptr, local_buffer,
    +                   (sizeof local_buffer), &length, profile_header, &size,
    +                   0/*finish: don't, because the output is too small*/);
    +
    +               if (size == 0)
    +               {
    +                  /* We have the ICC profile header; do the basic header checks.
    +                   */
    +                  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 this stuff will overflow.
    +                         */
    +                        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;
    +
    +# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
    +                                    /* Check for a match against sRGB */
    +                                    png_icc_set_sRGB(png_ptr,
    +                                        &png_ptr->colorspace, profile,
    +                                        png_ptr->zstream.adler);
    +# endif
    +
    +                                    /* Steal the profile for info_ptr. */
    +                                    if (info_ptr != NULL)
    +                                    {
    +                                       png_free_data(png_ptr, info_ptr,
    +                                           PNG_FREE_ICCP, 0);
    +
    +                                       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;
    +                                    }
    +                                 }
    +                                 if (errmsg == NULL)
    +                                    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);
    +
    +   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 /* READ_iCCP */
    +
    +#ifdef PNG_READ_sPLT_SUPPORTED
    +void /* PRIVATE */
    +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_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_uint_32 dl;
    +   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)
    +      {
    +         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 sPLT");
    +         png_crc_finish(png_ptr, length);
    +         return;
    +      }
    +   }
    +#endif
    +
    +   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_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "out of place");
    +      return;
    +   }
    +
    +#ifdef PNG_MAX_MALLOC_64K
    +   if (length > 65535U)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "too large to fit in memory");
    +      return;
    +   }
    +#endif
    +
    +   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.
    +    */
    +   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 (length < 2U || entry_start > buffer + (length - 2U))
    +   {
    +      png_warning(png_ptr, "malformed sPLT chunk");
    +      return;
    +   }
    +
    +   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.
    +    */
    +   data_length = length - (png_uint_32)(entry_start - buffer);
    +
    +   /* Integrity-check the data length */
    +   if ((data_length % (unsigned int)entry_size) != 0)
    +   {
    +      png_warning(png_ptr, "sPLT chunk has bad length");
    +      return;
    +   }
    +
    +   dl = (png_uint_32)(data_length / (unsigned int)entry_size);
    +   max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
    +
    +   if (dl > max_dl)
    +   {
    +      png_warning(png_ptr, "sPLT chunk too long");
    +      return;
    +   }
    +
    +   new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
    +
    +   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
    +       (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
    +
    +   if (new_palette.entries == NULL)
    +   {
    +      png_warning(png_ptr, "sPLT chunk requires too much memory");
    +      return;
    +   }
    +
    +#ifdef PNG_POINTER_INDEXING_SUPPORTED
    +   for (i = 0; i < new_palette.nentries; i++)
    +   {
    +      pp = new_palette.entries + i;
    +
    +      if (new_palette.depth == 8)
    +      {
    +         pp->red = *entry_start++;
    +         pp->green = *entry_start++;
    +         pp->blue = *entry_start++;
    +         pp->alpha = *entry_start++;
    +      }
    +
    +      else
    +      {
    +         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
    +         pp->green = png_get_uint_16(entry_start); entry_start += 2;
    +         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
    +         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
    +      }
    +
    +      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
    +   }
    +#else
    +   pp = new_palette.entries;
    +
    +   for (i = 0; i < new_palette.nentries; i++)
    +   {
    +
    +      if (new_palette.depth == 8)
    +      {
    +         pp[i].red   = *entry_start++;
    +         pp[i].green = *entry_start++;
    +         pp[i].blue  = *entry_start++;
    +         pp[i].alpha = *entry_start++;
    +      }
    +
    +      else
    +      {
    +         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
    +         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
    +         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
    +         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
    +      }
    +
    +      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
    +   }
    +#endif
    +
    +   /* Discard all chunk data except the name and stash that */
    +   new_palette.name = (png_charp)buffer;
    +
    +   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
    +
    +   png_free(png_ptr, new_palette.entries);
    +}
    +#endif /* READ_sPLT */
    +
    +#ifdef PNG_READ_tRNS_SUPPORTED
    +void /* PRIVATE */
    +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) == 0)
    +      png_chunk_error(png_ptr, "missing IHDR");
    +
    +   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    +   {
    +      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) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    +   {
    +      png_byte buf[2];
    +
    +      if (length != 2)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         png_chunk_benign_error(png_ptr, "invalid");
    +         return;
    +      }
    +
    +      png_crc_read(png_ptr, buf, 2);
    +      png_ptr->num_trans = 1;
    +      png_ptr->trans_color.gray = png_get_uint_16(buf);
    +   }
    +
    +   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
    +   {
    +      png_byte buf[6];
    +
    +      if (length != 6)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         png_chunk_benign_error(png_ptr, "invalid");
    +         return;
    +      }
    +
    +      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);
    +      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
    +   }
    +
    +   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +   {
    +      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
    +      {
    +         /* 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 > (unsigned int) png_ptr->num_palette ||
    +         length > (unsigned int) PNG_MAX_PALETTE_LENGTH ||
    +         length == 0)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         png_chunk_benign_error(png_ptr, "invalid");
    +         return;
    +      }
    +
    +      png_crc_read(png_ptr, readbuf, length);
    +      png_ptr->num_trans = (png_uint_16)length;
    +   }
    +
    +   else
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "invalid with alpha channel");
    +      return;
    +   }
    +
    +   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));
    +}
    +#endif
    +
    +#ifdef PNG_READ_bKGD_SUPPORTED
    +void /* PRIVATE */
    +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   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) == 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_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_bKGD) != 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 = 1;
    +
    +   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
    +      truelen = 6;
    +
    +   else
    +      truelen = 2;
    +
    +   if (length != truelen)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "invalid");
    +      return;
    +   }
    +
    +   png_crc_read(png_ptr, buf, truelen);
    +
    +   if (png_crc_finish(png_ptr, 0) != 0)
    +      return;
    +
    +   /* We convert the index value into RGB components so that we can allow
    +    * arbitrary RGB values for background when we have transparency, and
    +    * so it is easy to determine the RGB values of the background color
    +    * from the info_ptr struct.
    +    */
    +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +   {
    +      background.index = buf[0];
    +
    +      if (info_ptr != NULL && info_ptr->num_palette != 0)
    +      {
    +         if (buf[0] >= info_ptr->num_palette)
    +         {
    +            png_chunk_benign_error(png_ptr, "invalid index");
    +            return;
    +         }
    +
    +         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
    +         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
    +         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
    +      }
    +
    +      else
    +         background.red = background.green = background.blue = 0;
    +
    +      background.gray = 0;
    +   }
    +
    +   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
    +   {
    +      if (png_ptr->bit_depth <= 8)
    +      {
    +         if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
    +         {
    +            png_chunk_benign_error(png_ptr, "invalid gray level");
    +            return;
    +         }
    +      }
    +
    +      background.index = 0;
    +      background.red =
    +      background.green =
    +      background.blue =
    +      background.gray = png_get_uint_16(buf);
    +   }
    +
    +   else
    +   {
    +      if (png_ptr->bit_depth <= 8)
    +      {
    +         if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
    +         {
    +            png_chunk_benign_error(png_ptr, "invalid color");
    +            return;
    +         }
    +      }
    +
    +      background.index = 0;
    +      background.red = png_get_uint_16(buf);
    +      background.green = png_get_uint_16(buf + 2);
    +      background.blue = png_get_uint_16(buf + 4);
    +      background.gray = 0;
    +   }
    +
    +   png_set_bKGD(png_ptr, info_ptr, &background);
    +}
    +#endif
    +
    +#ifdef PNG_READ_eXIf_SUPPORTED
    +void /* PRIVATE */
    +png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   unsigned int i;
    +
    +   png_debug(1, "in png_handle_eXIf");
    +
    +   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
    +      png_chunk_error(png_ptr, "missing IHDR");
    +
    +   if (length < 2)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "too short");
    +      return;
    +   }
    +
    +   else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   info_ptr->free_me |= PNG_FREE_EXIF;
    +
    +   info_ptr->eXIf_buf = png_voidcast(png_bytep,
    +             png_malloc_warn(png_ptr, length));
    +
    +   if (info_ptr->eXIf_buf == NULL)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "out of memory");
    +      return;
    +   }
    +
    +   for (i = 0; i < length; i++)
    +   {
    +      png_byte buf[1];
    +      png_crc_read(png_ptr, buf, 1);
    +      info_ptr->eXIf_buf[i] = buf[0];
    +      if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
    +                 && info_ptr->eXIf_buf[0] != buf[0])
    +      {
    +         png_crc_finish(png_ptr, length);
    +         png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
    +         png_free(png_ptr, info_ptr->eXIf_buf);
    +         info_ptr->eXIf_buf = NULL;
    +         return;
    +      }
    +   }
    +
    +   if (png_crc_finish(png_ptr, 0) != 0)
    +      return;
    +
    +   png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
    +
    +   png_free(png_ptr, info_ptr->eXIf_buf);
    +   info_ptr->eXIf_buf = NULL;
    +}
    +#endif
    +
    +#ifdef PNG_READ_hIST_SUPPORTED
    +void /* PRIVATE */
    +png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   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) == 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_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_hIST) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   num = length / 2 ;
    +
    +   if (num != (unsigned int) png_ptr->num_palette ||
    +       num > (unsigned int) PNG_MAX_PALETTE_LENGTH)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "invalid");
    +      return;
    +   }
    +
    +   for (i = 0; i < num; i++)
    +   {
    +      png_byte buf[2];
    +
    +      png_crc_read(png_ptr, buf, 2);
    +      readbuf[i] = png_get_uint_16(buf);
    +   }
    +
    +   if (png_crc_finish(png_ptr, 0) != 0)
    +      return;
    +
    +   png_set_hIST(png_ptr, info_ptr, readbuf);
    +}
    +#endif
    +
    +#ifdef PNG_READ_pHYs_SUPPORTED
    +void /* PRIVATE */
    +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;
    +   int unit_type;
    +
    +   png_debug(1, "in png_handle_pHYs");
    +
    +   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_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) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   if (length != 9)
    +   {
    +      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) != 0)
    +      return;
    +
    +   res_x = png_get_uint_32(buf);
    +   res_y = png_get_uint_32(buf + 4);
    +   unit_type = buf[8];
    +   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
    +}
    +#endif
    +
    +#ifdef PNG_READ_oFFs_SUPPORTED
    +void /* PRIVATE */
    +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;
    +   int unit_type;
    +
    +   png_debug(1, "in png_handle_oFFs");
    +
    +   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_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) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   if (length != 9)
    +   {
    +      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) != 0)
    +      return;
    +
    +   offset_x = png_get_int_32(buf);
    +   offset_y = png_get_int_32(buf + 4);
    +   unit_type = buf[8];
    +   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
    +}
    +#endif
    +
    +#ifdef PNG_READ_pCAL_SUPPORTED
    +/* Read the pCAL chunk (described in the PNG Extensions document) */
    +void /* PRIVATE */
    +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_bytep buffer, buf, units, endptr;
    +   png_charpp params;
    +   int i;
    +
    +   png_debug(1, "in png_handle_pCAL");
    +
    +   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_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) != 0)
    +   {
    +      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);
    +
    +   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;
    +   }
    +
    +   png_crc_read(png_ptr, buffer, length);
    +
    +   if (png_crc_finish(png_ptr, 0) != 0)
    +      return;
    +
    +   buffer[length] = 0; /* Null terminate the last string */
    +
    +   png_debug(3, "Finding end of pCAL purpose string");
    +   for (buf = buffer; *buf; buf++)
    +      /* Empty loop */ ;
    +
    +   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_chunk_benign_error(png_ptr, "invalid");
    +      return;
    +   }
    +
    +   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
    +   X0 = png_get_int_32((png_bytep)buf+1);
    +   X1 = png_get_int_32((png_bytep)buf+5);
    +   type = buf[9];
    +   nparams = buf[10];
    +   units = buf + 11;
    +
    +   png_debug(3, "Checking pCAL equation type and number of parameters");
    +   /* Check that we have the right number of parameters for known
    +    * equation types.
    +    */
    +   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
    +       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
    +       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
    +       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
    +   {
    +      png_chunk_benign_error(png_ptr, "invalid parameter count");
    +      return;
    +   }
    +
    +   else if (type >= PNG_EQUATION_LAST)
    +   {
    +      png_chunk_benign_error(png_ptr, "unrecognized equation type");
    +   }
    +
    +   for (buf = units; *buf; buf++)
    +      /* Empty loop to move past the units string. */ ;
    +
    +   png_debug(3, "Allocating pCAL parameters array");
    +
    +   params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
    +       nparams * (sizeof (png_charp))));
    +
    +   if (params == NULL)
    +   {
    +      png_chunk_benign_error(png_ptr, "out of memory");
    +      return;
    +   }
    +
    +   /* Get pointers to the start of each parameter string. */
    +   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] = (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_free(png_ptr, params);
    +         png_chunk_benign_error(png_ptr, "invalid data");
    +         return;
    +      }
    +   }
    +
    +   png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
    +       (png_charp)units, params);
    +
    +   png_free(png_ptr, params);
    +}
    +#endif
    +
    +#ifdef PNG_READ_sCAL_SUPPORTED
    +/* Read the sCAL chunk */
    +void /* PRIVATE */
    +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_bytep buffer;
    +   size_t i;
    +   int state;
    +
    +   png_debug(1, "in png_handle_sCAL");
    +
    +   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_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;
    +   }
    +
    +   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_chunk_benign_error(png_ptr, "invalid unit");
    +      return;
    +   }
    +
    +   /* Validate the ASCII numbers, need two ASCII numbers separated by
    +    * a '\0' and they need to fit exactly in the chunk data.
    +    */
    +   i = 1;
    +   state = 0;
    +
    +   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
    +   {
    +      size_t heighti = i;
    +
    +      state = 0;
    +      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, buffer[0],
    +             (png_charp)buffer+1, (png_charp)buffer+heighti);
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_READ_tIME_SUPPORTED
    +void /* PRIVATE */
    +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) == 0)
    +      png_chunk_error(png_ptr, "missing IHDR");
    +
    +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "duplicate");
    +      return;
    +   }
    +
    +   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    +      png_ptr->mode |= PNG_AFTER_IDAT;
    +
    +   if (length != 7)
    +   {
    +      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) != 0)
    +      return;
    +
    +   mod_time.second = buf[6];
    +   mod_time.minute = buf[5];
    +   mod_time.hour = buf[4];
    +   mod_time.day = buf[3];
    +   mod_time.month = buf[2];
    +   mod_time.year = png_get_uint_16(buf);
    +
    +   png_set_tIME(png_ptr, info_ptr, &mod_time);
    +}
    +#endif
    +
    +#ifdef PNG_READ_tEXt_SUPPORTED
    +/* Note: this does not properly handle chunks that are > 64K under DOS */
    +void /* PRIVATE */
    +png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_text  text_info;
    +   png_bytep buffer;
    +   png_charp key;
    +   png_charp text;
    +   png_uint_32 skip = 0;
    +
    +   png_debug(1, "in png_handle_tEXt");
    +
    +#ifdef PNG_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_cache_max != 0)
    +   {
    +      if (png_ptr->user_chunk_cache_max == 1)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         return;
    +      }
    +
    +      if (--png_ptr->user_chunk_cache_max == 1)
    +      {
    +         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) == 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 > 65535U)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "too large to fit in memory");
    +      return;
    +   }
    +#endif
    +
    +   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
    +
    +   if (buffer == NULL)
    +   {
    +      png_chunk_benign_error(png_ptr, "out of memory");
    +      return;
    +   }
    +
    +   png_crc_read(png_ptr, buffer, length);
    +
    +   if (png_crc_finish(png_ptr, skip) != 0)
    +      return;
    +
    +   key = (png_charp)buffer;
    +   key[length] = 0;
    +
    +   for (text = key; *text; text++)
    +      /* Empty loop to find end of key */ ;
    +
    +   if (text != key + length)
    +      text++;
    +
    +   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
    +
    +#ifdef PNG_READ_zTXt_SUPPORTED
    +/* Note: this does not correctly handle chunks that are > 64K under DOS */
    +void /* PRIVATE */
    +png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_const_charp errmsg = NULL;
    +   png_bytep       buffer;
    +   png_uint_32     keyword_length;
    +
    +   png_debug(1, "in png_handle_zTXt");
    +
    +#ifdef PNG_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_cache_max != 0)
    +   {
    +      if (png_ptr->user_chunk_cache_max == 1)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         return;
    +      }
    +
    +      if (--png_ptr->user_chunk_cache_max == 1)
    +      {
    +         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) == 0)
    +      png_chunk_error(png_ptr, "missing IHDR");
    +
    +   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    +      png_ptr->mode |= PNG_AFTER_IDAT;
    +
    +   /* Note, "length" is sufficient here; we won't be adding
    +    * a null terminator later.
    +    */
    +   buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
    +
    +   if (buffer == NULL)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "out of memory");
    +      return;
    +   }
    +
    +   png_crc_read(png_ptr, buffer, length);
    +
    +   if (png_crc_finish(png_ptr, 0) != 0)
    +      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
    +   {
    +      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;
    +
    +         if (png_ptr->read_buffer == NULL)
    +           errmsg="Read failure in png_handle_zTXt";
    +         else
    +         {
    +            /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
    +             * except for the extra compression type byte and the fact that
    +             * it isn't necessarily '\0' terminated.
    +             */
    +            buffer = png_ptr->read_buffer;
    +            buffer[uncompressed_length+(keyword_length+2)] = 0;
    +
    +            text.compression = PNG_TEXT_COMPRESSION_zTXt;
    +            text.key = (png_charp)buffer;
    +            text.text = (png_charp)(buffer + keyword_length+2);
    +            text.text_length = uncompressed_length;
    +            text.itxt_length = 0;
    +            text.lang = NULL;
    +            text.lang_key = NULL;
    +
    +            if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
    +               errmsg = "insufficient memory";
    +         }
    +      }
    +
    +      else
    +         errmsg = png_ptr->zstream.msg;
    +   }
    +
    +   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_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    +{
    +   png_const_charp errmsg = NULL;
    +   png_bytep buffer;
    +   png_uint_32 prefix_length;
    +
    +   png_debug(1, "in png_handle_iTXt");
    +
    +#ifdef PNG_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_cache_max != 0)
    +   {
    +      if (png_ptr->user_chunk_cache_max == 1)
    +      {
    +         png_crc_finish(png_ptr, length);
    +         return;
    +      }
    +
    +      if (--png_ptr->user_chunk_cache_max == 1)
    +      {
    +         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) == 0)
    +      png_chunk_error(png_ptr, "missing IHDR");
    +
    +   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    +      png_ptr->mode |= PNG_AFTER_IDAT;
    +
    +   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
    +
    +   if (buffer == NULL)
    +   {
    +      png_crc_finish(png_ptr, length);
    +      png_chunk_benign_error(png_ptr, "out of memory");
    +      return;
    +   }
    +
    +   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))
    +   {
    +      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";
    +      }
    +   }
    +
    +   else
    +      errmsg = "bad compression info";
    +
    +   if (errmsg != NULL)
    +      png_chunk_benign_error(png_ptr, errmsg);
    +}
    +#endif
    +
    +#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_alloc_size_t limit = PNG_SIZE_MAX;
    +
    +   if (png_ptr->unknown_chunk.data != NULL)
    +   {
    +      png_free(png_ptr, png_ptr->unknown_chunk.data);
    +      png_ptr->unknown_chunk.data = NULL;
    +   }
    +
    +#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_malloc_max > 0 &&
    +       png_ptr->user_chunk_malloc_max < limit)
    +      limit = png_ptr->user_chunk_malloc_max;
    +
    +#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
    +   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
    +      limit = PNG_USER_CHUNK_MALLOC_MAX;
    +#  endif
    +
    +   if (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 = (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
    +   {
    +      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 occurred; png_chunk_error will be called.
    +          *     zero: The chunk was not handled, the chunk will be discarded
    +          *           unless png_set_keep_unknown_chunks has been used to set
    +          *           a 'keep' behavior for this particular chunk, in which
    +          *           case that will be used.  A critical chunk will cause an
    +          *           error at this point unless it is to be saved.
    +          * positive: The chunk was handled, libpng will ignore/discard it.
    +          */
    +         if (ret < 0)
    +            png_chunk_error(png_ptr, "error in user chunk");
    +
    +         else if (ret == 0)
    +         {
    +            /* 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");
    +            /* FALLTHROUGH */
    +         case 1:
    +            /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
    +             * chunk being skipped, now there will be a hard error below.
    +             */
    +            break;
    +
    +         default: /* not at limit */
    +            --(png_ptr->user_chunk_cache_max);
    +            /* FALLTHROUGH */
    +         case 0: /* no limit */
    +#  endif /* USER_LIMITS */
    +            /* Here when the limit isn't reached or when limits are compiled
    +             * out; store the chunk.
    +             */
    +            png_set_unknown_chunks(png_ptr, info_ptr,
    +                &png_ptr->unknown_chunk, 1);
    +            handled = 1;
    +#  ifdef PNG_USER_LIMITS_SUPPORTED
    +            break;
    +      }
    +#  endif
    +   }
    +#  else /* no store support: the chunk must be handled by the user callback */
    +   PNG_UNUSED(info_ptr)
    +#  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.
    + * This function can't have the "critical chunk check" incorporated
    + * into it, since in the future we will need to be able to call user
    + * functions to handle unknown critical chunks after we check that
    + * the chunk name itself is valid.
    + */
    +
    +/* 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_const_structrp png_ptr, png_uint_32 chunk_name)
    +{
    +   int i;
    +   png_uint_32 cn=chunk_name;
    +
    +   png_debug(1, "in png_check_chunk_name");
    +
    +   for (i=1; i<=4; ++i)
    +   {
    +      int c = cn & 0xff;
    +
    +      if (c < 65 || c > 122 || (c > 90 && c < 97))
    +         png_chunk_error(png_ptr, "invalid chunk type");
    +
    +      cn >>= 8;
    +   }
    +}
    +
    +void /* PRIVATE */
    +png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length)
    +{
    +   png_alloc_size_t limit = PNG_UINT_31_MAX;
    +
    +# ifdef PNG_SET_USER_LIMITS_SUPPORTED
    +   if (png_ptr->user_chunk_malloc_max > 0 &&
    +       png_ptr->user_chunk_malloc_max < limit)
    +      limit = png_ptr->user_chunk_malloc_max;
    +# elif PNG_USER_CHUNK_MALLOC_MAX > 0
    +   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
    +      limit = PNG_USER_CHUNK_MALLOC_MAX;
    +# endif
    +   if (png_ptr->chunk_name == png_IDAT)
    +   {
    +      png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
    +      size_t row_factor =
    +         (size_t)png_ptr->width
    +         * (size_t)png_ptr->channels
    +         * (png_ptr->bit_depth > 8? 2: 1)
    +         + 1
    +         + (png_ptr->interlaced? 6: 0);
    +      if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
    +         idat_limit = PNG_UINT_31_MAX;
    +      else
    +         idat_limit = png_ptr->height * row_factor;
    +      row_factor = row_factor > 32566? 32566 : row_factor;
    +      idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
    +      idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
    +      limit = limit < idat_limit? idat_limit : limit;
    +   }
    +
    +   if (length > limit)
    +   {
    +      png_debug2(0," length = %lu, limit = %lu",
    +         (unsigned long)length,(unsigned long)limit);
    +      png_chunk_error(png_ptr, "chunk data is too large");
    +   }
    +}
    +
    +/* 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_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.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(pixel_depth, row_width))
    +      png_error(png_ptr, "internal row size calculation error");
    +
    +   /* 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)
    +   {
    +      /* 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 = (unsigned int)(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 */
    +   }
    +
    +   /* 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)))
    +   {
    +      /* 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)
    +      {
    +         /* 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 const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
    +         {
    +            /* 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 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 */
    +            {
    +               if (m != 0xff)
    +                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
    +               else
    +                  *dp = *sp;
    +            }
    +
    +            /* 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) &&
    +                      png_isaligned(sp, png_uint_32) &&
    +                      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_row_infop row_info, png_bytep row, int pass,
    +    png_uint_32 transformations /* Because these may affect the byte layout */)
    +{
    +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    +   /* Offset to next interlace block */
    +   static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    +
    +   png_debug(1, "in png_do_read_interlace");
    +   if (row != NULL && row_info != NULL)
    +   {
    +      png_uint_32 final_width;
    +
    +      final_width = row_info->width * png_pass_inc[pass];
    +
    +      switch (row_info->pixel_depth)
    +      {
    +         case 1:
    +         {
    +            png_bytep sp = row + (size_t)((row_info->width - 1) >> 3);
    +            png_bytep dp = row + (size_t)((final_width - 1) >> 3);
    +            unsigned int sshift, dshift;
    +            unsigned int s_start, s_end;
    +            int s_inc;
    +            int jstop = (int)png_pass_inc[pass];
    +            png_byte v;
    +            png_uint_32 i;
    +            int j;
    +
    +#ifdef PNG_READ_PACKSWAP_SUPPORTED
    +            if ((transformations & PNG_PACKSWAP) != 0)
    +            {
    +                sshift = ((row_info->width + 7) & 0x07);
    +                dshift = ((final_width + 7) & 0x07);
    +                s_start = 7;
    +                s_end = 0;
    +                s_inc = -1;
    +            }
    +
    +            else
    +#endif
    +            {
    +                sshift = 7 - ((row_info->width + 7) & 0x07);
    +                dshift = 7 - ((final_width + 7) & 0x07);
    +                s_start = 0;
    +                s_end = 7;
    +                s_inc = 1;
    +            }
    +
    +            for (i = 0; i < row_info->width; i++)
    +            {
    +               v = (png_byte)((*sp >> sshift) & 0x01);
    +               for (j = 0; j < jstop; j++)
    +               {
    +                  unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
    +                  tmp |= (unsigned int)(v << dshift);
    +                  *dp = (png_byte)(tmp & 0xff);
    +
    +                  if (dshift == s_end)
    +                  {
    +                     dshift = s_start;
    +                     dp--;
    +                  }
    +
    +                  else
    +                     dshift = (unsigned int)((int)dshift + s_inc);
    +               }
    +
    +               if (sshift == s_end)
    +               {
    +                  sshift = s_start;
    +                  sp--;
    +               }
    +
    +               else
    +                  sshift = (unsigned int)((int)sshift + s_inc);
    +            }
    +            break;
    +         }
    +
    +         case 2:
    +         {
    +            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
    +            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
    +            unsigned int sshift, dshift;
    +            unsigned int s_start, s_end;
    +            int s_inc;
    +            int jstop = (int)png_pass_inc[pass];
    +            png_uint_32 i;
    +
    +#ifdef PNG_READ_PACKSWAP_SUPPORTED
    +            if ((transformations & PNG_PACKSWAP) != 0)
    +            {
    +               sshift = (((row_info->width + 3) & 0x03) << 1);
    +               dshift = (((final_width + 3) & 0x03) << 1);
    +               s_start = 6;
    +               s_end = 0;
    +               s_inc = -2;
    +            }
    +
    +            else
    +#endif
    +            {
    +               sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
    +               dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
    +               s_start = 0;
    +               s_end = 6;
    +               s_inc = 2;
    +            }
    +
    +            for (i = 0; i < row_info->width; i++)
    +            {
    +               png_byte v;
    +               int j;
    +
    +               v = (png_byte)((*sp >> sshift) & 0x03);
    +               for (j = 0; j < jstop; j++)
    +               {
    +                  unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
    +                  tmp |= (unsigned int)(v << dshift);
    +                  *dp = (png_byte)(tmp & 0xff);
    +
    +                  if (dshift == s_end)
    +                  {
    +                     dshift = s_start;
    +                     dp--;
    +                  }
    +
    +                  else
    +                     dshift = (unsigned int)((int)dshift + s_inc);
    +               }
    +
    +               if (sshift == s_end)
    +               {
    +                  sshift = s_start;
    +                  sp--;
    +               }
    +
    +               else
    +                  sshift = (unsigned int)((int)sshift + s_inc);
    +            }
    +            break;
    +         }
    +
    +         case 4:
    +         {
    +            png_bytep sp = row + (size_t)((row_info->width - 1) >> 1);
    +            png_bytep dp = row + (size_t)((final_width - 1) >> 1);
    +            unsigned int sshift, dshift;
    +            unsigned int s_start, s_end;
    +            int s_inc;
    +            png_uint_32 i;
    +            int jstop = (int)png_pass_inc[pass];
    +
    +#ifdef PNG_READ_PACKSWAP_SUPPORTED
    +            if ((transformations & PNG_PACKSWAP) != 0)
    +            {
    +               sshift = (((row_info->width + 1) & 0x01) << 2);
    +               dshift = (((final_width + 1) & 0x01) << 2);
    +               s_start = 4;
    +               s_end = 0;
    +               s_inc = -4;
    +            }
    +
    +            else
    +#endif
    +            {
    +               sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
    +               dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
    +               s_start = 0;
    +               s_end = 4;
    +               s_inc = 4;
    +            }
    +
    +            for (i = 0; i < row_info->width; i++)
    +            {
    +               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
    +               int j;
    +
    +               for (j = 0; j < jstop; j++)
    +               {
    +                  unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
    +                  tmp |= (unsigned int)(v << dshift);
    +                  *dp = (png_byte)(tmp & 0xff);
    +
    +                  if (dshift == s_end)
    +                  {
    +                     dshift = s_start;
    +                     dp--;
    +                  }
    +
    +                  else
    +                     dshift = (unsigned int)((int)dshift + s_inc);
    +               }
    +
    +               if (sshift == s_end)
    +               {
    +                  sshift = s_start;
    +                  sp--;
    +               }
    +
    +               else
    +                  sshift = (unsigned int)((int)sshift + s_inc);
    +            }
    +            break;
    +         }
    +
    +         default:
    +         {
    +            size_t pixel_bytes = (row_info->pixel_depth >> 3);
    +
    +            png_bytep sp = row + (size_t)(row_info->width - 1)
    +                * pixel_bytes;
    +
    +            png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes;
    +
    +            int jstop = (int)png_pass_inc[pass];
    +            png_uint_32 i;
    +
    +            for (i = 0; i < row_info->width; i++)
    +            {
    +               png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
    +               int j;
    +
    +               memcpy(v, sp, pixel_bytes);
    +
    +               for (j = 0; j < jstop; j++)
    +               {
    +                  memcpy(dp, v, pixel_bytes);
    +                  dp -= pixel_bytes;
    +               }
    +
    +               sp -= pixel_bytes;
    +            }
    +            break;
    +         }
    +      }
    +
    +      row_info->width = final_width;
    +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
    +   }
    +#ifndef PNG_READ_PACKSWAP_SUPPORTED
    +   PNG_UNUSED(transformations)  /* Silence compiler warning */
    +#endif
    +}
    +#endif /* READ_INTERLACING */
    +
    +static void
    +png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
    +    png_const_bytep prev_row)
    +{
    +   size_t i;
    +   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)
    +{
    +   size_t i;
    +   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)
    +{
    +   size_t i;
    +   png_bytep rp = row;
    +   png_const_bytep pp = prev_row;
    +   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    +   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)
    +{
    +   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    +   png_bytep rp_end = row + bpp;
    +
    +   /* Process the first pixel in the row completely (this is the same as 'up'
    +    * 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 = 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_structrp pp, png_row_infop row_info, png_bytep row,
    +    png_const_bytep prev_row, int filter)
    +{
    +   /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
    +    * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
    +    * implementations.  See png_init_filter_functions above.
    +    */
    +   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
    +   {
    +      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)
    +      {
    +         uInt avail_in;
    +         png_bytep buffer;
    +
    +         while (png_ptr->idat_size == 0)
    +         {
    +            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 = PNG_INFLATE(png_ptr, 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;
    +      }
    +
    +      if (ret != Z_OK)
    +      {
    +         png_zstream_error(png_ptr, ret);
    +
    +         if (output != NULL)
    +            png_chunk_error(png_ptr, png_ptr->zstream.msg);
    +
    +         else /* checking */
    +         {
    +            png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
    +            return;
    +         }
    +      }
    +   } 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");
    +   }
    +}
    +
    +void /* PRIVATE */
    +png_read_finish_IDAT(png_structrp png_ptr)
    +{
    +   /* 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 */
    +   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
    +
    +   /* Offset to next interlace block */
    +   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    +
    +   /* Start of interlace block in the y direction */
    +   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
    +
    +   /* Offset to next interlace block in the y direction */
    +   static 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;
    +
    +   if (png_ptr->interlaced != 0)
    +   {
    +      png_ptr->row_number = 0;
    +
    +      /* 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
    +      {
    +         png_ptr->pass++;
    +
    +         if (png_ptr->pass >= 7)
    +            break;
    +
    +         png_ptr->iwidth = (png_ptr->width +
    +            png_pass_inc[png_ptr->pass] - 1 -
    +            png_pass_start[png_ptr->pass]) /
    +            png_pass_inc[png_ptr->pass];
    +
    +         if ((png_ptr->transformations & PNG_INTERLACE) == 0)
    +         {
    +            png_ptr->num_rows = (png_ptr->height +
    +                png_pass_yinc[png_ptr->pass] - 1 -
    +                png_pass_ystart[png_ptr->pass]) /
    +                png_pass_yinc[png_ptr->pass];
    +         }
    +
    +         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
    +            break; /* libpng deinterlacing sees every row */
    +
    +      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
    +
    +      if (png_ptr->pass < 7)
    +         return;
    +   }
    +
    +   /* Here after at the end of the last row of the last pass. */
    +   png_read_finish_IDAT(png_ptr);
    +}
    +#endif /* SEQUENTIAL_READ */
    +
    +void /* PRIVATE */
    +png_read_start_row(png_structrp png_ptr)
    +{
    +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    +
    +   /* Start of interlace block */
    +   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
    +
    +   /* Offset to next interlace block */
    +   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    +
    +   /* Start of interlace block in the y direction */
    +   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
    +
    +   /* Offset to next interlace block in the y direction */
    +   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
    +
    +   unsigned int max_pixel_depth;
    +   size_t row_bytes;
    +
    +   png_debug(1, "in png_read_start_row");
    +
    +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
    +   png_init_read_transformations(png_ptr);
    +#endif
    +   if (png_ptr->interlaced != 0)
    +   {
    +      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];
    +
    +      else
    +         png_ptr->num_rows = png_ptr->height;
    +
    +      png_ptr->iwidth = (png_ptr->width +
    +          png_pass_inc[png_ptr->pass] - 1 -
    +          png_pass_start[png_ptr->pass]) /
    +          png_pass_inc[png_ptr->pass];
    +   }
    +
    +   else
    +   {
    +      png_ptr->num_rows = png_ptr->height;
    +      png_ptr->iwidth = png_ptr->width;
    +   }
    +
    +   max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
    +
    +   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
    +    * calculations to calculate the final pixel depth, then
    +    * 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) != 0 && png_ptr->bit_depth < 8)
    +      max_pixel_depth = 8;
    +#endif
    +
    +#ifdef PNG_READ_EXPAND_SUPPORTED
    +   if ((png_ptr->transformations & PNG_EXPAND) != 0)
    +   {
    +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      {
    +         if (png_ptr->num_trans != 0)
    +            max_pixel_depth = 32;
    +
    +         else
    +            max_pixel_depth = 24;
    +      }
    +
    +      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    +      {
    +         if (max_pixel_depth < 8)
    +            max_pixel_depth = 8;
    +
    +         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 != 0)
    +         {
    +            max_pixel_depth *= 4;
    +            max_pixel_depth /= 3;
    +         }
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_READ_EXPAND_16_SUPPORTED
    +   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
    +   {
    +#  ifdef PNG_READ_EXPAND_SUPPORTED
    +      /* In fact it is an error if it isn't supported, but checking is
    +       * the safe way.
    +       */
    +      if ((png_ptr->transformations & PNG_EXPAND) != 0)
    +      {
    +         if (png_ptr->bit_depth < 16)
    +            max_pixel_depth *= 2;
    +      }
    +      else
    +#  endif
    +      png_ptr->transformations &= ~PNG_EXPAND_16;
    +   }
    +#endif
    +
    +#ifdef PNG_READ_FILLER_SUPPORTED
    +   if ((png_ptr->transformations & (PNG_FILLER)) != 0)
    +   {
    +      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    +      {
    +         if (max_pixel_depth <= 8)
    +            max_pixel_depth = 16;
    +
    +         else
    +            max_pixel_depth = 32;
    +      }
    +
    +      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;
    +
    +         else
    +            max_pixel_depth = 64;
    +      }
    +   }
    +#endif
    +
    +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    +   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
    +   {
    +      if (
    +#ifdef PNG_READ_EXPAND_SUPPORTED
    +          (png_ptr->num_trans != 0 &&
    +          (png_ptr->transformations & PNG_EXPAND) != 0) ||
    +#endif
    +#ifdef PNG_READ_FILLER_SUPPORTED
    +          (png_ptr->transformations & (PNG_FILLER)) != 0 ||
    +#endif
    +          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    +      {
    +         if (max_pixel_depth <= 16)
    +            max_pixel_depth = 32;
    +
    +         else
    +            max_pixel_depth = 64;
    +      }
    +
    +      else
    +      {
    +         if (max_pixel_depth <= 8)
    +         {
    +            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +               max_pixel_depth = 32;
    +
    +            else
    +               max_pixel_depth = 24;
    +         }
    +
    +         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +            max_pixel_depth = 64;
    +
    +         else
    +            max_pixel_depth = 48;
    +      }
    +   }
    +#endif
    +
    +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
    +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
    +   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
    +   {
    +      unsigned 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;
    +   }
    +#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
    +    */
    +   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
    +   /* Calculate the maximum bytes needed, adding a byte and a pixel
    +    * for safety's sake
    +    */
    +   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
    +       1 + ((max_pixel_depth + 7) >> 3U);
    +
    +#ifdef PNG_MAX_MALLOC_64K
    +   if (row_bytes > (png_uint_32)65536L)
    +      png_error(png_ptr, "This image requires a row greater than 64KB");
    +#endif
    +
    +   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
    +   {
    +      png_free(png_ptr, png_ptr->big_row_buf);
    +      png_free(png_ptr, png_ptr->big_prev_row);
    +
    +      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->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
    +
    +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
    +      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
    +       * of padding before and after row_buf; treat prev_row similarly.
    +       * NOTE: the alignment is to the start of the pixels, one beyond the start
    +       * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
    +       * was incorrect; the filter byte was aligned, which had the exact
    +       * opposite effect of that intended.
    +       */
    +      {
    +         png_bytep temp = png_ptr->big_row_buf + 32;
    +         int extra = (int)((temp - (png_bytep)0) & 0x0f);
    +         png_ptr->row_buf = temp - extra - 1/*filter byte*/;
    +
    +         temp = png_ptr->big_prev_row + 32;
    +         extra = (int)((temp - (png_bytep)0) & 0x0f);
    +         png_ptr->prev_row = temp - extra - 1/*filter byte*/;
    +      }
    +
    +#else
    +      /* Use 31 bytes of padding before and 17 bytes after row_buf. */
    +      png_ptr->row_buf = png_ptr->big_row_buf + 31;
    +      png_ptr->prev_row = png_ptr->big_prev_row + 31;
    +#endif
    +      png_ptr->old_big_row_buf_size = row_bytes + 48;
    +   }
    +
    +#ifdef PNG_MAX_MALLOC_64K
    +   if (png_ptr->rowbytes > 65535)
    +      png_error(png_ptr, "This image requires a row greater than 64KB");
    +
    +#endif
    +   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
    +      png_error(png_ptr, "Row has too many bytes to allocate in memory");
    +
    +   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);
    +   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
    +   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
    +   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
    +   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 != NULL)
    +   {
    +      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 /* READ */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,1830 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngset.c - storage of image information into info struct
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + *
    + * The functions here are used during reads to store data from the file
    + * into the info struct, and during writes to store application data
    + * into the info struct for writing into the file.  This abstracts the
    + * info struct and allows us to change the structure in the future.
    + */
    +
    +#include "pngpriv.h"
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +
    +#ifdef PNG_bKGD_SUPPORTED
    +void PNGAPI
    +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 || background == NULL)
    +      return;
    +
    +   info_ptr->background = *background;
    +   info_ptr->valid |= PNG_INFO_bKGD;
    +}
    +#endif
    +
    +#ifdef PNG_cHRM_SUPPORTED
    +void PNGFAPI
    +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;
    +
    +   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_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_set_cHRM_fixed(png_ptr, info_ptr,
    +       png_fixed(png_ptr, white_x, "cHRM White X"),
    +       png_fixed(png_ptr, white_y, "cHRM White Y"),
    +       png_fixed(png_ptr, red_x, "cHRM Red X"),
    +       png_fixed(png_ptr, red_y, "cHRM Red Y"),
    +       png_fixed(png_ptr, green_x, "cHRM Green X"),
    +       png_fixed(png_ptr, green_y, "cHRM Green Y"),
    +       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
    +       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
    +}
    +
    +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 Green X"),
    +       png_fixed(png_ptr, green_Y, "cHRM Green Y"),
    +       png_fixed(png_ptr, green_Z, "cHRM Green Z"),
    +       png_fixed(png_ptr, blue_X, "cHRM Blue X"),
    +       png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
    +       png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
    +}
    +#  endif /* FLOATING_POINT */
    +
    +#endif /* cHRM */
    +
    +#ifdef PNG_eXIf_SUPPORTED
    +void PNGAPI
    +png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
    +    png_bytep eXIf_buf)
    +{
    +  png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
    +  PNG_UNUSED(info_ptr)
    +  PNG_UNUSED(eXIf_buf)
    +}
    +
    +void PNGAPI
    +png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
    +    png_uint_32 num_exif, png_bytep eXIf_buf)
    +{
    +   int i;
    +
    +   png_debug1(1, "in %s storage function", "eXIf");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   if (info_ptr->exif)
    +   {
    +      png_free(png_ptr, info_ptr->exif);
    +      info_ptr->exif = NULL;
    +   }
    +
    +   info_ptr->num_exif = num_exif;
    +
    +   info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
    +       info_ptr->num_exif));
    +
    +   if (info_ptr->exif == NULL)
    +   {
    +      png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
    +      return;
    +   }
    +
    +   info_ptr->free_me |= PNG_FREE_EXIF;
    +
    +   for (i = 0; i < (int) info_ptr->num_exif; i++)
    +      info_ptr->exif[i] = eXIf_buf[i];
    +
    +   info_ptr->valid |= PNG_INFO_eXIf;
    +}
    +#endif /* eXIf */
    +
    +#ifdef PNG_gAMA_SUPPORTED
    +void PNGFAPI
    +png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
    +    png_fixed_point file_gamma)
    +{
    +   png_debug1(1, "in %s storage function", "gAMA");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   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_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"));
    +}
    +#  endif
    +#endif
    +
    +#ifdef PNG_hIST_SUPPORTED
    +void PNGAPI
    +png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
    +    png_const_uint_16p hist)
    +{
    +   int i;
    +
    +   png_debug1(1, "in %s storage function", "hIST");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   if (info_ptr->num_palette == 0 || info_ptr->num_palette
    +       > PNG_MAX_PALETTE_LENGTH)
    +   {
    +      png_warning(png_ptr,
    +          "Invalid palette size, hIST allocation skipped");
    +
    +      return;
    +   }
    +
    +   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
    +
    +   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
    +    * version 1.2.1
    +    */
    +   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
    +       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
    +
    +   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++)
    +      info_ptr->hist[i] = hist[i];
    +
    +   info_ptr->valid |= PNG_INFO_hIST;
    +}
    +#endif
    +
    +void PNGAPI
    +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)
    +{
    +   png_debug1(1, "in %s storage function", "IHDR");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   info_ptr->width = width;
    +   info_ptr->height = height;
    +   info_ptr->bit_depth = (png_byte)bit_depth;
    +   info_ptr->color_type = (png_byte)color_type;
    +   info_ptr->compression_type = (png_byte)compression_type;
    +   info_ptr->filter_type = (png_byte)filter_type;
    +   info_ptr->interlace_type = (png_byte)interlace_type;
    +
    +   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);
    +
    +   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +      info_ptr->channels = 1;
    +
    +   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) != 0)
    +      info_ptr->channels++;
    +
    +   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
    +
    +   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
    +}
    +
    +#ifdef PNG_oFFs_SUPPORTED
    +void PNGAPI
    +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");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   info_ptr->x_offset = offset_x;
    +   info_ptr->y_offset = offset_y;
    +   info_ptr->offset_unit_type = (png_byte)unit_type;
    +   info_ptr->valid |= PNG_INFO_oFFs;
    +}
    +#endif
    +
    +#ifdef PNG_pCAL_SUPPORTED
    +void PNGAPI
    +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)
    +{
    +   size_t length;
    +   int i;
    +
    +   png_debug1(1, "in %s storage function", "pCAL");
    +
    +   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
    +       || (nparams > 0 && params == NULL))
    +      return;
    +
    +   length = strlen(purpose) + 1;
    +   png_debug1(3, "allocating purpose for info (%lu bytes)",
    +       (unsigned long)length);
    +
    +   /* TODO: validate format of calibration name and unit name */
    +
    +   /* Check that the type matches the specification. */
    +   if (type < 0 || type > 3)
    +   {
    +      png_chunk_report(png_ptr, "Invalid pCAL equation type",
    +            PNG_CHUNK_WRITE_ERROR);
    +      return;
    +   }
    +
    +   if (nparams < 0 || nparams > 255)
    +   {
    +      png_chunk_report(png_ptr, "Invalid pCAL parameter count",
    +            PNG_CHUNK_WRITE_ERROR);
    +      return;
    +   }
    +
    +   /* Validate params[nparams] */
    +   for (i=0; ipcal_purpose = png_voidcast(png_charp,
    +       png_malloc_warn(png_ptr, length));
    +
    +   if (info_ptr->pcal_purpose == NULL)
    +   {
    +      png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
    +            PNG_CHUNK_WRITE_ERROR);
    +      return;
    +   }
    +
    +   memcpy(info_ptr->pcal_purpose, purpose, length);
    +
    +   png_debug(3, "storing X0, X1, type, and nparams in info");
    +   info_ptr->pcal_X0 = X0;
    +   info_ptr->pcal_X1 = X1;
    +   info_ptr->pcal_type = (png_byte)type;
    +   info_ptr->pcal_nparams = (png_byte)nparams;
    +
    +   length = strlen(units) + 1;
    +   png_debug1(3, "allocating units for info (%lu bytes)",
    +       (unsigned long)length);
    +
    +   info_ptr->pcal_units = png_voidcast(png_charp,
    +       png_malloc_warn(png_ptr, length));
    +
    +   if (info_ptr->pcal_units == NULL)
    +   {
    +      png_warning(png_ptr, "Insufficient memory for pCAL units");
    +
    +      return;
    +   }
    +
    +   memcpy(info_ptr->pcal_units, units, length);
    +
    +   info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
    +       (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
    +
    +   if (info_ptr->pcal_params == NULL)
    +   {
    +      png_warning(png_ptr, "Insufficient memory for pCAL params");
    +
    +      return;
    +   }
    +
    +   memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
    +       (sizeof (png_charp)));
    +
    +   for (i = 0; i < nparams; i++)
    +   {
    +      length = strlen(params[i]) + 1;
    +      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
    +          (unsigned long)length);
    +
    +      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
    +
    +      if (info_ptr->pcal_params[i] == NULL)
    +      {
    +         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
    +
    +         return;
    +      }
    +
    +      memcpy(info_ptr->pcal_params[i], params[i], length);
    +   }
    +
    +   info_ptr->valid |= PNG_INFO_pCAL;
    +   info_ptr->free_me |= PNG_FREE_PCAL;
    +}
    +#endif
    +
    +#ifdef PNG_sCAL_SUPPORTED
    +void PNGAPI
    +png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
    +    int unit, png_const_charp swidth, png_const_charp sheight)
    +{
    +   size_t lengthw = 0, lengthh = 0;
    +
    +   png_debug1(1, "in %s storage function", "sCAL");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   /* Double check the unit (should never get here with an invalid
    +    * unit unless this is an API call.)
    +    */
    +   if (unit != 1 && unit != 2)
    +      png_error(png_ptr, "Invalid sCAL unit");
    +
    +   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 = strlen(sheight)) == 0 ||
    +       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
    +      png_error(png_ptr, "Invalid sCAL height");
    +
    +   info_ptr->scal_unit = (png_byte)unit;
    +
    +   ++lengthw;
    +
    +   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
    +
    +   info_ptr->scal_s_width = png_voidcast(png_charp,
    +       png_malloc_warn(png_ptr, lengthw));
    +
    +   if (info_ptr->scal_s_width == NULL)
    +   {
    +      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
    +
    +      return;
    +   }
    +
    +   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_voidcast(png_charp,
    +       png_malloc_warn(png_ptr, lengthh));
    +
    +   if (info_ptr->scal_s_height == NULL)
    +   {
    +      png_free (png_ptr, info_ptr->scal_s_width);
    +      info_ptr->scal_s_width = NULL;
    +
    +      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
    +
    +      return;
    +   }
    +
    +   memcpy(info_ptr->scal_s_height, sheight, lengthh);
    +
    +   info_ptr->valid |= PNG_INFO_sCAL;
    +   info_ptr->free_me |= PNG_FREE_SCAL;
    +}
    +
    +#  ifdef PNG_FLOATING_POINT_SUPPORTED
    +void PNGAPI
    +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");
    +
    +   /* Check the arguments. */
    +   if (width <= 0)
    +      png_warning(png_ptr, "Invalid sCAL width ignored");
    +
    +   else if (height <= 0)
    +      png_warning(png_ptr, "Invalid sCAL height ignored");
    +
    +   else
    +   {
    +      /* Convert 'width' and 'height' to ASCII. */
    +      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_sCAL_PRECISION);
    +      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
    +          PNG_sCAL_PRECISION);
    +
    +      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
    +   }
    +}
    +#  endif
    +
    +#  ifdef PNG_FIXED_POINT_SUPPORTED
    +void PNGAPI
    +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");
    +
    +   /* Check the arguments. */
    +   if (width <= 0)
    +      png_warning(png_ptr, "Invalid sCAL width ignored");
    +
    +   else if (height <= 0)
    +      png_warning(png_ptr, "Invalid sCAL height ignored");
    +
    +   else
    +   {
    +      /* Convert 'width' and 'height' to ASCII. */
    +      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_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
    +   }
    +}
    +#  endif
    +#endif
    +
    +#ifdef PNG_pHYs_SUPPORTED
    +void PNGAPI
    +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");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   info_ptr->x_pixels_per_unit = res_x;
    +   info_ptr->y_pixels_per_unit = res_y;
    +   info_ptr->phys_unit_type = (png_byte)unit_type;
    +   info_ptr->valid |= PNG_INFO_pHYs;
    +}
    +#endif
    +
    +void PNGAPI
    +png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
    +    png_const_colorp palette, int num_palette)
    +{
    +
    +   png_uint_32 max_palette_length;
    +
    +   png_debug1(1, "in %s storage function", "PLTE");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
    +      (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
    +
    +   if (num_palette < 0 || num_palette > (int) max_palette_length)
    +   {
    +      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    +         png_error(png_ptr, "Invalid palette length");
    +
    +      else
    +      {
    +         png_warning(png_ptr, "Invalid palette length");
    +
    +         return;
    +      }
    +   }
    +
    +   if ((num_palette > 0 && palette == NULL) ||
    +      (num_palette == 0
    +#        ifdef PNG_MNG_FEATURES_SUPPORTED
    +            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
    +#        endif
    +      ))
    +   {
    +      png_error(png_ptr, "Invalid palette");
    +   }
    +
    +   /* 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);
    +
    +   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
    +    * of num_palette entries, in case of an invalid PNG file or incorrect
    +    * call to png_set_PLTE() with too-large sample values.
    +    */
    +   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
    +       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
    +
    +   if (num_palette > 0)
    +      memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
    +          (sizeof (png_color)));
    +   info_ptr->palette = png_ptr->palette;
    +   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
    +
    +   info_ptr->free_me |= PNG_FREE_PLTE;
    +
    +   info_ptr->valid |= PNG_INFO_PLTE;
    +}
    +
    +#ifdef PNG_sBIT_SUPPORTED
    +void PNGAPI
    +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 || sig_bit == NULL)
    +      return;
    +
    +   info_ptr->sig_bit = *sig_bit;
    +   info_ptr->valid |= PNG_INFO_sBIT;
    +}
    +#endif
    +
    +#ifdef PNG_sRGB_SUPPORTED
    +void PNGAPI
    +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;
    +
    +   (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_const_structrp png_ptr, png_inforp info_ptr,
    +    int srgb_intent)
    +{
    +   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +      return;
    +
    +   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;
    +   }
    +
    +   png_colorspace_sync_info(png_ptr, info_ptr);
    +}
    +#endif /* sRGB */
    +
    +
    +#ifdef PNG_iCCP_SUPPORTED
    +void PNGAPI
    +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;
    +   size_t length;
    +
    +   png_debug1(1, "in %s storage function", "iCCP");
    +
    +   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
    +      return;
    +
    +   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_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
    +
    +      return;
    +   }
    +
    +   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_benign_error(png_ptr,
    +          "Insufficient memory to process iCCP profile");
    +
    +      return;
    +   }
    +
    +   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;
    +   info_ptr->free_me |= PNG_FREE_ICCP;
    +   info_ptr->valid |= PNG_INFO_iCCP;
    +}
    +#endif
    +
    +#ifdef PNG_TEXT_SUPPORTED
    +void PNGAPI
    +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 != 0)
    +      png_error(png_ptr, "Insufficient memory to store text");
    +}
    +
    +int /* PRIVATE */
    +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 %lx storage function", png_ptr == NULL ? 0xabadca11U :
    +      (unsigned long)png_ptr->chunk_name);
    +
    +   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
    +      return(0);
    +
    +   /* Make sure we have enough space in the "text" array in info_struct
    +    * 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 (num_text > info_ptr->max_text - info_ptr->num_text)
    +   {
    +      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)
    +      {
    +         max_text += num_text;
    +
    +         /* Round up to a multiple of 8 */
    +         if (max_text < INT_MAX-8)
    +            max_text = (max_text + 8) & ~0x7;
    +
    +         else
    +            max_text = INT_MAX;
    +
    +         /* 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));
    +      }
    +
    +      if (new_text == NULL)
    +      {
    +         png_chunk_report(png_ptr, "too many text chunks",
    +             PNG_CHUNK_WRITE_ERROR);
    +
    +         return 1;
    +      }
    +
    +      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++)
    +   {
    +      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)
    +          continue;
    +
    +      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
    +          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
    +      {
    +         png_chunk_report(png_ptr, "text compression mode is out of range",
    +             PNG_CHUNK_WRITE_ERROR);
    +         continue;
    +      }
    +
    +      key_len = strlen(text_ptr[i].key);
    +
    +      if (text_ptr[i].compression <= 0)
    +      {
    +         lang_len = 0;
    +         lang_key_len = 0;
    +      }
    +
    +      else
    +#  ifdef PNG_iTXt_SUPPORTED
    +      {
    +         /* Set iTXt data */
    +
    +         if (text_ptr[i].lang != NULL)
    +            lang_len = strlen(text_ptr[i].lang);
    +
    +         else
    +            lang_len = 0;
    +
    +         if (text_ptr[i].lang_key != NULL)
    +            lang_key_len = strlen(text_ptr[i].lang_key);
    +
    +         else
    +            lang_key_len = 0;
    +      }
    +#  else /* iTXt */
    +      {
    +         png_chunk_report(png_ptr, "iTXt chunk not supported",
    +             PNG_CHUNK_WRITE_ERROR);
    +         continue;
    +      }
    +#  endif
    +
    +      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
    +      {
    +         text_length = 0;
    +#  ifdef PNG_iTXt_SUPPORTED
    +         if (text_ptr[i].compression > 0)
    +            textp->compression = PNG_ITXT_COMPRESSION_NONE;
    +
    +         else
    +#  endif
    +            textp->compression = PNG_TEXT_COMPRESSION_NONE;
    +      }
    +
    +      else
    +      {
    +         text_length = strlen(text_ptr[i].text);
    +         textp->compression = text_ptr[i].compression;
    +      }
    +
    +      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)
    +      {
    +         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);
    +
    +      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;
    +         memcpy(textp->lang, text_ptr[i].lang, lang_len);
    +         *(textp->lang + lang_len) = '\0';
    +         textp->lang_key = textp->lang + lang_len + 1;
    +         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;
    +      }
    +
    +      else
    +      {
    +         textp->lang=NULL;
    +         textp->lang_key=NULL;
    +         textp->text = textp->key + key_len + 1;
    +      }
    +
    +      if (text_length != 0)
    +         memcpy(textp->text, text_ptr[i].text, text_length);
    +
    +      *(textp->text + text_length) = '\0';
    +
    +#  ifdef PNG_iTXt_SUPPORTED
    +      if (textp->compression > 0)
    +      {
    +         textp->text_length = 0;
    +         textp->itxt_length = text_length;
    +      }
    +
    +      else
    +#  endif
    +      {
    +         textp->text_length = text_length;
    +         textp->itxt_length = 0;
    +      }
    +
    +      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_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 || mod_time == NULL ||
    +       (png_ptr->mode & PNG_WROTE_tIME) != 0)
    +      return;
    +
    +   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_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");
    +
    +   if (png_ptr == NULL || info_ptr == NULL)
    +
    +      return;
    +
    +   if (trans_alpha != NULL)
    +   {
    +       /* 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);
    +
    +       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
    +       {
    +         /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
    +          info_ptr->trans_alpha = png_voidcast(png_bytep,
    +              png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
    +          memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
    +       }
    +       png_ptr->trans_alpha = info_ptr->trans_alpha;
    +   }
    +
    +   if (trans_color != NULL)
    +   {
    +#ifdef PNG_WARNINGS_SUPPORTED
    +      if (info_ptr->bit_depth < 16)
    +      {
    +         int sample_max = (1 << info_ptr->bit_depth) - 1;
    +
    +         if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
    +             trans_color->gray > sample_max) ||
    +             (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
    +             (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");
    +      }
    +#endif
    +
    +      info_ptr->trans_color = *trans_color;
    +
    +      if (num_trans == 0)
    +         num_trans = 1;
    +   }
    +
    +   info_ptr->num_trans = (png_uint_16)num_trans;
    +
    +   if (num_trans != 0)
    +   {
    +      info_ptr->valid |= PNG_INFO_tRNS;
    +      info_ptr->free_me |= PNG_FREE_TRNS;
    +   }
    +}
    +#endif
    +
    +#ifdef PNG_sPLT_SUPPORTED
    +void PNGAPI
    +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
    + *                   in the info structure.
    + *
    + *  nentries       - number of palette structures to be
    + *                   added.
    + */
    +{
    +   png_sPLT_tp np;
    +
    +   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
    +      return;
    +
    +   /* 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)
    +   {
    +      /* Out of memory or too many chunks */
    +      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
    +
    +      return;
    +   }
    +
    +   png_free(png_ptr, info_ptr->splt_palettes);
    +   info_ptr->splt_palettes = np;
    +   info_ptr->free_me |= PNG_FREE_SPLT;
    +
    +   np += info_ptr->splt_palettes_num;
    +
    +   do
    +   {
    +      size_t length;
    +
    +      /* Skip invalid input entries */
    +      if (entries->name == NULL || entries->entries == NULL)
    +      {
    +         /* 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;
    +      }
    +
    +      np->depth = entries->depth;
    +
    +      /* 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_free(png_ptr, np->name);
    +         np->name = NULL;
    +         break;
    +      }
    +
    +      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,
    +          (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
    +
    +      /* Note that 'continue' skips the advance of the out pointer and out
    +       * count, so an invalid entry is not added.
    +       */
    +      info_ptr->valid |= PNG_INFO_sPLT;
    +      ++(info_ptr->splt_palettes_num);
    +      ++np;
    +      ++entries;
    +   }
    +   while (--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));
    +   }
    +
    +   /* 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;
    +}
    +
    +void PNGAPI
    +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;
    +
    +   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
    +       unknowns == NULL)
    +      return;
    +
    +   /* 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_chunk_report(png_ptr, "too many unknown chunks",
    +          PNG_CHUNK_WRITE_ERROR);
    +
    +      return;
    +   }
    +
    +   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;
    +
    +   np += info_ptr->unknown_chunks_num;
    +
    +   /* Increment unknown_chunks_num each time round the loop to protect the
    +    * just-allocated chunk data.
    +    */
    +   for (; num_unknowns > 0; --num_unknowns, ++unknowns)
    +   {
    +      memcpy(np->name, unknowns->name, (sizeof np->name));
    +      np->name[(sizeof np->name)-1] = '\0';
    +      np->location = check_location(png_ptr, unknowns->location);
    +
    +      if (unknowns->size == 0)
    +      {
    +         np->data = NULL;
    +         np->size = 0;
    +      }
    +
    +      else
    +      {
    +         np->data = png_voidcast(png_bytep,
    +             png_malloc_base(png_ptr, unknowns->size));
    +
    +         if (np->data == NULL)
    +         {
    +            png_chunk_report(png_ptr, "unknown chunk: out of memory",
    +                PNG_CHUNK_WRITE_ERROR);
    +            /* But just skip storing the unknown chunk */
    +            continue;
    +         }
    +
    +         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);
    +   }
    +}
    +
    +void PNGAPI
    +png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
    +    int chunk, int 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 (((unsigned int)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 /* STORE_UNKNOWN_CHUNKS */
    +
    +#ifdef PNG_MNG_FEATURES_SUPPORTED
    +png_uint_32 PNGAPI
    +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 0;
    +
    +   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
    +
    +   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= PNG_HANDLE_CHUNK_LAST)
    +   {
    +      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
    +
    +      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 const png_byte chunks_to_ignore[] = {
    +         98,  75,  71,  68, '\0',  /* bKGD */
    +         99,  72,  82,  77, '\0',  /* cHRM */
    +        101,  88,  73, 102, '\0',  /* eXIf */
    +        103,  65,  77,  65, '\0',  /* gAMA */
    +        104,  73,  83,  84, '\0',  /* hIST */
    +        105,  67,  67,  80, '\0',  /* iCCP */
    +        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 = (unsigned int)num_chunks_in;
    +   }
    +
    +   old_num_chunks = png_ptr->num_chunk_list;
    +   if (png_ptr->chunk_list == NULL)
    +      old_num_chunks = 0;
    +
    +   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
    +    */
    +   if (num_chunks + old_num_chunks > UINT_MAX/5)
    +   {
    +      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
    +
    +      return;
    +   }
    +
    +   /* 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)));
    +
    +      if (old_num_chunks > 0)
    +         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
    +   }
    +
    +   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; ichunk_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_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");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
    +   png_ptr->user_chunk_ptr = user_chunk_ptr;
    +}
    +#endif
    +
    +#ifdef PNG_INFO_IMAGE_SUPPORTED
    +void PNGAPI
    +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 != 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 != NULL)
    +      info_ptr->valid |= PNG_INFO_IDAT;
    +}
    +#endif
    +
    +void PNGAPI
    +png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
    +{
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (size == 0 || size > PNG_UINT_31_MAX)
    +      png_error(png_ptr, "invalid compression buffer size");
    +
    +#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    +   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
    +   {
    +      png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
    +      return;
    +   }
    +#  endif
    +
    +#  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;
    +      }
    +
    +#ifndef __COVERITY__
    +      /* Some compilers complain that this is always false.  However, it
    +       * can be true when integer overflow happens.
    +       */
    +      if (size > ZLIB_IO_MAX)
    +      {
    +         png_warning(png_ptr,
    +             "Compression buffer size limited to system maximum");
    +         size = ZLIB_IO_MAX; /* must fit */
    +      }
    +#endif
    +
    +      if (size < 6)
    +      {
    +         /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
    +          * if this is permitted.
    +          */
    +         png_warning(png_ptr,
    +             "Compression buffer size cannot be reduced below 6");
    +
    +         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_const_structrp png_ptr, png_inforp info_ptr, int mask)
    +{
    +   if (png_ptr != NULL && info_ptr != NULL)
    +      info_ptr->valid &= (unsigned int)(~mask);
    +}
    +
    +
    +#ifdef PNG_SET_USER_LIMITS_SUPPORTED
    +/* This function was added to libpng 1.2.6 */
    +void PNGAPI
    +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
    +    * rejected by png_set_IHDR().  To accept any PNG datastream
    +    * regardless of dimensions, set both limits to 0x7fffffff.
    +    */
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->user_width_max = user_width_max;
    +   png_ptr->user_height_max = user_height_max;
    +}
    +
    +/* This function was added to libpng 1.4.0 */
    +void PNGAPI
    +png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
    +{
    +   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_structrp png_ptr,
    +    png_alloc_size_t user_chunk_malloc_max)
    +{
    +   if (png_ptr != NULL)
    +      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
    +}
    +#endif /* ?SET_USER_LIMITS */
    +
    +
    +#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    +void PNGAPI
    +png_set_benign_errors(png_structrp png_ptr, int allowed)
    +{
    +   png_debug(1, "in png_set_benign_errors");
    +
    +   /* 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_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
    +}
    +#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
    +
    +#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
    +    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
    +/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
    + * and if invalid, correct the keyword rather than discarding the entire
    + * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
    + * length, forbids leading or trailing whitespace, multiple internal spaces,
    + * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
    + *
    + * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
    + * trailing '\0').  If this routine returns 0 then there was no keyword, or a
    + * valid one could not be generated, and the caller must png_error.
    + */
    +png_uint_32 /* PRIVATE */
    +png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
    +{
    +#ifdef PNG_WARNINGS_SUPPORTED
    +   png_const_charp orig_key = key;
    +#endif
    +   png_uint_32 key_len = 0;
    +   int bad_character = 0;
    +   int space = 1;
    +
    +   png_debug(1, "in png_check_keyword");
    +
    +   if (key == NULL)
    +   {
    +      *new_key = 0;
    +      return 0;
    +   }
    +
    +   while (*key && key_len < 79)
    +   {
    +      png_byte ch = (png_byte)*key++;
    +
    +      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
    +      {
    +         *new_key++ = ch; ++key_len; space = 0;
    +      }
    +
    +      else if (space == 0)
    +      {
    +         /* A space or an invalid character when one wasn't seen immediately
    +          * before; output just a space.
    +          */
    +         *new_key++ = 32; ++key_len; space = 1;
    +
    +         /* If the character was not a space then it is invalid. */
    +         if (ch != 32)
    +            bad_character = ch;
    +      }
    +
    +      else if (bad_character == 0)
    +         bad_character = ch; /* just skip it, record the first error */
    +   }
    +
    +   if (key_len > 0 && space != 0) /* trailing space */
    +   {
    +      --key_len; --new_key;
    +      if (bad_character == 0)
    +         bad_character = 32;
    +   }
    +
    +   /* Terminate the keyword */
    +   *new_key = 0;
    +
    +   if (key_len == 0)
    +      return 0;
    +
    +#ifdef PNG_WARNINGS_SUPPORTED
    +   /* Try to only output one warning per keyword: */
    +   if (*key != 0) /* keyword too long */
    +      png_warning(png_ptr, "keyword truncated");
    +
    +   else if (bad_character != 0)
    +   {
    +      PNG_WARNING_PARAMETERS(p)
    +
    +      png_warning_parameter(p, 1, orig_key);
    +      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
    +
    +      png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
    +   }
    +#else /* !WARNINGS */
    +   PNG_UNUSED(png_ptr)
    +#endif /* !WARNINGS */
    +
    +   return key_len;
    +}
    +#endif /* TEXT || pCAL || iCCP || sPLT */
    +#endif /* READ || WRITE */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngstruct.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,517 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngstruct.h - header file for PNG reference library
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018-2019 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +/* The structure that holds the information to read and write PNG files.
    + * The only people who need to care about what is inside of this are the
    + * people who will be modifying the library for their own special needs.
    + * It should NOT be accessed directly by an application.
    + */
    +
    +#ifndef PNGSTRUCT_H
    +#define PNGSTRUCT_H
    +/* zlib.h defines the structure z_stream, an instance of which is included
    + * in this structure and is required for decompressing the LZ compressed
    + * data in PNG files.
    + */
    +#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
    + * maximum for size_t.  The value can be overridden 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 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
    +   png_error_ptr warning_fn;  /* function for printing warnings */
    +#endif
    +   png_voidp error_ptr;       /* user supplied struct for error functions */
    +   png_rw_ptr write_data_fn;  /* function for writing output data */
    +   png_rw_ptr read_data_fn;   /* function for reading input data */
    +   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
    +
    +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
    +   png_user_transform_ptr read_user_transform_fn; /* user read transform */
    +#endif
    +
    +#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
    +   png_user_transform_ptr write_user_transform_fn; /* user write transform */
    +#endif
    +
    +/* These were added in libpng-1.0.2 */
    +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
    +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
    +    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    +   png_voidp user_transform_ptr; /* user supplied struct for user transform */
    +   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
    +   png_byte user_transform_channels; /* channels in user transformed pixels */
    +#endif
    +#endif
    +
    +   png_uint_32 mode;          /* tells us where we are in the PNG file */
    +   png_uint_32 flags;         /* flags indicating various things to libpng */
    +   png_uint_32 transformations; /* which transformations to perform */
    +
    +   png_uint_32 zowner;        /* ID (chunk type) of zstream owner, 0 if none */
    +   z_stream    zstream;       /* decompression structure */
    +
    +#ifdef PNG_WRITE_SUPPORTED
    +   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 */
    +   int zlib_window_bits;      /* holds zlib compression window bits */
    +   int zlib_mem_level;        /* holds zlib compression memory level */
    +   int zlib_strategy;         /* holds zlib compression strategy */
    +#endif
    +/* Added at libpng 1.5.4 */
    +#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 */
    +   int zlib_text_mem_level;        /* holds zlib compression memory level */
    +   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 */
    +   png_uint_32 num_rows;      /* number of rows in current pass */
    +   png_uint_32 usr_width;     /* width of row at start of write */
    +   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_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
    +   png_bytep prev_row;        /* buffer to save previous (unfiltered) row.
    +                               * While reading this is a pointer into
    +                               * big_prev_row; while writing it is separately
    +                               * allocated if needed.
    +                               */
    +   png_bytep row_buf;         /* buffer to save current (unfiltered) row.
    +                               * While reading, this is a pointer into
    +                               * big_row_buf; while writing it is separately
    +                               * allocated.
    +                               */
    +#ifdef PNG_WRITE_FILTER_SUPPORTED
    +   png_bytep try_row;    /* buffer to save trial row when filtering */
    +   png_bytep tst_row;    /* buffer to save best trial row when filtering */
    +#endif
    +   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 compression;      /* file compression type (always 0) */
    +   png_byte filter;           /* file filter type (always 0) */
    +   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
    +   png_byte pass;             /* current interlace pass (0 - 6) */
    +   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ in png.h ) */
    +   png_byte color_type;       /* color type of file */
    +   png_byte bit_depth;        /* bit depth of file */
    +   png_byte usr_bit_depth;    /* bit depth of users row: write only */
    +   png_byte pixel_depth;      /* number of bits per pixel */
    +   png_byte channels;         /* number of channels in file */
    +#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 ZLIB_VERNUM >= 0x1240
    +   png_byte zstream_start;    /* at start of an input zlib stream */
    +#endif /* Zlib >= 1.2.4 */
    +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
    +   png_uint_16 filler;           /* filler bytes for pixel expansion */
    +#endif
    +
    +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
    +   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
    +   png_byte background_gamma_type;
    +   png_fixed_point background_gamma;
    +   png_color_16 background;   /* background color in screen gamma space */
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +   png_color_16 background_1; /* background normalized to gamma 1.0 */
    +#endif
    +#endif /* bKGD */
    +
    +#ifdef PNG_WRITE_FLUSH_SUPPORTED
    +   png_flush_ptr output_flush_fn; /* Function for flushing output */
    +   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
    +   png_uint_32 flush_rows;    /* number of rows written since last flush */
    +#endif
    +
    +#ifdef PNG_READ_GAMMA_SUPPORTED
    +   int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
    +   png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
    +
    +   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_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)
    +   png_color_8 sig_bit;       /* significant bits in each available channel */
    +#endif
    +
    +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
    +   png_color_8 shift;         /* shift for significant bit transformation */
    +#endif
    +
    +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
    + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    +   png_bytep trans_alpha;           /* alpha values for paletted files */
    +   png_color_16 trans_color;  /* transparent color for non-paletted files */
    +#endif
    +
    +   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
    +   png_write_status_ptr write_row_fn; /* called after each row is encoded */
    +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    +   png_progressive_info_ptr info_fn; /* called after header data fully read */
    +   png_progressive_row_ptr row_fn;   /* called after a prog. row is decoded */
    +   png_progressive_end_ptr end_fn;   /* called after image is complete */
    +   png_bytep save_buffer_ptr;        /* current location in save_buffer */
    +   png_bytep save_buffer;            /* buffer for previously read data */
    +   png_bytep current_buffer_ptr;     /* current location in current_buffer */
    +   png_bytep current_buffer;         /* buffer for recently used data */
    +   png_uint_32 push_length;          /* size of current input chunk */
    +   png_uint_32 skip_length;          /* bytes to skip in input data */
    +   size_t save_buffer_size;          /* amount of data now in save_buffer */
    +   size_t save_buffer_max;           /* total size of save_buffer */
    +   size_t buffer_size;               /* total amount of available input data */
    +   size_t current_buffer_size;       /* amount of data now in current_buffer */
    +   int process_mode;                 /* what push library is currently doing */
    +   int cur_palette;                  /* current push library palette index */
    +
    +#endif /* PROGRESSIVE_READ */
    +
    +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
    +/* For the Borland special 64K segment handler */
    +   png_bytepp offset_table_ptr;
    +   png_bytep offset_table;
    +   png_uint_16 offset_table_number;
    +   png_uint_16 offset_table_count;
    +   png_uint_16 offset_table_count_free;
    +#endif
    +
    +#ifdef PNG_READ_QUANTIZE_SUPPORTED
    +   png_bytep palette_lookup; /* lookup table for quantizing */
    +   png_bytep quantize_index; /* index translation for palette files */
    +#endif
    +
    +/* Options */
    +#ifdef PNG_SET_OPTION_SUPPORTED
    +   png_uint_32 options;           /* On/off state (up to 16 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 */
    +
    +   png_uint_32 free_me;    /* flags items libpng is responsible for freeing */
    +
    +#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_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;
    +   /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
    +#endif
    +
    +/* New member added in libpng-1.6.36 */
    +#if defined(PNG_READ_EXPAND_SUPPORTED) && \
    +    defined(PNG_ARM_NEON_IMPLEMENTATION)
    +   png_bytep riffled_palette; /* buffer for accelerated palette expansion */
    +#endif
    +
    +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
    +#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
    +
    +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
    +#ifdef PNG_MNG_FEATURES_SUPPORTED
    +   png_byte filter_type;
    +#endif
    +
    +/* New members added in libpng-1.2.0 */
    +
    +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
    +#ifdef PNG_USER_MEM_SUPPORTED
    +   png_voidp mem_ptr;             /* user supplied struct for mem functions */
    +   png_malloc_ptr malloc_fn;      /* function for allocating memory */
    +   png_free_ptr free_fn;          /* function for freeing memory */
    +#endif
    +
    +/* New member added in libpng-1.0.13 and 1.2.0 */
    +   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
    +
    +#ifdef PNG_READ_QUANTIZE_SUPPORTED
    +/* The following three members were added at version 1.0.14 and 1.2.4 */
    +   png_bytep quantize_sort;          /* working sort array */
    +   png_bytep index_to_palette;       /* where the original index currently is
    +                                        in the palette */
    +   png_bytep palette_to_index;       /* which original index points to this
    +                                         palette color */
    +#endif
    +
    +/* New members added in libpng-1.0.16 and 1.2.6 */
    +   png_byte compression_type;
    +
    +#ifdef PNG_USER_LIMITS_SUPPORTED
    +   png_uint_32 user_width_max;
    +   png_uint_32 user_height_max;
    +
    +   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
    +    * chunks that can be stored (0 means unlimited).
    +    */
    +   png_uint_32 user_chunk_cache_max;
    +
    +   /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
    +    * can occupy when decompressed.  0 means unlimited.
    +    */
    +   png_alloc_size_t user_chunk_malloc_max;
    +#endif
    +
    +/* New member added in libpng-1.0.25 and 1.2.17 */
    +#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 member added in libpng-1.2.26 */
    +   size_t old_big_row_buf_size;
    +
    +#ifdef PNG_READ_SUPPORTED
    +/* New member added in libpng-1.2.30 */
    +  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 */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/pngtrans.c	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,892 @@
    +/*
    + * 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.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * 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.
    + */
    +
    +/* pngtrans.c - transforms the data in a row (used by both readers and writers)
    + *
    + * This file is available under and governed by the GNU General Public
    + * License version 2 only, as published by the Free Software Foundation.
    + * However, the following notice accompanied the original version of this
    + * file and, per its terms, should not be removed:
    + *
    + * Copyright (c) 2018 Cosmin Truta
    + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
    + * Copyright (c) 1996-1997 Andreas Dilger
    + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
    + *
    + * This code is released under the libpng license.
    + * For conditions of distribution and use, see the disclaimer
    + * and license in png.h
    + */
    +
    +#include "pngpriv.h"
    +
    +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    +
    +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
    +/* Turn on BGR-to-RGB mapping */
    +void PNGAPI
    +png_set_bgr(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_bgr");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->transformations |= PNG_BGR;
    +}
    +#endif
    +
    +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
    +/* Turn on 16-bit byte swapping */
    +void PNGAPI
    +png_set_swap(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_swap");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (png_ptr->bit_depth == 16)
    +      png_ptr->transformations |= PNG_SWAP_BYTES;
    +}
    +#endif
    +
    +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
    +/* Turn on pixel packing */
    +void PNGAPI
    +png_set_packing(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_packing");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (png_ptr->bit_depth < 8)
    +   {
    +      png_ptr->transformations |= PNG_PACK;
    +#     ifdef PNG_WRITE_SUPPORTED
    +         png_ptr->usr_bit_depth = 8;
    +#     endif
    +   }
    +}
    +#endif
    +
    +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
    +/* Turn on packed pixel swapping */
    +void PNGAPI
    +png_set_packswap(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_packswap");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   if (png_ptr->bit_depth < 8)
    +      png_ptr->transformations |= PNG_PACKSWAP;
    +}
    +#endif
    +
    +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
    +void PNGAPI
    +png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
    +{
    +   png_debug(1, "in png_set_shift");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->transformations |= PNG_SHIFT;
    +   png_ptr->shift = *true_bits;
    +}
    +#endif
    +
    +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
    +    defined(PNG_WRITE_INTERLACING_SUPPORTED)
    +int PNGAPI
    +png_set_interlace_handling(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_interlace handling");
    +
    +   if (png_ptr != 0 && png_ptr->interlaced != 0)
    +   {
    +      png_ptr->transformations |= PNG_INTERLACE;
    +      return (7);
    +   }
    +
    +   return (1);
    +}
    +#endif
    +
    +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
    +/* Add a filler byte on read, or remove a filler or alpha byte on write.
    + * The filler type has changed in v0.95 to allow future 2-byte fillers
    + * for 48-bit input data, as well as to avoid problems with some compilers
    + * that don't like bytes as parameters.
    + */
    +void PNGAPI
    +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;
    +
    +   if (filler_loc == PNG_FILLER_AFTER)
    +      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
    +
    +   else
    +      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
    +}
    +
    +/* Added to libpng-1.2.7 */
    +void PNGAPI
    +png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
    +{
    +   png_debug(1, "in png_set_add_alpha");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_set_filler(png_ptr, filler, filler_loc);
    +   /* The above may fail to do anything. */
    +   if ((png_ptr->transformations & PNG_FILLER) != 0)
    +      png_ptr->transformations |= PNG_ADD_ALPHA;
    +}
    +
    +#endif
    +
    +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
    +    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
    +void PNGAPI
    +png_set_swap_alpha(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_swap_alpha");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->transformations |= PNG_SWAP_ALPHA;
    +}
    +#endif
    +
    +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
    +    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
    +void PNGAPI
    +png_set_invert_alpha(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_invert_alpha");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->transformations |= PNG_INVERT_ALPHA;
    +}
    +#endif
    +
    +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
    +void PNGAPI
    +png_set_invert_mono(png_structrp png_ptr)
    +{
    +   png_debug(1, "in png_set_invert_mono");
    +
    +   if (png_ptr == NULL)
    +      return;
    +
    +   png_ptr->transformations |= PNG_INVERT_MONO;
    +}
    +
    +/* Invert monochrome grayscale data */
    +void /* PRIVATE */
    +png_do_invert(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_invert");
    +
    +  /* This test removed from libpng version 1.0.13 and 1.2.0:
    +   *   if (row_info->bit_depth == 1 &&
    +   */
    +   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    +   {
    +      png_bytep rp = row;
    +      size_t i;
    +      size_t istop = row_info->rowbytes;
    +
    +      for (i = 0; i < istop; i++)
    +      {
    +         *rp = (png_byte)(~(*rp));
    +         rp++;
    +      }
    +   }
    +
    +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
    +      row_info->bit_depth == 8)
    +   {
    +      png_bytep rp = row;
    +      size_t i;
    +      size_t istop = row_info->rowbytes;
    +
    +      for (i = 0; i < istop; i += 2)
    +      {
    +         *rp = (png_byte)(~(*rp));
    +         rp += 2;
    +      }
    +   }
    +
    +#ifdef PNG_16BIT_SUPPORTED
    +   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
    +      row_info->bit_depth == 16)
    +   {
    +      png_bytep rp = row;
    +      size_t i;
    +      size_t istop = row_info->rowbytes;
    +
    +      for (i = 0; i < istop; i += 4)
    +      {
    +         *rp = (png_byte)(~(*rp));
    +         *(rp + 1) = (png_byte)(~(*(rp + 1)));
    +         rp += 4;
    +      }
    +   }
    +#endif
    +}
    +#endif
    +
    +#ifdef PNG_16BIT_SUPPORTED
    +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
    +/* Swaps byte order on 16-bit depth images */
    +void /* PRIVATE */
    +png_do_swap(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_swap");
    +
    +   if (row_info->bit_depth == 16)
    +   {
    +      png_bytep rp = row;
    +      png_uint_32 i;
    +      png_uint_32 istop= row_info->width * row_info->channels;
    +
    +      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
    +      }
    +   }
    +}
    +#endif
    +#endif
    +
    +#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
    +static const png_byte onebppswaptable[256] = {
    +   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
    +   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
    +   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
    +   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
    +   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
    +   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
    +   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
    +   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
    +   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
    +   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
    +   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
    +   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
    +   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
    +   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
    +   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
    +   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
    +   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
    +   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
    +   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
    +   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
    +   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
    +   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
    +   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
    +   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
    +   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
    +   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
    +   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
    +   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
    +   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
    +   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
    +   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
    +   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
    +};
    +
    +static const png_byte twobppswaptable[256] = {
    +   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
    +   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
    +   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
    +   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
    +   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
    +   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
    +   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
    +   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
    +   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
    +   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
    +   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
    +   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
    +   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
    +   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
    +   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
    +   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
    +   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
    +   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
    +   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
    +   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
    +   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
    +   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
    +   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
    +   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
    +   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
    +   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
    +   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
    +   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
    +   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
    +   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
    +   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
    +   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
    +};
    +
    +static const png_byte fourbppswaptable[256] = {
    +   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
    +   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
    +   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
    +   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
    +   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
    +   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
    +   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
    +   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
    +   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
    +   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
    +   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
    +   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
    +   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
    +   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
    +   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
    +   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
    +   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
    +   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
    +   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
    +   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
    +   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
    +   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
    +   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
    +   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
    +   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
    +   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
    +   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
    +   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
    +   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
    +   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
    +   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
    +   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
    +};
    +
    +/* Swaps pixel packing order within bytes */
    +void /* PRIVATE */
    +png_do_packswap(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_packswap");
    +
    +   if (row_info->bit_depth < 8)
    +   {
    +      png_bytep rp;
    +      png_const_bytep end, table;
    +
    +      end = row + row_info->rowbytes;
    +
    +      if (row_info->bit_depth == 1)
    +         table = onebppswaptable;
    +
    +      else if (row_info->bit_depth == 2)
    +         table = twobppswaptable;
    +
    +      else if (row_info->bit_depth == 4)
    +         table = fourbppswaptable;
    +
    +      else
    +         return;
    +
    +      for (rp = row; rp < end; rp++)
    +         *rp = table[*rp];
    +   }
    +}
    +#endif /* PACKSWAP || WRITE_PACKSWAP */
    +
    +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
    +    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
    +/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
    + * somewhat weird combination of flags to determine what to do.  All the calls
    + * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
    + * correct arguments.
    + *
    + * The routine isn't general - the channel must be the channel at the start or
    + * end (not in the middle) of each pixel.
    + */
    +void /* PRIVATE */
    +png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
    +{
    +   png_bytep sp = row; /* source pointer */
    +   png_bytep dp = row; /* destination pointer */
    +   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
    +
    +   /* At the start sp will point to the first byte to copy and dp to where
    +    * it is copied to.  ep always points just beyond the end of the row, so
    +    * the loop simply copies (channels-1) channels until sp reaches ep.
    +    *
    +    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
    +    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
    +    */
    +
    +   /* GA, GX, XG cases */
    +   if (row_info->channels == 2)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         if (at_start != 0) /* Skip initial filler */
    +            ++sp;
    +         else          /* Skip initial channel and, for sp, the filler */
    +         {
    +            sp += 2; ++dp;
    +         }
    +
    +         /* For a 1 pixel wide image there is nothing to do */
    +         while (sp < ep)
    +         {
    +            *dp++ = *sp; sp += 2;
    +         }
    +
    +         row_info->pixel_depth = 8;
    +      }
    +
    +      else if (row_info->bit_depth == 16)
    +      {
    +         if (at_start != 0) /* Skip initial filler */
    +            sp += 2;
    +         else          /* Skip initial channel and, for sp, the filler */
    +         {
    +            sp += 4; dp += 2;
    +         }
    +
    +         while (sp < ep)
    +         {
    +            *dp++ = *sp++; *dp++ = *sp; sp += 3;
    +         }
    +
    +         row_info->pixel_depth = 16;
    +      }
    +
    +      else
    +         return; /* bad bit depth */
    +
    +      row_info->channels = 1;
    +
    +      /* Finally fix the color type if it records an alpha channel */
    +      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    +         row_info->color_type = PNG_COLOR_TYPE_GRAY;
    +   }
    +
    +   /* RGBA, RGBX, XRGB cases */
    +   else if (row_info->channels == 4)
    +   {
    +      if (row_info->bit_depth == 8)
    +      {
    +         if (at_start != 0) /* Skip initial filler */
    +            ++sp;
    +         else          /* Skip initial channels and, for sp, the filler */
    +         {
    +            sp += 4; dp += 3;
    +         }
    +
    +         /* Note that the loop adds 3 to dp and 4 to sp each time. */
    +         while (sp < ep)
    +         {
    +            *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
    +         }
    +
    +         row_info->pixel_depth = 24;
    +      }
    +
    +      else if (row_info->bit_depth == 16)
    +      {
    +         if (at_start != 0) /* Skip initial filler */
    +            sp += 2;
    +         else          /* Skip initial channels and, for sp, the filler */
    +         {
    +            sp += 8; dp += 6;
    +         }
    +
    +         while (sp < ep)
    +         {
    +            /* Copy 6 bytes, skip 2 */
    +            *dp++ = *sp++; *dp++ = *sp++;
    +            *dp++ = *sp++; *dp++ = *sp++;
    +            *dp++ = *sp++; *dp++ = *sp; sp += 3;
    +         }
    +
    +         row_info->pixel_depth = 48;
    +      }
    +
    +      else
    +         return; /* bad bit depth */
    +
    +      row_info->channels = 3;
    +
    +      /* Finally fix the color type if it records an alpha channel */
    +      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +         row_info->color_type = PNG_COLOR_TYPE_RGB;
    +   }
    +
    +   else
    +      return; /* The filler channel has gone already */
    +
    +   /* Fix the rowbytes value. */
    +   row_info->rowbytes = (size_t)(dp-row);
    +}
    +#endif
    +
    +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
    +/* Swaps red and blue bytes within a pixel */
    +void /* PRIVATE */
    +png_do_bgr(png_row_infop row_info, png_bytep row)
    +{
    +   png_debug(1, "in png_do_bgr");
    +
    +   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
    +   {
    +      png_uint_32 row_width = row_info->width;
    +      if (row_info->bit_depth == 8)
    +      {
    +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
    +         {
    +            png_bytep rp;
    +            png_uint_32 i;
    +
    +            for (i = 0, rp = row; i < row_width; i++, rp += 3)
    +            {
    +               png_byte save = *rp;
    +               *rp = *(rp + 2);
    +               *(rp + 2) = save;
    +            }
    +         }
    +
    +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +         {
    +            png_bytep rp;
    +            png_uint_32 i;
    +
    +            for (i = 0, rp = row; i < row_width; i++, rp += 4)
    +            {
    +               png_byte save = *rp;
    +               *rp = *(rp + 2);
    +               *(rp + 2) = save;
    +            }
    +         }
    +      }
    +
    +#ifdef PNG_16BIT_SUPPORTED
    +      else if (row_info->bit_depth == 16)
    +      {
    +         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
    +         {
    +            png_bytep rp;
    +            png_uint_32 i;
    +
    +            for (i = 0, rp = row; i < row_width; i++, rp += 6)
    +            {
    +               png_byte save = *rp;
    +               *rp = *(rp + 4);
    +               *(rp + 4) = save;
    +               save = *(rp + 1);
    +               *(rp + 1) = *(rp + 5);
    +               *(rp + 5) = save;
    +            }
    +         }
    +
    +         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    +         {
    +            png_bytep rp;
    +            png_uint_32 i;
    +
    +            for (i = 0, rp = row; i < row_width; i++, rp += 8)
    +            {
    +               png_byte save = *rp;
    +               *rp = *(rp + 4);
    +               *(rp + 4) = save;
    +               save = *(rp + 1);
    +               *(rp + 1) = *(rp + 5);
    +               *(rp + 5) = save;
    +            }
    +         }
    +      }
    +#endif
    +   }
    +}
    +#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 = PNG_PADBITS(row_info->pixel_depth, row_info->width);
    +      png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
    +
    +      switch (row_info->bit_depth)
    +      {
    +         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_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;
    +}
    +#endif
    +
    +/* This function returns a pointer to the user_transform_ptr associated with
    + * the user transform functions.  The application should free any memory
    + * associated with this pointer before png_write_destroy and png_read_destroy
    + * are called.
    + */
    +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
    +png_voidp PNGAPI
    +png_get_user_transform_ptr(png_const_structrp png_ptr)
    +{
    +   if (png_ptr == NULL)
    +      return (NULL);
    +
    +   return png_ptr->user_transform_ptr;
    +}
    +#endif
    +
    +#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
    +png_uint_32 PNGAPI
    +png_get_current_row_number(png_const_structrp png_ptr)
    +{
    +   /* See the comments in png.h - this is the sub-image row when reading an
    +    * interlaced image.
    +    */
    +   if (png_ptr != NULL)
    +      return png_ptr->row_number;
    +
    +   return PNG_UINT_32_MAX; /* help the app not to fail silently */
    +}
    +
    +png_byte PNGAPI
    +png_get_current_pass_number(png_const_structrp png_ptr)
    +{
    +   if (png_ptr != NULL)
    +      return png_ptr->pass;
    +   return 8; /* invalid */
    +}
    +#endif /* USER_TRANSFORM_INFO */
    +#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
    +#endif /* READ || WRITE */
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/README openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/README
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/README	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/README	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,183 @@
    +README for libpng version 1.6.37 - April 14, 2019
    +=================================================
    +
    +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 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 extensive use and testing since mid-1995.  By late 1997 it had
    +finally gotten to the stage where there hadn't been significant
    +changes to the API in some time, and people have a bad feeling about
    +libraries with versions < 1.0.  Version 1.0.0 was released in
    +March 1998.
    +
    +****
    +Note that some of the changes to the png_info structure render this
    +version of the library binary incompatible with libpng-0.89 or
    +earlier versions if you are using a shared library.  The type of the
    +"filler" parameter for png_set_filler() has changed from png_byte to
    +png_uint_32, which will affect shared-library applications that use
    +this function.
    +
    +To avoid problems with changes to the internals of the png info_struct,
    +new APIs have been made available in 0.95 to avoid direct application
    +access to info_ptr.  These functions are the png_set_ and
    +png_get_ functions.  These functions should be used when
    +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 did not make current programs
    +that access the info struct directly incompatible with the new
    +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
    +Windows DLL, and new APIs for accessing data in the info struct.
    +Experimental functions include the ability to set weighting and cost
    +factors for row filter selection, direct reads of integers from buffers
    +on big-endian processors that support misaligned data access, faster
    +methods of doing alpha composition, and more accurate 16->8 bit color
    +conversion.
    +
    +The additions since 0.89 include the ability to read from a PNG stream
    +which has had some (or all) of the signature bytes read by the calling
    +application.  This also allows the reading of embedded PNG streams that
    +do not have the PNG file signature.  As well, it is now possible to set
    +the library action on the detection of chunk CRC errors.  It is possible
    +to set different actions based on whether the CRC error occurred in a
    +critical or an ancillary chunk.
    +
    +For a detailed description on using libpng, read libpng-manual.txt.
    +For examples of libpng in a program, see example.c and pngtest.c.  For
    +usage information and restrictions (what little they are) on libpng,
    +see png.h.  For a description on using zlib (the compression library
    +used by libpng) and zlib's restrictions, see zlib.h
    +
    +I have included a general makefile, as well as several machine and
    +compiler specific ones, but you may have to modify one for your own
    +needs.
    +
    +You should use zlib 1.0.4 or later to run this, but it MAY work with
    +versions as old as zlib 0.95.  Even so, there are bugs in older zlib
    +versions which can cause the output of invalid compression streams for
    +some images.
    +
    +You should also note that zlib is a compression library that is useful
    +for more things than just PNG files.  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
    +https://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/pngdocs.html .
    +
    +This code is currently being archived at libpng.sourceforge.io in the
    +[DOWNLOAD] area, and at http://libpng.download/src .
    +
    +This release, based in a large way on Glenn's, Guy's and Andreas'
    +earlier work, was created and will be supported by myself and the PNG
    +development group.
    +
    +Send comments/corrections/commendations to png-mng-implement at
    +lists.sourceforge.net (subscription required; visit
    +https://lists.sourceforge.net/lists/listinfo/png-mng-implement
    +to subscribe).
    +
    +Send general questions about the PNG specification to png-mng-misc
    +at lists.sourceforge.net (subscription required; visit
    +https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
    +subscribe).
    +
    +Files in this distribution:
    +
    +      ANNOUNCE      =>  Announcement of this version, with recent changes
    +      AUTHORS       =>  List of contributing authors
    +      CHANGES       =>  Description of changes between libpng versions
    +      KNOWNBUG      =>  List of known bugs and deficiencies
    +      LICENSE       =>  License to use and redistribute libpng
    +      README        =>  This file
    +      TODO          =>  Things not implemented in the current library
    +      TRADEMARK     =>  Trademark information
    +      example.c     =>  Example code for using libpng functions
    +      libpng.3      =>  manual page for libpng (includes libpng-manual.txt)
    +      libpng-manual.txt  =>  Description of libpng and its functions
    +      libpngpf.3    =>  manual page for libpng's private functions
    +      png.5         =>  manual page for the PNG format
    +      png.c         =>  Basic interface functions common to library
    +      png.h         =>  Library function and interface declarations (public)
    +      pngpriv.h     =>  Library function and interface declarations (private)
    +      pngconf.h     =>  System specific library configuration (public)
    +      pngstruct.h   =>  png_struct declaration (private)
    +      pnginfo.h     =>  png_info struct declaration (private)
    +      pngdebug.h    =>  debugging macros (private)
    +      pngerror.c    =>  Error/warning message I/O functions
    +      pngget.c      =>  Functions for retrieving info from struct
    +      pngmem.c      =>  Memory handling functions
    +      pngbar.png    =>  PNG logo, 88x31
    +      pngnow.png    =>  PNG logo, 98x31
    +      pngpread.c    =>  Progressive reading functions
    +      pngread.c     =>  Read data/helper high-level functions
    +      pngrio.c      =>  Lowest-level data read I/O functions
    +      pngrtran.c    =>  Read data transformation functions
    +      pngrutil.c    =>  Read data utility functions
    +      pngset.c      =>  Functions for storing data into the info_struct
    +      pngtest.c     =>  Library test program
    +      pngtest.png   =>  Library test sample image
    +      pngtrans.c    =>  Common data transformation functions
    +      pngwio.c      =>  Lowest-level write I/O functions
    +      pngwrite.c    =>  High-level write functions
    +      pngwtran.c    =>  Write data transformations
    +      pngwutil.c    =>  Write utility functions
    +      arm           =>  Contains optimized code for the ARM platform
    +      powerpc       =>  Contains optimized code for the PowerPC platform
    +      contrib       =>  Contributions
    +       arm-neon         =>  Optimized code for ARM-NEON platform
    +       powerpc-vsx      =>  Optimized code for POWERPC-VSX platform
    +       examples         =>  Example programs
    +       gregbook         =>  source code for PNG reading and writing, from
    +                            Greg Roelofs' "PNG: The Definitive Guide",
    +                            O'Reilly, 1999
    +       libtests         =>  Test programs
    +       mips-msa         =>  Optimized code for MIPS-MSA platform
    +       pngminim         =>  Minimal decoder, encoder, and progressive decoder
    +                            programs demonstrating use of pngusr.dfa
    +       pngminus         =>  Simple pnm2png and png2pnm programs
    +       pngsuite         =>  Test images
    +       testpngs
    +       tools            =>  Various tools
    +       visupng          =>  Contains a MSVC workspace for VisualPng
    +      intel             =>  Optimized code for INTEL-SSE2 platform
    +      mips              =>  Optimized code for MIPS platform
    +      projects      =>  Contains project files and workspaces for
    +                        building a DLL
    +       owatcom          =>  Contains a WATCOM project for building libpng
    +       visualc71        =>  Contains a Microsoft Visual C++ (MSVC)
    +                            workspace for building libpng and zlib
    +       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)
    +
    +Good luck, and happy coding!
    +
    + * Cosmin Truta (current maintainer, since 2018)
    + * Glenn Randers-Pehrson (former maintainer, 1998-2018)
    + * Andreas Eric Dilger (former maintainer, 1996-1997)
    + * Guy Eric Schalnat (original author and former maintainer, 1995-1996)
    +   (formerly of Group 42, Inc.)
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt
    --- openjdk-17-17.0.5+8/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/share/native/libsplashscreen/libpng/UPDATING.txt	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,49 @@
    +Updating libpng in OpenJDK
    +
    +1) Update the src/java.desktop/share/legal/libpng.md file.
    +Usually this is just a matter of updating the version at the top,
    +and in the embedded text, and extending the copyright date.
    +
    +The updated info comes from the LICENSE file.
    +
    +2) Copy LICENSE, README, and CHANGES from the new version into OpenJDK's
    +libpng source directory
    +
    +3) OpenJDK includes just a subset of the files, since we use it only for reading.
    +Copy only the same .c and .h files as are already there and re-apply the
    +GPL v2 + CP header to all the updated files. These files also have a special
    +note referencing the previous license. Restore everything as it was.
    +You can either do this with a clever-enough script, or manually copy/paste.
    +There are 18 files to update so either is do-able.
    +
    +4) Special and careful handling of pnglibconf.h
    +OpenJDK has a heavily modified copy of pnglibconf.h.
    +This is the trickiest part of the whole exercise.
    +This file is generated by png at build time.
    +Except for the dates and version, you should generally not need to update
    +OpenJDK's copy unless the new version of PNG has added rquired new #defines
    +that cause problems building.
    +You can run configure && make on the downloaded source and compare but we
    +do not want to enable any of the WRITE support, and there are many more
    +modifications as well.
    +So do NOT just copy in a file from the new libpng.
    +The header may be the only thing you want to update.
    +Also this file has a special "THIS FILE WAS MODIFIED BY ORACLE, INC."
    +line in the GPL header.
    +So lots of reasons to not copy over the new version,
    +and instead just tweak the existing one.
    +
    +5) Run scripts to expand tabs and remove trailing white space from source files.
    +
    +Use expand to remove tabs
    +expand ${f} > ${f}.tmp
    +mv ${f}.tmp $f
    +
    +Use sed to remove trailing white space
    +sed -e 's/[ ]* $//' ${f} > ${f}.tmp
    +mv ${f}.tmp $f
    +
    +6) As with all native code, run it through the official build systems, in case
    +the updated code trigger any fatal warnings with the official compilers.
    +
    +7) Run the splashscreen jtreg tests. 
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java openjdk-17-17.0.6+10/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/classes/sun/awt/windows/WTrayIconPeer.java	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2022, 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,17 +25,20 @@
     
     package sun.awt.windows;
     
    -import java.awt.Graphics2D;
     import java.awt.AWTEvent;
     import java.awt.Frame;
    +import java.awt.Graphics2D;
     import java.awt.GraphicsEnvironment;
    -import java.awt.PopupMenu;
    +import java.awt.Image;
     import java.awt.Point;
    +import java.awt.PopupMenu;
     import java.awt.TrayIcon;
    -import java.awt.Image;
     import java.awt.geom.AffineTransform;
    +import java.awt.image.BufferedImage;
    +import java.awt.image.DataBufferInt;
    +import java.awt.image.ImageObserver;
    +import java.awt.image.Raster;
     import java.awt.peer.TrayIconPeer;
    -import java.awt.image.*;
     
     import sun.awt.AWTAccessor;
     import sun.awt.SunToolkit;
    @@ -49,14 +52,11 @@
     
         IconObserver observer = new IconObserver();
         boolean firstUpdate = true;
    -    Frame popupParent = new Frame("PopupMessageWindow");
    +    final Frame popupParent = new Frame("PopupMessageWindow");
         PopupMenu popup;
     
         @Override
         protected void disposeImpl() {
    -        if (popupParent != null) {
    -            popupParent.dispose();
    -        }
             popupParent.dispose();
             _dispose();
             WToolkit.targetDisposedPeer(target, this);
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	2023-01-10 13:21:55.000000000 +0000
    @@ -25,6 +25,7 @@
     
     #include "awt.h"
     #include 
    +#include 
     #include "jlong.h"
     #include "awt_Font.h"
     #include "awt_Toolkit.h"
    @@ -287,7 +288,6 @@
                     return NULL;
                 }
                 LPCWSTR textComponentFontName = JNU_GetStringPlatformChars(env, jTextComponentFontName, NULL);
    -
                 awtFont->m_textInput = -1;
                 for (int i = 0; i < cfnum; i++) {
                     // nativeName is a pair of platform fontname and its charset
    @@ -463,7 +463,7 @@
     
         // Set font name
         WCHAR tmpname[80];
    -    wcscpy(tmpname, name);
    +    StringCchCopy(tmpname, 80, name);
         WCHAR* delimit = wcschr(tmpname, L',');
         if (delimit != NULL)
             *delimit = L'\0';  // terminate the string after the font name.
    @@ -471,7 +471,7 @@
         strip_tail(tmpname,L""); //strip possible trailing whitespace
         strip_tail(tmpname,L"Italic");
         strip_tail(tmpname,L"Bold");
    -    wcscpy(&(logFont.lfFaceName[0]), tmpname);
    +    StringCchCopy(&(logFont.lfFaceName[0]), LF_FACESIZE, tmpname);
         HFONT hFont = ::CreateFontIndirect(&logFont);
         DASSERT(hFont != NULL);
         // get a expanded or condensed version if its specified.
    @@ -502,7 +502,7 @@
         // 80 > (max face name(=30) + strlen("CHINESEBIG5_CHARSET"))
         // longName doesn't have to be printable.  So, it is OK not to convert.
     
    -    wsprintf(longName, L"%ls-%d-%d", name, style, height);
    +    StringCchPrintf(longName, 80, L"%ls-%d-%d", name, style, height);
     
         HFONT hFont = NULL;
     
    @@ -1750,12 +1750,12 @@
         lpszCP++; // cf lpszCP = "932"
     
         char szSubKey[KEYLEN];
    -    strcpy(szSubKey, "EUDC\\");
    +    StringCchCopyA(szSubKey, KEYLEN, "EUDC\\");
         if ((strlen(szSubKey) + strlen(lpszCP)) >= KEYLEN) {
             return NULL;
         }
    -    strcpy(&(szSubKey[strlen(szSubKey)]), lpszCP);
    -    strcpy(m_szCodePageSubkey, szSubKey);
    +    StringCchCatA(szSubKey, KEYLEN, lpszCP);
    +    StringCchCopyA(m_szCodePageSubkey, KEYLEN, szSubKey);
         return m_szCodePageSubkey;
     }
     
    @@ -1780,7 +1780,7 @@
     
         // get EUDC font file name
         WCHAR szFamilyName[80];
    -    wcscpy(szFamilyName, GetFontName());
    +    StringCchCopy(szFamilyName, 80, GetFontName());
         WCHAR* delimit = wcschr(szFamilyName, L',');
         if (delimit != NULL)
             *delimit = L'\0';
    @@ -1799,7 +1799,7 @@
             if (m_fTTEUDCFileExist == FALSE)
                 return;
             if (wcslen(m_szDefaultEUDCFile) > 0) {
    -            wcscpy(lpszFileName, m_szDefaultEUDCFile);
    +            StringCchCopy(lpszFileName, cchFileName, m_szDefaultEUDCFile);
                 return;
             }
             char szDefault[] = "SystemDefaultEUDCFont";
    @@ -1825,7 +1825,7 @@
         VERIFY(::MultiByteToWideChar(CP_ACP, 0,
             (LPCSTR)szFileName, -1, lpszFileName, cchFileName) != 0);
         if (fUseDefault)
    -        wcscpy(m_szDefaultEUDCFile, lpszFileName);
    +        StringCchCopy(m_szDefaultEUDCFile, _MAX_PATH, lpszFileName);
     }
     
     void CCombinedSegTable::Create(LPCWSTR name)
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp	2023-01-10 13:21:55.000000000 +0000
    @@ -24,6 +24,7 @@
      */
     
     #include "awt.h"
    +#include 
     #include 
     #include 
     #include 
    @@ -2408,7 +2409,7 @@
         size_t nameLen = wcslen(fontNameW);
         if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
     
    -        wcscpy(lf.lfFaceName, fontNameW);
    +        StringCchCopyW(lf.lfFaceName, LF_FACESIZE, fontNameW);
     
             lf.lfCharSet = DEFAULT_CHARSET;
             lf.lfPitchAndFamily = 0;
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.cpp	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2022, 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
    @@ -70,10 +70,12 @@
     
     jfieldID AwtTrayIcon::idID;
     jfieldID AwtTrayIcon::actionCommandID;
    +jmethodID AwtTrayIcon::updateImageID;
     
     HWND AwtTrayIcon::sm_msgWindow = NULL;
     AwtTrayIcon::TrayIconListItem* AwtTrayIcon::sm_trayIconList = NULL;
     int AwtTrayIcon::sm_instCount = 0;
    +bool AwtTrayIcon::m_bDPIChanged = false;
     
     /************************************************************************
      * AwtTrayIcon methods
    @@ -221,6 +223,18 @@
         m_nid.uVersion = NOTIFYICON_VERSION;
     }
     
    +// Call updateImage() method on the peer when screen scale changes
    +void AwtTrayIcon::UpdateImage()
    +{
    +    JNIEnv *env =(JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    +
    +    jobject peer = GetPeer(env);
    +    if (peer != NULL) {
    +        env->CallVoidMethod(peer, updateImageID);
    +        env->ExceptionClear();
    +    }
    +}
    +
     BOOL AwtTrayIcon::SendTrayMessage(DWORD dwMessage)
     {
         return Shell_NotifyIcon(dwMessage, (PNOTIFYICONDATA)&m_nid);
    @@ -248,6 +262,10 @@
                     }
                 }
                 break;
    +        case WM_DPICHANGED:
    +            // Set the flag to update icon images, see WmTaskbarCreated
    +            m_bDPIChanged = true;
    +            break;
             default:
                 if(uMsg == s_msgTaskbarCreated) {
                     if (hwnd == AwtTrayIcon::sm_msgWindow) {
    @@ -474,12 +492,13 @@
     MsgRouting AwtTrayIcon::WmTaskbarCreated() {
         TrayIconListItem* item;
         for (item = sm_trayIconList; item != NULL; item = item->m_next) {
    -        BOOL result = item->m_trayIcon->SendTrayMessage(NIM_ADD);
    -        // 6270114: Instructs the taskbar to behave according to the Shell version 5.0
    -        if (result) {
    -            item->m_trayIcon->SendTrayMessage(NIM_SETVERSION);
    +        if (m_bDPIChanged) {
    +            // Update the icon image
    +            item->m_trayIcon->UpdateImage();
             }
    +        item->m_trayIcon->AddTrayIcon();
         }
    +    m_bDPIChanged = false;
         return mrDoDefault;
     }
     
    @@ -725,7 +744,7 @@
             _tcscpy_s(m_nid.szTip, TRAY_ICON_TOOLTIP_MAX_SIZE, tooltip);
         }
     
    -    SendTrayMessage(NIM_MODIFY);
    +    ModifyTrayIcon();
     }
     
     void AwtTrayIcon::_SetToolTip(void *param)
    @@ -793,10 +812,10 @@
         JNI_CHECK_PEER_GOTO(self, ret);
         trayIcon = (AwtTrayIcon *)pData;
     
    -    BOOL result = trayIcon->SendTrayMessage(jupdate == JNI_TRUE ? NIM_MODIFY : NIM_ADD);
    -    // 6270114: Instructs the taskbar to behave according to the Shell version 5.0
    -    if (result && jupdate == JNI_FALSE) {
    -        trayIcon->SendTrayMessage(NIM_SETVERSION);
    +    if (jupdate == JNI_TRUE) {
    +        trayIcon->ModifyTrayIcon();
    +    } else {
    +        trayIcon->AddTrayIcon();
         }
     ret:
         env->DeleteGlobalRef(self);
    @@ -845,7 +864,7 @@
             _tcscpy_s(m_nid.szInfo, TRAY_ICON_BALLOON_INFO_MAX_SIZE, text);
         }
     
    -    SendTrayMessage(NIM_MODIFY);
    +    ModifyTrayIcon();
         m_nid.uFlags &= ~NIF_INFO;
     }
     
    @@ -917,6 +936,14 @@
         DASSERT(AwtTrayIcon::actionCommandID != NULL);
         CHECK_NULL( AwtTrayIcon::actionCommandID);
     
    +    jclass wPeerCls = env->FindClass("sun/awt/windows/WTrayIconPeer");
    +    DASSERT(wPeerCls != NULL);
    +    CHECK_NULL(wPeerCls);
    +
    +    AwtTrayIcon::updateImageID = env->GetMethodID(wPeerCls, "updateImage", "()V");
    +    DASSERT(AwtTrayIcon::updateImageID != NULL);
    +    CHECK_NULL(AwtTrayIcon::updateImageID);
    +
         CATCH_BAD_ALLOC;
     }
     
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.h openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.h
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.h	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/awt_TrayIcon.h	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2022, 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
    @@ -52,7 +52,6 @@
     
         virtual void Dispose();
     
    -    BOOL SendTrayMessage(DWORD dwMessage);
         void LinkObjects(JNIEnv *env, jobject peer);
         void UnlinkObjects();
     
    @@ -86,6 +85,8 @@
     
         void DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType);
     
    +    void UpdateImage();
    +
         // Adds to the head of the list
         INLINE void AddTrayIconItem(UINT id) {
             TrayIconListItem* item = new TrayIconListItem(id, this);
    @@ -121,6 +122,7 @@
          */
         static jfieldID idID;
         static jfieldID actionCommandID;
    +    static jmethodID updateImageID;
     
         // ************************
     
    @@ -151,6 +153,22 @@
             TrayIconListItem* m_next;
         };
     
    +    BOOL SendTrayMessage(DWORD dwMessage);
    +
    +    INLINE void AddTrayIcon() {
    +        BOOL result = SendTrayMessage(NIM_ADD);
    +        // 6270114: Instructs the taskbar to behave according to the Shell version 5.0
    +        if (result) {
    +            SendTrayMessage(NIM_SETVERSION);
    +        }
    +    }
    +
    +    INLINE void ModifyTrayIcon() {
    +        SendTrayMessage(NIM_MODIFY);
    +    }
    +
    +    static bool m_bDPIChanged;
    +
     public:
         static TrayIconListItem* sm_trayIconList;
     };
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp	2023-01-10 13:21:55.000000000 +0000
    @@ -700,6 +700,7 @@
         STRRET strret;
         OLECHAR olePath[MAX_PATH]; // wide-char version of path name
         LPWSTR wstr;
    +    int ret;
     
         IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
         if (pParent == NULL) {
    @@ -719,12 +720,18 @@
         switch (strret.uType) {
           case STRRET_CSTR :
             // IShellFolder::ParseDisplayName requires the path name in Unicode.
    -        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strret.cStr, -1, olePath, MAX_PATH);
    +        ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strret.cStr, -1, olePath, MAX_PATH);
    +        if (ret == 0) {
    +            return NULL;
    +        }
             wstr = olePath;
             break;
     
           case STRRET_OFFSET :
    -        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (CHAR *)pidl + strret.uOffset, -1, olePath, MAX_PATH);
    +        ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (CHAR *)pidl + strret.uOffset, -1, olePath, MAX_PATH);
    +        if (ret == 0) {
    +            return NULL;
    +        }
             wstr = olePath;
             break;
     
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libfontmanager/fontpath.c openjdk-17-17.0.6+10/src/java.desktop/windows/native/libfontmanager/fontpath.c
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libfontmanager/fontpath.c	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libfontmanager/fontpath.c	2023-01-10 13:21:55.000000000 +0000
    @@ -24,6 +24,7 @@
      */
     
     #include 
    +#include 
     #include 
     
     #include 
    @@ -63,20 +64,20 @@
         end = strrchr(sysdir,'\\');
         if (end && (stricmp(end,"\\System") || stricmp(end,"\\System32"))) {
             *end = 0;
    -         strcat(sysdir, "\\Fonts");
    +        StringCchCatA(sysdir, BSIZE, "\\Fonts");
         }
     
         GetWindowsDirectory(windir, BSIZE);
         if (strlen(windir) > BSIZE-7) {
             *windir = 0;
         } else {
    -        strcat(windir, "\\Fonts");
    +        StringCchCatA(windir, BSIZE, "\\Fonts");
         }
     
    -    strcpy(fontpath,sysdir);
    +    StringCchCopyA(fontpath, BSIZE*2, sysdir);
         if (stricmp(sysdir,windir)) {
    -        strcat(fontpath,";");
    -        strcat(fontpath,windir);
    +        StringCchCatA(fontpath, BSIZE*2, ";");
    +        StringCchCatA(fontpath, BSIZE*2, windir);
         }
     
         return JNU_NewStringPlatform(env, fontpath);
    @@ -152,7 +153,7 @@
         info.isDifferent = 0;
     
         memset(&lfw, 0, sizeof(lfw));
    -    wcscpy(lfw.lfFaceName, fullName);
    +    StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, fullName);
         lfw.lfCharSet = DEFAULT_CHARSET;
         EnumFontFamiliesExW(screenDC, &lfw,
                             (FONTENUMPROCW)CheckFontFamilyProcW,
    @@ -349,7 +350,7 @@
         }
     
         memset(&lfw, 0, sizeof(lfw));
    -    wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName);
    +    StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, lpelfe->elfLogFont.lfFaceName);
         lfw.lfCharSet = lpelfe->elfLogFont.lfCharSet;
         EnumFontFamiliesExW(screenDC, &lfw,
                             (FONTENUMPROCW)EnumFontFacesInFamilyProcW,
    @@ -653,7 +654,7 @@
         /* Enumerate fonts via GDI to build maps of fonts and families */
         memset(&lfw, 0, sizeof(lfw));
         lfw.lfCharSet = DEFAULT_CHARSET;  /* all charsets */
    -    wcscpy(lfw.lfFaceName, L"");      /* one face per family (CHECK) */
    +    StringCchCopyW(lfw.lfFaceName, LF_FACESIZE, L"");      /* one face per family (CHECK) */
         EnumFontFamiliesExW(screenDC, &lfw,
                             (FONTENUMPROCW)EnumFamilyNamesW,
                             (LPARAM)(&fmi), 0L);
    diff -Nru openjdk-17-17.0.5+8/src/java.desktop/windows/native/libfontmanager/lcdglyph.c openjdk-17-17.0.6+10/src/java.desktop/windows/native/libfontmanager/lcdglyph.c
    --- openjdk-17-17.0.5+8/src/java.desktop/windows/native/libfontmanager/lcdglyph.c	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.desktop/windows/native/libfontmanager/lcdglyph.c	2023-01-10 13:21:55.000000000 +0000
    @@ -48,6 +48,7 @@
     #include 
     #include 
     #include 
    +#include 
     #include 
     #include 
     
    @@ -236,7 +237,7 @@
         name[nameLen] = '\0';
     
         if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
    -        wcscpy(lf.lfFaceName, name);
    +        StringCchCopyW(lf.lfFaceName, LF_FACESIZE, name);
         } else {
             FREE_AND_RETURN;
         }
    diff -Nru openjdk-17-17.0.5+8/src/java.instrument/windows/native/libinstrument/EncodingSupport_md.c openjdk-17-17.0.6+10/src/java.instrument/windows/native/libinstrument/EncodingSupport_md.c
    --- openjdk-17-17.0.5+8/src/java.instrument/windows/native/libinstrument/EncodingSupport_md.c	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.instrument/windows/native/libinstrument/EncodingSupport_md.c	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2004, 2022, 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
    @@ -76,8 +76,8 @@
                     if (plen >= 0) {
                         platform_str[plen] = '\0';
                     }
    -                free(wstr);
                 }
    +            free(wstr);
             }
         }
         return plen;
    diff -Nru openjdk-17-17.0.5+8/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java openjdk-17-17.0.6+10/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java
    --- openjdk-17-17.0.5+8/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2004, 2022, 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
    @@ -422,7 +422,9 @@
                 cleanState();
                 throw new LoginException ("Subject is read-only");
             }
    -        subject.getPrincipals().remove(user);
    +        if (user != null) {
    +            subject.getPrincipals().remove(user);
    +        }
     
             // clean out state
             cleanState();
    diff -Nru openjdk-17-17.0.5+8/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java openjdk-17-17.0.6+10/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
    --- openjdk-17-17.0.5+8/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java	2023-01-10 13:21:55.000000000 +0000
    @@ -189,6 +189,10 @@
                         ctx = getLdapCtxFromUrl(
                                 r.getDomainName(), url, new LdapURL(u), env);
                         return ctx;
    +                } catch (AuthenticationException e) {
    +                    // do not retry on a different endpoint to avoid blocking
    +                    // the user if authentication credentials are wrong.
    +                    throw e;
                     } catch (NamingException e) {
                         // try the next element
                         lastException = e;
    @@ -241,6 +245,10 @@
             for (String u : urls) {
                 try {
                     return getUsingURL(u, env);
    +            } catch (AuthenticationException e) {
    +                // do not retry on a different URL to avoid blocking
    +                // the user if authentication credentials are wrong.
    +                throw e;
                 } catch (NamingException e) {
                     ex = e;
                 }
    diff -Nru openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING
    --- openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,95 @@
    +Copyright (c) 1999-2003 David Corcoran 
    +Copyright (c) 2001-2011 Ludovic Rousseau 
    +All rights reserved.
    +
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions
    +are met:
    +
    +1. Redistributions of source code must retain the above copyright
    +   notice, this list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright
    +   notice, this list of conditions and the following disclaimer in the
    +   documentation and/or other materials provided with the distribution.
    +3. The name of the author may not be used to endorse or promote products
    +   derived from this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +
    +Some files are under GNU GPL v3 or any later version
    +- doc/example/pcsc_demo.c
    +- the files in src/spy/
    +- the files in UnitaryTests/
    +
    +    Copyright (C) 2003-2014  Ludovic Rousseau
    +
    +    This program is free software: you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation, either version 3 of the License, or
    +    (at your option) any later version.
    +
    +    This program 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 for more details.
    +
    +    You should have received a copy of the GNU General Public License
    +    along with this program.  If not, see .
    +
    +
    +Files src/auth.c and src/auth.h are:
    + * Copyright (C) 2013 Red Hat
    + *
    + * All rights reserved.
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *
    + * 2. Redistributions in binary form must reproduce the above copyright
    + * notice, this list of conditions and the following disclaimer in the
    + * documentation and/or other materials provided with the distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
    + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
    + * DAMAGE.
    + *
    + * Author: Nikos Mavrogiannopoulos 
    +
    +
    +Files src/simclist.c and src/simclist.h are:
    + * Copyright (c) 2007,2008,2009,2010,2011 Mij 
    + *
    + * Permission to use, copy, modify, and distribute this software for any
    + * purpose with or without fee is hereby granted, provided that the above
    + * copyright notice and this permission notice appear in all copies.
    + *
    + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    +
    diff -Nru openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h
    --- openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/pcsclite.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,309 @@
    +/*
    + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
    + *
    + * Copyright (C) 1999-2004
    + *  David Corcoran 
    + * Copyright (C) 2002-2011
    + *  Ludovic Rousseau 
    + * Copyright (C) 2005
    + *  Martin Paljak 
    + *
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions
    +are met:
    +
    +1. Redistributions of source code must retain the above copyright
    +   notice, this list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright
    +   notice, this list of conditions and the following disclaimer in the
    +   documentation and/or other materials provided with the distribution.
    +3. The name of the author may not be used to endorse or promote products
    +   derived from this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + * @file
    + * @brief This keeps a list of defines for pcsc-lite.
    + *
    + * Error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
    + */
    +
    +#ifndef __pcsclite_h__
    +#define __pcsclite_h__
    +
    +#include 
    +
    +#ifdef __cplusplus
    +extern "C"
    +{
    +#endif
    +
    +typedef LONG SCARDCONTEXT; /**< \p hContext returned by SCardEstablishContext() */
    +typedef SCARDCONTEXT *PSCARDCONTEXT;
    +typedef SCARDCONTEXT *LPSCARDCONTEXT;
    +typedef LONG SCARDHANDLE; /**< \p hCard returned by SCardConnect() */
    +typedef SCARDHANDLE *PSCARDHANDLE;
    +typedef SCARDHANDLE *LPSCARDHANDLE;
    +
    +#define MAX_ATR_SIZE            33    /**< Maximum ATR size */
    +
    +/* Set structure elements aligment on bytes
    + * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
    +#ifdef __APPLE__
    +#pragma pack(1)
    +#endif
    +
    +typedef struct
    +{
    +    const char *szReader;
    +    void *pvUserData;
    +    DWORD dwCurrentState;
    +    DWORD dwEventState;
    +    DWORD cbAtr;
    +    unsigned char rgbAtr[MAX_ATR_SIZE];
    +}
    +SCARD_READERSTATE, *LPSCARD_READERSTATE;
    +
    +/** Protocol Control Information (PCI) */
    +typedef struct
    +{
    +    unsigned long dwProtocol;    /**< Protocol identifier */
    +    unsigned long cbPciLength;    /**< Protocol Control Inf Length */
    +}
    +SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
    +
    +typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;
    +
    +extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci;
    +
    +/* restore default structure elements alignment */
    +#ifdef __APPLE__
    +#pragma pack()
    +#endif
    +
    +#define SCARD_PCI_T0    (&g_rgSCardT0Pci) /**< protocol control information (PCI) for T=0 */
    +#define SCARD_PCI_T1    (&g_rgSCardT1Pci) /**< protocol control information (PCI) for T=1 */
    +#define SCARD_PCI_RAW    (&g_rgSCardRawPci) /**< protocol control information (PCI) for RAW protocol */
    +
    +/**
    + * @defgroup ErrorCodes ErrorCodes
    + * @brief Error code documentation
    + *
    + * The error codes descriptions are from
    + * http://msdn.microsoft.com/en-us/library/aa924526.aspx
    + */
    +/** @ingroup ErrorCodes */
    +#define SCARD_S_SUCCESS            ((LONG)0x00000000) /**< No error was encountered. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_F_INTERNAL_ERROR        ((LONG)0x80100001) /**< An internal consistency check failed. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_CANCELLED        ((LONG)0x80100002) /**< The action was cancelled by an SCardCancel request. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_HANDLE        ((LONG)0x80100003) /**< The supplied handle was invalid. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_PARAMETER    ((LONG)0x80100004) /**< One or more of the supplied parameters could not be properly interpreted. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_TARGET        ((LONG)0x80100005) /**< Registry startup information is missing or invalid. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_MEMORY        ((LONG)0x80100006) /**< Not enough memory available to complete this command. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_F_WAITED_TOO_LONG        ((LONG)0x80100007) /**< An internal consistency timer has expired. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INSUFFICIENT_BUFFER    ((LONG)0x80100008) /**< The data buffer to receive returned data is too small for the returned data. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_UNKNOWN_READER        ((LONG)0x80100009) /**< The specified reader name is not recognized. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_TIMEOUT            ((LONG)0x8010000A) /**< The user-specified timeout value has expired. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_SHARING_VIOLATION    ((LONG)0x8010000B) /**< The smart card cannot be accessed because of other connections outstanding. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_SMARTCARD        ((LONG)0x8010000C) /**< The operation requires a Smart Card, but no Smart Card is currently in the device. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_UNKNOWN_CARD        ((LONG)0x8010000D) /**< The specified smart card name is not recognized. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_CANT_DISPOSE        ((LONG)0x8010000E) /**< The system could not dispose of the media in the requested manner. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_PROTO_MISMATCH        ((LONG)0x8010000F) /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NOT_READY        ((LONG)0x80100010) /**< The reader or smart card is not ready to accept commands. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_VALUE        ((LONG)0x80100011) /**< One or more of the supplied parameters values could not be properly interpreted. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_SYSTEM_CANCELLED    ((LONG)0x80100012) /**< The action was cancelled by the system, presumably to log off or shut down. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_F_COMM_ERROR        ((LONG)0x80100013) /**< An internal communications error has been detected. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_F_UNKNOWN_ERROR        ((LONG)0x80100014) /**< An internal error has been detected, but the source is unknown. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_ATR        ((LONG)0x80100015) /**< An ATR obtained from the registry is not a valid ATR string. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NOT_TRANSACTED        ((LONG)0x80100016) /**< An attempt was made to end a non-existent transaction. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_READER_UNAVAILABLE    ((LONG)0x80100017) /**< The specified reader is not currently available for use. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_P_SHUTDOWN        ((LONG)0x80100018) /**< The operation has been aborted to allow the server application to exit. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_PCI_TOO_SMALL        ((LONG)0x80100019) /**< The PCI Receive buffer was too small. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_READER_UNSUPPORTED    ((LONG)0x8010001A) /**< The reader driver does not meet minimal requirements for support. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_DUPLICATE_READER    ((LONG)0x8010001B) /**< The reader driver did not produce a unique reader name. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_CARD_UNSUPPORTED    ((LONG)0x8010001C) /**< The smart card does not meet minimal requirements for support. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_SERVICE        ((LONG)0x8010001D) /**< The Smart card resource manager is not running. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_SERVICE_STOPPED        ((LONG)0x8010001E) /**< The Smart card resource manager has shut down. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_UNEXPECTED        ((LONG)0x8010001F) /**< An unexpected card error has occurred. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_UNSUPPORTED_FEATURE    ((LONG)0x8010001F) /**< This smart card does not support the requested feature. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_ICC_INSTALLATION    ((LONG)0x80100020) /**< No primary provider can be found for the smart card. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_ICC_CREATEORDER        ((LONG)0x80100021) /**< The requested order of object creation is not supported. */
    +/** @ingroup ErrorCodes */
    +/* #define SCARD_E_UNSUPPORTED_FEATURE    ((LONG)0x80100022) / **< This smart card does not support the requested feature. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_DIR_NOT_FOUND        ((LONG)0x80100023) /**< The identified directory does not exist in the smart card. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_FILE_NOT_FOUND        ((LONG)0x80100024) /**< The identified file does not exist in the smart card. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_DIR            ((LONG)0x80100025) /**< The supplied path does not represent a smart card directory. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_FILE            ((LONG)0x80100026) /**< The supplied path does not represent a smart card file. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_ACCESS        ((LONG)0x80100027) /**< Access is denied to this file. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_WRITE_TOO_MANY        ((LONG)0x80100028) /**< The smart card does not have enough memory to store the information. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_BAD_SEEK        ((LONG)0x80100029) /**< There was an error trying to set the smart card file object pointer. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_INVALID_CHV        ((LONG)0x8010002A) /**< The supplied PIN is incorrect. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_UNKNOWN_RES_MNG        ((LONG)0x8010002B) /**< An unrecognized error code was returned from a layered component. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_SUCH_CERTIFICATE    ((LONG)0x8010002C) /**< The requested certificate does not exist. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_CERTIFICATE_UNAVAILABLE    ((LONG)0x8010002D) /**< The requested certificate could not be obtained. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_READERS_AVAILABLE    ((LONG)0x8010002E) /**< Cannot find a smart card reader. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_COMM_DATA_LOST        ((LONG)0x8010002F) /**< A communications error with the smart card has been detected. Retry the operation. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_NO_KEY_CONTAINER    ((LONG)0x80100030) /**< The requested key container does not exist on the smart card. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_E_SERVER_TOO_BUSY        ((LONG)0x80100031) /**< The Smart Card Resource Manager is too busy to complete this operation. */
    +
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_UNSUPPORTED_CARD    ((LONG)0x80100065) /**< The reader cannot communicate with the card, due to ATR string configuration conflicts. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_UNRESPONSIVE_CARD    ((LONG)0x80100066) /**< The smart card is not responding to a reset. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_UNPOWERED_CARD        ((LONG)0x80100067) /**< Power has been removed from the smart card, so that further communication is not possible. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_RESET_CARD        ((LONG)0x80100068) /**< The smart card has been reset, so any shared state information is invalid. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_REMOVED_CARD        ((LONG)0x80100069) /**< The smart card has been removed, so further communication is not possible. */
    +
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_SECURITY_VIOLATION    ((LONG)0x8010006A) /**< Access was denied because of a security violation. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_WRONG_CHV        ((LONG)0x8010006B) /**< The card cannot be accessed because the wrong PIN was presented. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_CHV_BLOCKED        ((LONG)0x8010006C) /**< The card cannot be accessed because the maximum number of PIN entry attempts has been reached. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_EOF            ((LONG)0x8010006D) /**< The end of the smart card file has been reached. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_CANCELLED_BY_USER    ((LONG)0x8010006E) /**< The user pressed "Cancel" on a Smart Card Selection Dialog. */
    +/** @ingroup ErrorCodes */
    +#define SCARD_W_CARD_NOT_AUTHENTICATED    ((LONG)0x8010006F) /**< No PIN was presented to the smart card. */
    +
    +#define SCARD_AUTOALLOCATE (DWORD)(-1)    /**< see SCardFreeMemory() */
    +#define SCARD_SCOPE_USER        0x0000    /**< Scope in user space */
    +#define SCARD_SCOPE_TERMINAL        0x0001    /**< Scope in terminal */
    +#define SCARD_SCOPE_SYSTEM        0x0002    /**< Scope in system */
    +#define SCARD_SCOPE_GLOBAL        0x0003    /**< Scope is global */
    +
    +#define SCARD_PROTOCOL_UNDEFINED    0x0000    /**< protocol not set */
    +#define SCARD_PROTOCOL_UNSET SCARD_PROTOCOL_UNDEFINED    /* backward compat */
    +#define SCARD_PROTOCOL_T0        0x0001    /**< T=0 active protocol. */
    +#define SCARD_PROTOCOL_T1        0x0002    /**< T=1 active protocol. */
    +#define SCARD_PROTOCOL_RAW        0x0004    /**< Raw active protocol. */
    +#define SCARD_PROTOCOL_T15        0x0008    /**< T=15 protocol. */
    +
    +#define SCARD_PROTOCOL_ANY        (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1)    /**< IFD determines prot. */
    +
    +#define SCARD_SHARE_EXCLUSIVE        0x0001    /**< Exclusive mode only */
    +#define SCARD_SHARE_SHARED        0x0002    /**< Shared mode only */
    +#define SCARD_SHARE_DIRECT        0x0003    /**< Raw mode only */
    +
    +#define SCARD_LEAVE_CARD        0x0000    /**< Do nothing on close */
    +#define SCARD_RESET_CARD        0x0001    /**< Reset on close */
    +#define SCARD_UNPOWER_CARD        0x0002    /**< Power down on close */
    +#define SCARD_EJECT_CARD        0x0003    /**< Eject on close */
    +
    +#define SCARD_UNKNOWN            0x0001    /**< Unknown state */
    +#define SCARD_ABSENT            0x0002    /**< Card is absent */
    +#define SCARD_PRESENT            0x0004    /**< Card is present */
    +#define SCARD_SWALLOWED            0x0008    /**< Card not powered */
    +#define SCARD_POWERED            0x0010    /**< Card is powered */
    +#define SCARD_NEGOTIABLE        0x0020    /**< Ready for PTS */
    +#define SCARD_SPECIFIC            0x0040    /**< PTS has been set */
    +
    +#define SCARD_STATE_UNAWARE        0x0000    /**< App wants status */
    +#define SCARD_STATE_IGNORE        0x0001    /**< Ignore this reader */
    +#define SCARD_STATE_CHANGED        0x0002    /**< State has changed */
    +#define SCARD_STATE_UNKNOWN        0x0004    /**< Reader unknown */
    +#define SCARD_STATE_UNAVAILABLE        0x0008    /**< Status unavailable */
    +#define SCARD_STATE_EMPTY        0x0010    /**< Card removed */
    +#define SCARD_STATE_PRESENT        0x0020    /**< Card inserted */
    +#define SCARD_STATE_ATRMATCH        0x0040    /**< ATR matches card */
    +#define SCARD_STATE_EXCLUSIVE        0x0080    /**< Exclusive Mode */
    +#define SCARD_STATE_INUSE        0x0100    /**< Shared Mode */
    +#define SCARD_STATE_MUTE        0x0200    /**< Unresponsive card */
    +#define SCARD_STATE_UNPOWERED        0x0400    /**< Unpowered card */
    +
    +#ifndef INFINITE
    +#define INFINITE            0xFFFFFFFF    /**< Infinite timeout */
    +#endif
    +
    +#define PCSCLITE_VERSION_NUMBER        "1.9.5"    /**< Current version */
    +/** Maximum readers context (a slot is count as a reader) */
    +#define PCSCLITE_MAX_READERS_CONTEXTS            16
    +
    +#define MAX_READERNAME            128
    +
    +#ifndef SCARD_ATR_LENGTH
    +#define SCARD_ATR_LENGTH        MAX_ATR_SIZE    /**< Maximum ATR size */
    +#endif
    +
    +/*
    + * The message and buffer sizes must be multiples of 16.
    + * The max message size must be at least large enough
    + * to accomodate the transmit_struct
    + */
    +#define MAX_BUFFER_SIZE            264    /**< Maximum Tx/Rx Buffer for short APDU */
    +#define MAX_BUFFER_SIZE_EXTENDED    (4 + 3 + (1<<16) + 3 + 2)    /**< enhanced (64K + APDU + Lc + Le + SW) Tx/Rx Buffer */
    +
    +/*
    + * Gets a stringified error response
    + */
    +const char *pcsc_stringify_error(const LONG);
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif
    diff -Nru openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h
    --- openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/winscard.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,122 @@
    +/*
    + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
    + *
    + * Copyright (C) 1999-2003
    + *  David Corcoran 
    + * Copyright (C) 2002-2009
    + *  Ludovic Rousseau 
    + *
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions
    +are met:
    +
    +1. Redistributions of source code must retain the above copyright
    +   notice, this list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright
    +   notice, this list of conditions and the following disclaimer in the
    +   documentation and/or other materials provided with the distribution.
    +3. The name of the author may not be used to endorse or promote products
    +   derived from this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + * @file
    + * @brief This handles smart card reader communications.
    + */
    +
    +#ifndef __winscard_h__
    +#define __winscard_h__
    +
    +#include 
    +
    +#ifdef __cplusplus
    +extern "C"
    +{
    +#endif
    +
    +#ifndef PCSC_API
    +#define PCSC_API
    +#endif
    +
    +    PCSC_API LONG SCardEstablishContext(DWORD dwScope,
    +        /*@null@*/ LPCVOID pvReserved1, /*@null@*/ LPCVOID pvReserved2,
    +        /*@out@*/ LPSCARDCONTEXT phContext);
    +
    +    PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext);
    +
    +    PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext);
    +
    +    PCSC_API LONG SCardConnect(SCARDCONTEXT hContext,
    +        LPCSTR szReader,
    +        DWORD dwShareMode,
    +        DWORD dwPreferredProtocols,
    +        /*@out@*/ LPSCARDHANDLE phCard, /*@out@*/ LPDWORD pdwActiveProtocol);
    +
    +    PCSC_API LONG SCardReconnect(SCARDHANDLE hCard,
    +        DWORD dwShareMode,
    +        DWORD dwPreferredProtocols,
    +        DWORD dwInitialization, /*@out@*/ LPDWORD pdwActiveProtocol);
    +
    +    PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition);
    +
    +    PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard);
    +
    +    PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition);
    +
    +    PCSC_API LONG SCardStatus(SCARDHANDLE hCard,
    +        /*@null@*/ /*@out@*/ LPSTR mszReaderName,
    +        /*@null@*/ /*@out@*/ LPDWORD pcchReaderLen,
    +        /*@null@*/ /*@out@*/ LPDWORD pdwState,
    +        /*@null@*/ /*@out@*/ LPDWORD pdwProtocol,
    +        /*@null@*/ /*@out@*/ LPBYTE pbAtr,
    +        /*@null@*/ /*@out@*/ LPDWORD pcbAtrLen);
    +
    +    PCSC_API LONG SCardGetStatusChange(SCARDCONTEXT hContext,
    +        DWORD dwTimeout,
    +        SCARD_READERSTATE *rgReaderStates, DWORD cReaders);
    +
    +    PCSC_API LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
    +        LPCVOID pbSendBuffer, DWORD cbSendLength,
    +        /*@out@*/ LPVOID pbRecvBuffer, DWORD cbRecvLength,
    +        LPDWORD lpBytesReturned);
    +
    +    PCSC_API LONG SCardTransmit(SCARDHANDLE hCard,
    +        const SCARD_IO_REQUEST *pioSendPci,
    +        LPCBYTE pbSendBuffer, DWORD cbSendLength,
    +        /*@out@*/ SCARD_IO_REQUEST *pioRecvPci,
    +        /*@out@*/ LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
    +
    +    PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext,
    +        /*@out@*/ LPSTR mszGroups, LPDWORD pcchGroups);
    +
    +    PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext,
    +        /*@null@*/ /*@out@*/ LPCSTR mszGroups,
    +        /*@null@*/ /*@out@*/ LPSTR mszReaders,
    +        /*@out@*/ LPDWORD pcchReaders);
    +
    +    PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem);
    +
    +    PCSC_API LONG SCardCancel(SCARDCONTEXT hContext);
    +
    +    PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
    +        /*@out@*/ LPBYTE pbAttr, LPDWORD pcbAttrLen);
    +
    +    PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
    +        LPCBYTE pbAttr, DWORD cbAttrLen);
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif
    diff -Nru openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h
    --- openjdk-17-17.0.5+8/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/wintypes.h	2023-01-10 13:21:55.000000000 +0000
    @@ -0,0 +1,115 @@
    +/*
    + * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
    + *
    + * Copyright (C) 1999
    + *  David Corcoran 
    + * Copyright (C) 2002-2011
    + *  Ludovic Rousseau 
    + *
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions
    +are met:
    +
    +1. Redistributions of source code must retain the above copyright
    +   notice, this list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright
    +   notice, this list of conditions and the following disclaimer in the
    +   documentation and/or other materials provided with the distribution.
    +3. The name of the author may not be used to endorse or promote products
    +   derived from this software without specific prior written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + */
    +
    +/**
    + * @file
    + * @brief This keeps a list of Windows(R) types.
    + */
    +
    +#ifndef __wintypes_h__
    +#define __wintypes_h__
    +
    +#ifdef __cplusplus
    +extern "C"
    +{
    +#endif
    +
    +#ifdef __APPLE__
    +
    +#include 
    +
    +#ifndef BYTE
    +    typedef uint8_t BYTE;
    +#endif
    +    typedef uint8_t UCHAR;
    +    typedef UCHAR *PUCHAR;
    +    typedef uint16_t USHORT;
    +
    +#ifndef __COREFOUNDATION_CFPLUGINCOM__
    +    typedef uint32_t ULONG;
    +    typedef void *LPVOID;
    +    typedef int16_t BOOL;
    +#endif
    +
    +    typedef ULONG *PULONG;
    +    typedef const void *LPCVOID;
    +    typedef uint32_t DWORD;
    +    typedef DWORD *PDWORD;
    +    typedef uint16_t WORD;
    +    typedef int32_t LONG;
    +    typedef const char *LPCSTR;
    +    typedef const BYTE *LPCBYTE;
    +    typedef BYTE *LPBYTE;
    +    typedef DWORD *LPDWORD;
    +    typedef char *LPSTR;
    +
    +#else
    +
    +#ifndef BYTE
    +    typedef unsigned char BYTE;
    +#endif
    +    typedef unsigned char UCHAR;
    +    typedef UCHAR *PUCHAR;
    +    typedef unsigned short USHORT;
    +
    +#ifndef __COREFOUNDATION_CFPLUGINCOM__
    +    typedef unsigned long ULONG;
    +    typedef void *LPVOID;
    +#endif
    +
    +    typedef const void *LPCVOID;
    +    typedef unsigned long DWORD;
    +    typedef DWORD *PDWORD;
    +    typedef long LONG;
    +    typedef const char *LPCSTR;
    +    typedef const BYTE *LPCBYTE;
    +    typedef BYTE *LPBYTE;
    +    typedef DWORD *LPDWORD;
    +    typedef char *LPSTR;
    +
    +    /* these types were deprecated but still used by old drivers and
    +     * applications. So just declare and use them. */
    +    typedef LPSTR LPTSTR;
    +    typedef LPCSTR LPCTSTR;
    +
    +    /* types unused by pcsc-lite */
    +    typedef short BOOL;
    +    typedef unsigned short WORD;
    +    typedef ULONG *PULONG;
    +
    +#endif
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +
    +#endif
    diff -Nru openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java
    --- openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttributeMap.java	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
      */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
    @@ -39,7 +39,7 @@
      *
      * @xerces.internal
      *
    - * @LastModified: Oct 2017
    + * @LastModified: June 2022
      */
     public class AttributeMap extends NamedNodeMapImpl {
     
    @@ -117,7 +117,7 @@
             } else {
                 i = -1 - i; // Insert point (may be end of list)
                 if (null == nodes) {
    -                nodes = new ArrayList<>(5);
    +                nodes = new ArrayList<>();
                 }
                 nodes.add(i, arg);
             }
    @@ -193,7 +193,7 @@
                 } else {
                     i = -1 - i; // Insert point (may be end of list)
                     if (null == nodes) {
    -                    nodes = new ArrayList<>(5);
    +                    nodes = new ArrayList<>();
                     }
                     nodes.add(i, arg);
                 }
    @@ -591,7 +591,7 @@
                 else {
                     i = -1 - i; // Insert point (may be end of list)
                     if (null == nodes) {
    -                    nodes = new ArrayList<>(5);
    +                    nodes = new ArrayList<>();
                     }
                     nodes.add(i, arg);
                 }
    diff -Nru openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java
    --- openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
      */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
    @@ -89,7 +89,7 @@
      *
      * @author Elena Litani, IBM
      * @author Neeraj Bajaj, Sun Microsystems, inc.
    - * @LastModified: Apr 2019
    + * @LastModified: June 2022
      */
     public class DOMNormalizer implements XMLDocumentHandler {
     
    @@ -140,9 +140,6 @@
         /** Stores all namespace bindings on the current element */
         protected final NamespaceContext fLocalNSBinder = new NamespaceSupport();
     
    -    /** list of attributes */
    -    protected final List fAttributeList = new ArrayList<>(5);
    -
         /** DOM Locator -  for namespace fixup algorithm */
         protected final DOMLocatorImpl fLocator = new DOMLocatorImpl();
     
    @@ -885,9 +882,9 @@
             if (attributes != null) {
     
                 // clone content of the attributes
    -            attributes.cloneMap(fAttributeList);
    -            for (int i = 0; i < fAttributeList.size(); i++) {
    -                Attr attr = (Attr) fAttributeList.get(i);
    +            List attrList = attributes.cloneMap(new ArrayList<>());
    +            for (int i = 0; i < attrList.size(); i++) {
    +                Attr attr = (Attr) attrList.get(i);
                     fLocator.fRelatedNode = attr;
     
                     if (DEBUG) {
    diff -Nru openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java
    --- openjdk-17-17.0.5+8/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
      */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
    @@ -56,7 +56,7 @@
      * @xerces.internal
      *
      * @since  PR-DOM-Level-1-19980818.
    - * @LastModified: Jan 2018
    + * @LastModified: June 2022
      */
     public class NamedNodeMapImpl
         implements NamedNodeMap, Serializable {
    @@ -196,7 +196,7 @@
             } else {
                 i = -1 - i; // Insert point (may be end of list)
                 if (null == nodes) {
    -                nodes = new ArrayList<>(5);
    +                nodes = new ArrayList<>();
                 }
                 nodes.add(i, arg);
             }
    @@ -246,7 +246,7 @@
                 } else {
                     i = -1 - i; // Insert point (may be end of list)
                     if (null == nodes) {
    -                    nodes = new ArrayList<>(5);
    +                    nodes = new ArrayList<>();
                     }
                     nodes.add(i, arg);
                 }
    @@ -561,7 +561,7 @@
                 else {
                     i = -1 - i; // Insert point (may be end of list)
                     if (null == nodes) {
    -                    nodes = new ArrayList<>(5);
    +                    nodes = new ArrayList<>();
                     }
                     nodes.add(i, arg);
                 }
    diff -Nru openjdk-17-17.0.5+8/src/java.xml/share/legal/dom.md openjdk-17-17.0.6+10/src/java.xml/share/legal/dom.md
    --- openjdk-17-17.0.5+8/src/java.xml/share/legal/dom.md	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.xml/share/legal/dom.md	2023-01-10 13:21:55.000000000 +0000
    @@ -1,5 +1,20 @@
     ## DOM Level 3 Core Specification v1.0
     
    +### W3C Software Notice
    +
    +Copyright © 2004 World Wide Web Consortium, (Massachusetts Institute of Technology,
    +European Research Consortium for Informatics and Mathematics, Keio University).
    +All Rights Reserved.
    +
    +The DOM bindings are published under the W3C Software Copyright Notice and License.
    +The software license requires "Notice of any changes or modifications to the W3C
    +files, including the date changes were made." Consequently, modified versions of
    +the DOM bindings must document that they do not conform to the W3C standard; in the
    +case of the IDL definitions, the pragma prefix can no longer be 'w3c.org'; in the
    +case of the Java language binding, the package names can no longer be in the
    +'org.w3c' package.
    +
    + ### W3C License
     
    diff -Nru openjdk-17-17.0.5+8/src/java.xml/share/legal/jcup.md openjdk-17-17.0.6+10/src/java.xml/share/legal/jcup.md
    --- openjdk-17-17.0.5+8/src/java.xml/share/legal/jcup.md	2022-10-10 13:07:22.000000000 +0000
    +++ openjdk-17-17.0.6+10/src/java.xml/share/legal/jcup.md	2023-01-10 13:21:55.000000000 +0000
    @@ -1,8 +1,8 @@
     ## CUP Parser Generator for Java v 0.11b
     
     ### CUP Parser Generator License
    -
     
    +```
     Copyright 1996-2015 by Scott Hudson, Frank Flannery, C. Scott Ananian, Michael Petter
     
     Permission to use, copy, modify, and distribute this software and its
    @@ -20,5 +20,12 @@
     resulting from loss of use, data or profits, whether in an action of
     contract, negligence or other tortious action, arising out of or in
     connection with the use or performance of this software.
    +```
    +---
    +```
    +This is an open source license. It is also GPL-Compatible (see entry for
    +"Standard ML of New Jersey"). The portions of CUP output which are hard-coded
    +into the CUP source code are (naturally) covered by this same license, as is
    +the CUP runtime code linked with the generated parser.
    +```
     
    -
    diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java 2023-01-10 13:21:55.000000000 +0000 @@ -862,7 +862,7 @@ Type itype = attribExpr(variable.init, env, type); if (variable.isImplicitlyTyped()) { //fixup local variable type - type = variable.type = variable.sym.type = chk.checkLocalVarType(variable, itype.baseType(), variable.name); + type = variable.type = variable.sym.type = chk.checkLocalVarType(variable, itype, variable.name); } if (itype.constValue() != null) { return coerce(itype, type).constValue(); @@ -1314,7 +1314,7 @@ attribExpr(tree.init, initEnv, v.type); if (tree.isImplicitlyTyped()) { //fixup local variable type - v.type = chk.checkLocalVarType(tree, tree.init.type.baseType(), tree.name); + v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name); } } if (tree.isImplicitlyTyped()) { @@ -2594,7 +2594,7 @@ argtypes.isEmpty()) { // as a special case, x.getClass() has type Class return new ClassType(restype.getEnclosingType(), - List.of(new WildcardType(types.erasure(qualifierType), + List.of(new WildcardType(types.erasure(qualifierType.baseType()), BoundKind.EXTENDS, syms.boundClass)), restype.tsym, diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java 2023-01-10 13:21:55.000000000 +0000 @@ -985,7 +985,7 @@ } //upward project the initializer type - return types.upward(t, types.captures(t)); + return types.upward(t, types.captures(t)).baseType(); } Type checkMethod(final Type mtype, diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java 2023-01-10 13:21:55.000000000 +0000 @@ -3656,7 +3656,9 @@ List typeargtypes, MethodResolutionPhase maxPhase) { super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); if (site.isRaw()) { - this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata()); + this.site = new ClassType(site.getEnclosingType(), + !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ? + site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata()); needsInference = true; } } diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java 2023-01-10 13:21:55.000000000 +0000 @@ -341,9 +341,8 @@ JCCase lastCase = cases.last(); if (hasTotalPattern && !hasNullCase) { - JCCase last = lastCase; - if (last.labels.stream().noneMatch(l -> l.hasTag(Tag.DEFAULTCASELABEL))) { - last.labels = last.labels.prepend(makeLit(syms.botType, null)); + if (cases.stream().flatMap(c -> c.labels.stream()).noneMatch(l -> l.hasTag(Tag.DEFAULTCASELABEL))) { + lastCase.labels = lastCase.labels.prepend(makeLit(syms.botType, null)); hasNullCase = true; } } diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ReferenceParser.java 2023-01-10 13:21:55.000000000 +0000 @@ -25,6 +25,9 @@ package com.sun.tools.javac.parser; +import com.sun.source.tree.AnnotatedTypeTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreeScanner; import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.List; @@ -193,6 +196,21 @@ if (p.token().kind != TokenKind.EOF) throw new ParseException("dc.ref.unexpected.input"); + if (new TypeAnnotationFinder().scan(paramTypes, null) != null) + throw new ParseException("dc.ref.annotations.not.allowed"); + return paramTypes.toList(); } -} + + static class TypeAnnotationFinder extends TreeScanner { + @Override + public Tree visitAnnotatedType(AnnotatedTypeTree t, Void ignore) { + return t; + } + + @Override + public Tree reduce(Tree t1, Tree t2) { + return t1 != null ? t1 : t2; + } + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties 2023-01-10 13:21:55.000000000 +0000 @@ -3269,6 +3269,9 @@ compiler.err.dc.unterminated.string=\ unterminated string +compiler.err.dc.ref.annotations.not.allowed=\ + annotations not allowed + ### # errors related to modules diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties 2023-01-10 13:21:55.000000000 +0000 @@ -208,7 +208,7 @@ javac.msg.usage.nonstandard.footer=\u3053\u306E\u8FFD\u52A0\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002 -javac.msg.bug=\u30B3\u30F3\u30D1\u30A4\u30E9\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F({0})\u3002Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8(http://bugreport.java.com)\u3067Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3001\u4E0B\u8A18\u306E\u8A3A\u65AD\u5185\u5BB9\u3001\u304A\u3088\u3073Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u6E21\u3057\u305F\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 +javac.msg.bug=\u30B3\u30F3\u30D1\u30A4\u30E9\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F({0})\u3002Bug Database (https://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8(https://bugreport.java.com)\u3067Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3001\u4E0B\u8A18\u306E\u8A3A\u65AD\u5185\u5BB9\u3001\u304A\u3088\u3073Java\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u6E21\u3057\u305F\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 javac.msg.io=\n\n\u5165\u51FA\u529B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\n\u8A73\u7D30\u306F\u6B21\u306E\u30B9\u30BF\u30C3\u30AF\u30C8\u30EC\u30FC\u30B9\u3067\u8ABF\u67FB\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties 2023-01-10 13:21:55.000000000 +0000 @@ -363,8 +363,8 @@ javac.msg.bug=\ An exception has occurred in the compiler ({0}). \ -Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) \ -after checking the Bug Database (http://bugs.java.com) for duplicates. \ +Please file a bug against the Java compiler via the Java bug reporting page (https://bugreport.java.com) \ +after checking the Bug Database (https://bugs.java.com) for duplicates. \ Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you. javac.msg.io=\ diff -Nru openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties --- openjdk-17-17.0.5+8/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties 2023-01-10 13:21:55.000000000 +0000 @@ -208,7 +208,7 @@ javac.msg.usage.nonstandard.footer=\u8FD9\u4E9B\u989D\u5916\u9009\u9879\u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002 -javac.msg.bug=\u7F16\u8BD1\u5668 ({0}) \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF\uFF0C\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u5EFA\u7ACB\u8BE5 Java \u7F16\u8BD1\u5668 Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u3001\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u4EE5\u53CA\u4F20\u9012\u5230 Java \u7F16\u8BD1\u5668\u7684\u53C2\u6570\u3002\u8C22\u8C22\u3002 +javac.msg.bug=\u7F16\u8BD1\u5668 ({0}) \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Bug Database (https://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF\uFF0C\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (https://bugreport.java.com) \u5EFA\u7ACB\u8BE5 Java \u7F16\u8BD1\u5668 Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u3001\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u4EE5\u53CA\u4F20\u9012\u5230 Java \u7F16\u8BD1\u5668\u7684\u53C2\u6570\u3002\u8C22\u8C22\u3002 javac.msg.io=\n\n\u53D1\u751F\u8F93\u5165/\u8F93\u51FA\u9519\u8BEF\u3002\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u53C2\u9605\u4EE5\u4E0B\u5806\u6808\u8DDF\u8E2A\u3002\n diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java 2023-01-10 13:21:55.000000000 +0000 @@ -358,7 +358,7 @@ try { return PropertyExpander.expand(s); } catch (Exception e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e.getMessage(), e); } } @@ -396,6 +396,10 @@ return new ConfigurationException(msg + ", line " + st.lineno()); } + private ConfigurationException excLine(String msg, Throwable e) { + return new ConfigurationException(msg + ", line " + st.lineno(), e); + } + private void parse() throws IOException { while (true) { int token = nextToken(); @@ -792,7 +796,7 @@ try { return Functions.getMechanismId(mech); } catch (IllegalArgumentException e) { - throw excLine("Unknown mechanism: " + mech); + throw excLine("Unknown mechanism: " + mech, e); } } } @@ -952,7 +956,7 @@ try { return Functions.getObjectClassId(name); } catch (IllegalArgumentException e) { - throw excLine("Unknown object class " + name); + throw excLine("Unknown object class " + name, e); } } @@ -964,7 +968,7 @@ try { return Functions.getKeyId(name); } catch (IllegalArgumentException e) { - throw excLine("Unknown key algorithm " + name); + throw excLine("Unknown key algorithm " + name, e); } } } @@ -976,7 +980,7 @@ try { return Functions.getAttributeId(name); } catch (IllegalArgumentException e) { - throw excLine("Unknown attribute name " + name); + throw excLine("Unknown attribute name " + name, e); } } } @@ -1032,4 +1036,8 @@ ConfigurationException(String msg) { super(msg); } + + ConfigurationException(String msg, Throwable e) { + super(msg, e); + } } diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -140,7 +140,7 @@ try { engineSetPadding(algoParts[2]); } catch (NoSuchPaddingException e) { - throw new NoSuchAlgorithmException(); + throw new NoSuchAlgorithmException(e); } } else if (algoParts[0].equals("ChaCha20-Poly1305")) { fixedKeySize = 32; diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -808,13 +808,21 @@ if (paddingObj != null) { int startOff = 0; if (reqBlockUpdates) { - startOff = padBufferLen; + // call C_EncryptUpdate first if the padBuffer is full + // to make room for padding bytes + if (padBufferLen == padBuffer.length) { + k = token.p11.C_EncryptUpdate(session.id(), + 0, padBuffer, 0, padBufferLen, + 0, out, outOfs, outLen); + } else { + startOff = padBufferLen; + } } int actualPadLen = paddingObj.setPaddingBytes(padBuffer, startOff, requiredOutLen - bytesBuffered); - k = token.p11.C_EncryptUpdate(session.id(), + k += token.p11.C_EncryptUpdate(session.id(), 0, padBuffer, 0, startOff + actualPadLen, - 0, out, outOfs, outLen); + 0, out, outOfs + k, outLen - k); } // Some implementations such as the NSS Software Token do not // cancel the operation upon a C_EncryptUpdate failure (as @@ -896,13 +904,21 @@ if (paddingObj != null) { int startOff = 0; if (reqBlockUpdates) { - startOff = padBufferLen; + // call C_EncryptUpdate first if the padBuffer is full + // to make room for padding bytes + if (padBufferLen == padBuffer.length) { + k = token.p11.C_EncryptUpdate(session.id(), + 0, padBuffer, 0, padBufferLen, + outAddr, outArray, outOfs, outLen); + } else { + startOff = padBufferLen; + } } int actualPadLen = paddingObj.setPaddingBytes(padBuffer, startOff, requiredOutLen - bytesBuffered); - k = token.p11.C_EncryptUpdate(session.id(), + k += token.p11.C_EncryptUpdate(session.id(), 0, padBuffer, 0, startOff + actualPadLen, - outAddr, outArray, outOfs, outLen); + outAddr, outArray, outOfs + k, outLen - k); } // Some implementations such as the NSS Software Token do not // cancel the operation upon a C_EncryptUpdate failure (as diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java 2023-01-10 13:21:55.000000000 +0000 @@ -145,7 +145,7 @@ try { checkKeySize(keySize, null); } catch (InvalidAlgorithmParameterException e) { - throw new InvalidParameterException(e.getMessage()); + throw (InvalidParameterException) new InvalidParameterException(e.getMessage()).initCause(e); } this.params = null; if (algorithm.equals("EC")) { diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java 2023-01-10 13:21:55.000000000 +0000 @@ -1323,7 +1323,7 @@ RSAKeyFactory.checkKeyLengths(keyLength, null, -1, Integer.MAX_VALUE); } catch (InvalidKeyException e) { - throw new KeyStoreException(e.getMessage()); + throw new KeyStoreException(e.getMessage(), e); } return P11Key.privateKey(session, diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -569,10 +569,10 @@ case T_UPDATE: try { if (mode == M_SIGN) { - System.out.println(this + ": Calling C_SignUpdate"); + if (DEBUG) System.out.println(this + ": Calling C_SignUpdate"); token.p11.C_SignUpdate(session.id(), 0, b, ofs, len); } else { - System.out.println(this + ": Calling C_VerfifyUpdate"); + if (DEBUG) System.out.println(this + ": Calling C_VerfifyUpdate"); token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len); } bytesProcessed += len; @@ -618,11 +618,11 @@ int ofs = byteBuffer.position(); try { if (mode == M_SIGN) { - System.out.println(this + ": Calling C_SignUpdate"); + if (DEBUG) System.out.println(this + ": Calling C_SignUpdate"); token.p11.C_SignUpdate (session.id(), addr + ofs, null, 0, len); } else { - System.out.println(this + ": Calling C_VerifyUpdate"); + if (DEBUG) System.out.println(this + ": Calling C_VerifyUpdate"); token.p11.C_VerifyUpdate (session.id(), addr + ofs, null, 0, len); } diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java 2023-01-10 13:21:55.000000000 +0000 @@ -433,7 +433,7 @@ padding = RSAPadding.getInstance (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3); } catch (InvalidAlgorithmParameterException iape) { - throw new InvalidKeyException(iape.getMessage()); + throw new InvalidKeyException(iape.getMessage(), iape); } int maxDataSize = padding.getMaxDataSize(); int encodedLength = switch (algorithm) { @@ -804,7 +804,7 @@ DerValue result = new DerValue(DerValue.tag_Sequence, outseq.toByteArray()); return result.toByteArray(); - } catch (java.io.IOException e) { + } catch (IOException e) { throw new RuntimeException("Internal error", e); } } diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -207,7 +207,12 @@ // will be added to correct pool on release, nothing to do now return; } - opSessions.release(session); + // Objects could have been added to this session by other thread between + // check in Session.removeObject method and objSessions.remove call + // higher. Therefore releaseSession method, which performs additional + // check for objects, is used here to avoid placing this session + // in wrong pool due to race condition. + releaseSession(session); } private Session openSession() throws PKCS11Exception { diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java --- openjdk-17-17.0.5+8/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java 2023-01-10 13:21:55.000000000 +0000 @@ -209,14 +209,37 @@ } }; + public static enum RV_VENDOR { + // NSS + CKR_NSS_CERTDB_FAILED(0xCE534351L), + CKR_NSS_KEYDB_FAILED(0xCE534352L); + + private final long value; + + RV_VENDOR(long value) { + this.value = value; + } + }; + private static String lookup(long errorCode) { for (RV r : RV.values()) { if (r.value == errorCode) { return r.name(); } } - // for unknown PKCS11 return values, just use hex as its string - return "0x" + Functions.toFullHexString((int)errorCode); + // for unknown PKCS11 return values, use hex as its string + String res = "0x" + Functions.toFullHexString((int)errorCode); + // for vendor-defined values, check the enum for vendors and include + // potential matches + if ((errorCode & 0x80000000L) != 0) { + for (RV_VENDOR r : RV_VENDOR.values()) { + if (r.value == errorCode) { + res += "(" + r.name() + ")"; + break; + } + } + } + return res; } /** diff -Nru openjdk-17-17.0.5+8/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp openjdk-17-17.0.6+10/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp --- openjdk-17-17.0.5+8/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -128,22 +128,43 @@ } } +void ThrowExceptionWithMessageAndErrcode(JNIEnv *env, const char *exceptionName, + const char *msg, DWORD dwError) { + char szMessage[500]; + szMessage[0] = '\0'; + char szMessage2[1024]; + szMessage2[0] = '\0'; + + DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, + NULL, szMessage, sizeof(szMessage), NULL); + if (res == 0) { + strcpy(szMessage, "Unknown error"); + } + snprintf(szMessage2, sizeof(szMessage2), "%s: error %lu, %s", msg, dwError, szMessage); + + ThrowExceptionWithMessage(env, exceptionName, szMessage2); +} + + /* * Throws an arbitrary Java exception. * The exception message is a Windows system error message. */ void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError) { - char szMessage[1024]; + char szMessage[500]; szMessage[0] = '\0'; + char szMessage2[1024]; + szMessage2[0] = '\0'; DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, NULL, szMessage, sizeof(szMessage), NULL); if (res == 0) { strcpy(szMessage, "Unknown error"); } + snprintf(szMessage2, sizeof(szMessage2), "error %lu, %s", dwError, szMessage); - ThrowExceptionWithMessage(env, exceptionName, szMessage); + ThrowExceptionWithMessage(env, exceptionName, szMessage2); } /* @@ -1834,8 +1855,7 @@ // Destroying the default key container is not permitted // (because it may contain more one keypair). if (pszKeyContainerName == NULL) { - - ThrowException(env, KEYSTORE_EXCEPTION, NTE_BAD_KEYSET_PARAM); + ThrowExceptionWithMessage(env, KEYSTORE_EXCEPTION, "key container name was NULL, NTE_BAD_KEYSET_PARAM"); __leave; } @@ -1847,7 +1867,7 @@ PROV_RSA_FULL, CRYPT_DELETEKEYSET) == FALSE) { - ThrowException(env, KEYSTORE_EXCEPTION, GetLastError()); + ThrowExceptionWithMessageAndErrcode(env, KEYSTORE_EXCEPTION, "CryptAcquireContext failure", GetLastError()); __leave; } diff -Nru openjdk-17-17.0.5+8/src/jdk.hotspot.agent/doc/clhsdb.html openjdk-17-17.0.6+10/src/jdk.hotspot.agent/doc/clhsdb.html --- openjdk-17-17.0.5+8/src/jdk.hotspot.agent/doc/clhsdb.html 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.hotspot.agent/doc/clhsdb.html 2023-01-10 13:21:55.000000000 +0000 @@ -90,7 +90,7 @@ vmstructsdump dump hotspot type library in text verbose true | false turn on/off verbose mode versioncheck [ true | false ] turn on/off debuggee VM version check - whatis address print info about any arbitrary address + whatis address print info about any arbitrary address. alias for findpc command where { -a | id } print Java stack trace of given Java thread or all Java threads (-a)
    diff -Nru openjdk-17-17.0.5+8/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java openjdk-17-17.0.6+10/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java --- openjdk-17-17.0.5+8/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2023-01-10 13:21:55.000000000 +0000 @@ -613,6 +613,18 @@ } } }, + // "whatis" is just an alias for "findpc". It's kept around for compatiblity reasons. + new Command("whatis", "whatis address", false) { + public void doit(Tokens t) { + if (t.countTokens() != 1) { + usage(); + } else { + Address a = VM.getVM().getDebugger().parseAddress(t.nextToken()); + PointerLocation loc = PointerFinder.find(a); + loc.printOn(out); + } + } + }, new Command("symbol", "symbol address", false) { public void doit(Tokens t) { if (t.countTokens() != 1) { diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java 2023-01-10 13:21:55.000000000 +0000 @@ -211,6 +211,14 @@ native HotSpotResolvedJavaType lookupClass(Class javaClass); /** + * Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object. + * + * The behavior of this method is undefined if {@code cpi} does not denote an + * {@code JVM_CONSTANT_String}. + */ + native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi); + + /** * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the * constant pool cache first. * diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java 2023-01-10 13:21:55.000000000 +0000 @@ -245,11 +245,23 @@ if (opcode == Bytecodes.INVOKEDYNAMIC) { index = rawIndex; // See: ConstantPool::is_invokedynamic_index - assert index < 0 : "not an invokedynamic constant pool index " + index; + if (index >= 0) { + throw new IllegalArgumentException("not an invokedynamic constant pool index " + index); + } } else { - assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE || - opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode; - index = rawIndex + config().constantPoolCpCacheIndexTag; + if (opcode == Bytecodes.GETFIELD || + opcode == Bytecodes.PUTFIELD || + opcode == Bytecodes.GETSTATIC || + opcode == Bytecodes.PUTSTATIC || + opcode == Bytecodes.INVOKEINTERFACE || + opcode == Bytecodes.INVOKEVIRTUAL || + opcode == Bytecodes.INVOKESPECIAL || + opcode == Bytecodes.INVOKESTATIC) { + index = rawIndex + config().constantPoolCpCacheIndexTag; + } else { + throw new IllegalArgumentException("unexpected opcode " + opcode); + + } } return index; } @@ -281,7 +293,9 @@ * See {@code ConstantPool::decode_invokedynamic_index}. */ private static int decodeInvokedynamicIndex(int i) { - assert isInvokedynamicIndex(i) : i; + if (!isInvokedynamicIndex(i)) { + throw new IllegalArgumentException("not an invokedynamic index: " + i); + } return ~i; } @@ -301,7 +315,7 @@ * @return constant pool tag */ private JvmConstant getTagAt(int index) { - assert checkBounds(index); + checkBounds(index); HotSpotVMConfig config = config(); final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset); final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index); @@ -318,7 +332,7 @@ * @return constant pool entry */ long getEntryAt(int index) { - assert checkBounds(index); + checkBounds(index); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -330,7 +344,7 @@ * @return integer constant pool entry at index */ private int getIntAt(int index) { - assert checkTag(index, constants.jvmInteger); + checkTag(index, constants.jvmInteger); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -342,7 +356,7 @@ * @return long constant pool entry */ private long getLongAt(int index) { - assert checkTag(index, constants.jvmLong); + checkTag(index, constants.jvmLong); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -354,7 +368,7 @@ * @return float constant pool entry */ private float getFloatAt(int index) { - assert checkTag(index, constants.jvmFloat); + checkTag(index, constants.jvmFloat); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -366,7 +380,7 @@ * @return float constant pool entry */ private double getDoubleAt(int index) { - assert checkTag(index, constants.jvmDouble); + checkTag(index, constants.jvmDouble); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -378,7 +392,7 @@ * @return {@code JVM_CONSTANT_NameAndType} constant pool entry */ private int getNameAndTypeAt(int index) { - assert checkTag(index, constants.jvmNameAndType); + checkTag(index, constants.jvmNameAndType); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); } @@ -460,7 +474,7 @@ * @return klass reference index */ private int getUncachedKlassRefIndexAt(int index) { - assert checkTagIsFieldOrMethod(index); + checkTagIsFieldOrMethod(index); int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize; final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + offset); // klass ref index is in the low 16-bits. @@ -471,11 +485,12 @@ * Checks that the constant pool index {@code index} is in the bounds of the constant pool. * * @param index constant pool index - * @throws AssertionError if the check fails + * @throws IndexOutOfBoundsException if the check fails */ - private boolean checkBounds(int index) { - assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length(); - return true; + private void checkBounds(int index) { + if (index < 1 || index >= length()) { + throw new IndexOutOfBoundsException("index " + index + " not between 1 and " + length()); + } } /** @@ -483,12 +498,13 @@ * * @param index constant pool index * @param tag expected tag - * @throws AssertionError if the check fails + * @throws IllegalArgumentException if the check fails */ - private boolean checkTag(int index, JvmConstant tag) { + private void checkTag(int index, JvmConstant tag) { final JvmConstant tagAt = getTagAt(index); - assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag; - return true; + if (tagAt != tag) { + throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt + " but expected " + tag); + } } /** @@ -497,12 +513,13 @@ * {@link JvmConstants#jvmInterfaceMethodref}. * * @param index constant pool index - * @throws AssertionError if the check fails + * @throws IllegalArgumentException if the check fails */ - private boolean checkTagIsFieldOrMethod(int index) { + private void checkTagIsFieldOrMethod(int index) { final JvmConstant tagAt = getTagAt(index); - assert tagAt == constants.jvmFieldref || tagAt == constants.jvmMethodref || tagAt == constants.jvmInterfaceMethodref : tagAt; - return true; + if (tagAt != constants.jvmFieldref && tagAt != constants.jvmMethodref && tagAt != constants.jvmInterfaceMethodref) { + throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt); + } } @Override @@ -518,9 +535,29 @@ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolFlagsOffset); } + /** + * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of a field. + */ + JavaConstant getStaticFieldConstantValue(int cpi) { + final JvmConstant tag = getTagAt(cpi); + switch (tag.name) { + case "Integer": + return JavaConstant.forInt(getIntAt(cpi)); + case "Long": + return JavaConstant.forLong(getLongAt(cpi)); + case "Float": + return JavaConstant.forFloat(getFloatAt(cpi)); + case "Double": + return JavaConstant.forDouble(getDoubleAt(cpi)); + case "String": + return compilerToVM().getUncachedStringInPool(this, cpi); + default: + throw new IllegalArgumentException("Illegal entry for a ConstantValue attribute:" + tag); + } + } + @Override public Object lookupConstant(int cpi) { - assert cpi != 0; final JvmConstant tag = getTagAt(cpi); switch (tag.name) { case "Integer": @@ -557,7 +594,7 @@ @Override public String lookupUtf8(int cpi) { - assert checkTag(cpi, constants.jvmUtf8); + checkTag(cpi, constants.jvmUtf8); return compilerToVM().getSymbol(getEntryAt(cpi)); } @@ -568,7 +605,10 @@ @Override public JavaConstant lookupAppendix(int cpi, int opcode) { - assert Bytecodes.isInvoke(opcode); + if (!Bytecodes.isInvoke(opcode)) { + throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode); + } + final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); return compilerToVM().lookupAppendixInPool(this, index); } @@ -702,10 +742,14 @@ public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) { int index; if (isInvokedynamicIndex(rawIndex)) { - assert opcode == Bytecodes.INVOKEDYNAMIC; + if (opcode != Bytecodes.INVOKEDYNAMIC) { + throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode); + } index = decodeInvokedynamicIndex(rawIndex) + config().constantPoolCpCacheIndexTag; } else { - assert opcode != Bytecodes.INVOKEDYNAMIC; + if (opcode == Bytecodes.INVOKEDYNAMIC) { + throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex); + } index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode); } return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); @@ -716,6 +760,7 @@ loadReferencedType(cpi, opcode, true /* initialize */); } + @Override @SuppressWarnings("fallthrough") public void loadReferencedType(int cpi, int opcode, boolean initialize) { int index; @@ -777,7 +822,7 @@ if (tag == constants.jvmMethodref) { if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) { final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); - assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); + checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex); } } @@ -829,7 +874,7 @@ public boolean isResolvedDynamicInvoke(int cpi, int opcode) { if (Bytecodes.isInvokeHandleAlias(opcode)) { final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode); - assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); + checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref); int op = compilerToVM().isResolvedInvokeHandleInPool(this, methodRefCacheIndex); return op == opcode; } diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java 2023-01-10 13:21:55.000000000 +0000 @@ -283,7 +283,7 @@ * Gets a {@link Method} object corresponding to {@code method}. This method guarantees the same * {@link Method} object is returned if called twice on the same {@code method} value. */ - private static Executable getMethod(HotSpotResolvedJavaMethodImpl method) { + static Executable getMethod(HotSpotResolvedJavaMethodImpl method) { assert !method.isClassInitializer() : method; if (method.toJavaCache == null) { synchronized (method) { @@ -303,7 +303,7 @@ * {@code f} and annotation class {@code a}, the same object is returned for each call to * {@code f.getAnnotation(a)}). */ - private static Field getField(HotSpotResolvedJavaFieldImpl field) { + static Field getField(HotSpotResolvedJavaFieldImpl field) { HotSpotResolvedObjectTypeImpl declaringClass = field.getDeclaringClass(); synchronized (declaringClass) { HashMap cache = declaringClass.reflectionFieldCache; diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2023-01-10 13:21:55.000000000 +0000 @@ -35,6 +35,8 @@ import java.lang.invoke.ConstantCallSite; import java.lang.invoke.MethodHandle; import java.lang.ref.WeakReference; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; @@ -60,6 +62,8 @@ import jdk.vm.ci.common.NativeImageReinitialize; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.UnresolvedJavaType; import jdk.vm.ci.runtime.JVMCI; @@ -767,7 +771,7 @@ } /** - * Get the {@link Class} corresponding to {@code type}. + * Gets the {@link Class} corresponding to {@code type}. * * @param type the type for which a {@link Class} is requested * @return the original Java class corresponding to {@code type} or {@code null} if this runtime @@ -780,6 +784,36 @@ } return null; } + + /** + * Gets the {@link Executable} corresponding to {@code method}. + * + * @param method the method for which an {@link Executable} is requested + * @return the original Java method or constructor corresponding to {@code method} or + * {@code null} if this runtime does not support mapping {@link ResolvedJavaMethod} + * instances to {@link Executable} instances + */ + public Executable getMirror(ResolvedJavaMethod method) { + if (method instanceof HotSpotResolvedJavaMethodImpl && reflection instanceof HotSpotJDKReflection) { + return HotSpotJDKReflection.getMethod((HotSpotResolvedJavaMethodImpl) method); + } + return null; + } + + /** + * Gets the {@link Field} corresponding to {@code field}. + * + * @param field the field for which a {@link Field} is requested + * @return the original Java field corresponding to {@code field} or {@code null} if this + * runtime does not support mapping {@link ResolvedJavaField} instances to {@link Field} + * instances + */ + public Field getMirror(ResolvedJavaField field) { + if (field instanceof HotSpotResolvedJavaFieldImpl && reflection instanceof HotSpotJDKReflection) { + return HotSpotJDKReflection.getField((HotSpotResolvedJavaFieldImpl) field); + } + return null; + } static class ErrorCreatingCompiler implements JVMCICompiler { private final RuntimeException t; diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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 @@ -45,6 +45,9 @@ HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method, boolean includeNormal, boolean includeOSR) { this.methodData = methodData; this.method = method; + if (!method.getDeclaringClass().isLinked()) { + throw new IllegalArgumentException(method.format("%H.%n(%p) must be linked")); + } this.includeNormal = includeNormal; this.includeOSR = includeOSR; this.isMature = methodData.isProfileMature(); diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -22,10 +22,10 @@ */ package jdk.vm.ci.hotspot; +import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; -import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; import java.lang.annotation.Annotation; @@ -45,28 +45,26 @@ private JavaType type; /** - * Value of {@code fieldDescriptor::access_flags()}. + * Offset (in bytes) of field from start of its storage container (i.e. {@code instanceOop} or + * {@code Klass*}). */ private final int offset; /** * Value of {@code fieldDescriptor::index()}. */ - private final short index; + private final int index; /** * This value contains all flags as stored in the VM including internal ones. */ private final int modifiers; - HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, long offset, int modifiers, int index) { + HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) { this.holder = holder; this.type = type; - this.index = (short) index; - assert this.index == index; - assert offset != -1; - assert offset == (int) offset : "offset larger than int"; - this.offset = (int) offset; + this.index = index; + this.offset = offset; this.modifiers = modifiers; } @@ -143,6 +141,10 @@ } + /** + * Gets the offset (in bytes) of field from start of its storage container (i.e. + * {@code instanceOop} or {@code Klass*}). + */ @Override public int getOffset() { return offset; @@ -214,4 +216,9 @@ } return runtime().reflection.getFieldAnnotation(this, annotationClass); } + + @Override + public JavaConstant getConstantValue() { + return holder.createFieldInfo(index).getConstantValue(); + } } diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -258,7 +258,11 @@ @Override public int getCodeSize() { - return UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset); + int codeSize = UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset); + if (codeSize > 0 && !getDeclaringClass().isLinked()) { + return -1; + } + return codeSize; } @Override diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java 2023-01-10 13:21:55.000000000 +0000 @@ -576,7 +576,7 @@ return result; } - HotSpotResolvedJavaField createField(JavaType type, long offset, int rawFlags, int index) { + HotSpotResolvedJavaField createField(JavaType type, int offset, int rawFlags, int index) { return new HotSpotResolvedJavaFieldImpl(this, type, offset, rawFlags, index); } @@ -684,6 +684,10 @@ return readFieldSlot(config().fieldInfoSignatureIndexOffset); } + private int getConstantValueIndex() { + return readFieldSlot(config().fieldInfoConstantValueIndexOffset); + } + public int getOffset() { HotSpotVMConfig config = config(); final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); @@ -719,6 +723,19 @@ return isInternal() ? config().symbolAt(signatureIndex) : getConstantPool().lookupUtf8(signatureIndex); } + /** + * Gets the {@link JavaConstant} for the {@code ConstantValue} attribute of this field. + * + * @return {@code null} if this field has no {@code ConstantValue} attribute + */ + public JavaConstant getConstantValue() { + int cvIndex = getConstantValueIndex(); + if (cvIndex == 0) { + return null; + } + return constantPool.getStaticFieldConstantValue(cvIndex); + } + public JavaType getType() { String signature = getSignature(); return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false); @@ -978,11 +995,28 @@ @Override public ResolvedJavaMethod[] getDeclaredConstructors() { + link(); + return runtime().compilerToVm.getDeclaredConstructors(this); + } + + @Override + public ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { + if (forceLink) { + link(); + } return runtime().compilerToVm.getDeclaredConstructors(this); } @Override public ResolvedJavaMethod[] getDeclaredMethods() { + return getDeclaredMethods(true); + } + + @Override + public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { + if (forceLink) { + link(); + } return runtime().compilerToVm.getDeclaredMethods(this); } diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java 2023-01-10 13:21:55.000000000 +0000 @@ -120,6 +120,7 @@ final int fieldInfoAccessFlagsOffset = getConstant("FieldInfo::access_flags_offset", Integer.class); final int fieldInfoNameIndexOffset = getConstant("FieldInfo::name_index_offset", Integer.class); final int fieldInfoSignatureIndexOffset = getConstant("FieldInfo::signature_index_offset", Integer.class); + final int fieldInfoConstantValueIndexOffset = getConstant("FieldInfo::initval_index_offset", Integer.class); final int fieldInfoLowPackedOffset = getConstant("FieldInfo::low_packed_offset", Integer.class); final int fieldInfoHighPackedOffset = getConstant("FieldInfo::high_packed_offset", Integer.class); final int fieldInfoFieldSlots = getConstant("FieldInfo::field_slots", Integer.class); diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantPool.java 2023-01-10 13:21:55.000000000 +0000 @@ -47,6 +47,24 @@ void loadReferencedType(int cpi, int opcode); /** + * Ensures that the type referenced by the specified constant pool entry is loaded. This can be + * used to compile time resolve a type. It works for field, method, or type constant pool + * entries. + * + * @param cpi the index of the constant pool entry that references the type + * @param opcode the opcode of the instruction that references the type + * @param initialize if {@code true}, the referenced type is either guaranteed to be initialized + * upon return or an initialization exception is thrown + */ + default void loadReferencedType(int cpi, int opcode, boolean initialize) { + if (initialize) { + loadReferencedType(cpi, opcode); + } else { + throw new UnsupportedOperationException(); + } + } + + /** * Looks up the type referenced by the constant pool entry at {@code cpi} as referenced by the * {@code opcode} bytecode instruction. * diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java 2023-01-10 13:21:55.000000000 +0000 @@ -40,6 +40,10 @@ @Override int getModifiers(); + /** + * Returns the offset of the field relative to the base of its storage container (e.g., + * {@code instanceOop} for an instance field or {@code Klass*} for a static field on HotSpot). + */ int getOffset(); default boolean isFinal() { @@ -63,4 +67,15 @@ */ @Override ResolvedJavaType getDeclaringClass(); + + /** + * Gets the value of the {@code ConstantValue} attribute ({@jvms 4.7.2}) associated with this + * field. + * + * @return {@code null} if this field has no {@code ConstantValue} attribute + * @throws UnsupportedOperationException if this operation is not supported + */ + default JavaConstant getConstantValue() { + throw new UnsupportedOperationException(); + } } diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, 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 @@ -36,24 +36,26 @@ public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement { /** - * Returns the bytecode of this method, if the method has code. The returned byte array does not - * contain breakpoints or non-Java bytecodes. This may return null if the - * {@linkplain #getDeclaringClass() declaring class} is not - * {@linkplain ResolvedJavaType#isLinked() linked}. + * Returns the method's bytecode. The returned bytecode does not contain breakpoints or non-Java + * bytecodes. This will return {@code null} if {@link #getCodeSize()} returns {@code <= 0} or if + * {@link #hasBytecodes()} returns {@code false}. * - * The contained constant pool indices may not be the ones found in the original class file but + * The contained constant pool indexes may not be the ones found in the original class file but * they can be used with the JVMCI API (e.g. methods in {@link ConstantPool}). * - * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} or if the - * code is not ready. + * @return {@code null} if {@code getLinkedCodeSize() <= 0} otherwise the bytecode of the method + * whose length is guaranteed to be {@code > 0} */ byte[] getCode(); /** - * Returns the size of the bytecode of this method, if the method has code. This is equivalent - * to {@link #getCode()}. {@code length} if the method has code. + * Returns the size of the method's bytecode. If this method returns a value {@code > 0} then + * {@link #getCode()} will not return {@code null}. * - * @return the size of the bytecode in bytes, or 0 if no bytecode is available + * @return 0 if the method has no bytecode, {@code -1} if the method does have bytecode but its + * {@linkplain #getDeclaringClass() declaring class} is not + * {@linkplain ResolvedJavaType#isLinked() linked} otherwise the size of the bytecode in + * bytes (guaranteed to be {@code > 0}) */ int getCodeSize(); @@ -439,15 +441,11 @@ } /** - * Checks whether the method has bytecodes associated with it. Note that even if this method - * returns {@code true}, {@link #getCode} can return {@code null} if - * {@linkplain #getDeclaringClass() declaring class} is not - * {@linkplain ResolvedJavaType#isLinked() linked}. - * - * @return {@code this.getCodeSize() != 0} + * @see #getCodeSize() + * @return {@code getCodeSize() > 0} */ default boolean hasBytecodes() { - return getCodeSize() != 0; + return getCodeSize() > 0; } /** diff -Nru openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java --- openjdk-17-17.0.5+8/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java 2023-01-10 13:21:55.000000000 +0000 @@ -340,6 +340,16 @@ ResolvedJavaMethod[] getDeclaredConstructors(); /** + * Returns an array reflecting all the constructors declared by this type. This method is + * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. + * + * @param forceLink if {@code true}, forces this type to be {@link #link linked} + */ + default ResolvedJavaMethod[] getDeclaredConstructors(boolean forceLink) { + throw new UnsupportedOperationException(); + } + + /** * Returns an array reflecting all the methods declared by this type. This method is similar to * {@link Class#getDeclaredMethods()} in terms of returned methods. Calling this method forces * this type to be {@link #link linked}. @@ -347,6 +357,16 @@ ResolvedJavaMethod[] getDeclaredMethods(); /** + * Returns an array reflecting all the methods declared by this type. This method is similar to + * {@link Class#getDeclaredMethods()} in terms of returned methods. + * + * @param forceLink if {@code true}, forces this type to be {@link #link linked} + */ + default ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { + throw new UnsupportedOperationException(); + } + + /** * Returns the {@code } method for this class if there is one. */ ResolvedJavaMethod getClassInitializer(); diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties 2023-01-10 13:21:55.000000000 +0000 @@ -45,7 +45,7 @@ doclet.exception.write.file=\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1}) doclet.exception.read.resource=\u30B7\u30B9\u30C6\u30E0\u30FB\u30EA\u30BD\u30FC\u30B9\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\t({1}) doclet.internal.exception=\u5185\u90E8\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002 \n\t({0}) -doclet.internal.report.bug=Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(http://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 +doclet.internal.report.bug=Bug Database (https://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(https://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 doclet.File_not_found=\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0} doclet.Copy_Overwrite_warning=\u30D5\u30A1\u30A4\u30EB{0}\u306F\u540C\u3058\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308B\u306E\u3067{1}\u306B\u30B3\u30D4\u30FC\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F... doclet.Copy_Ignored_warning=\u30D5\u30A1\u30A4\u30EB{0}\u306F\u30B3\u30D4\u30FC\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F: \u540D\u524D\u304C\u7121\u52B9\u3067\u3059 diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties 2023-01-10 13:21:55.000000000 +0000 @@ -49,7 +49,7 @@ \t({0}) doclet.internal.report.bug=\ Please file a bug against the javadoc tool via the Java bug reporting page\n\ -(http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)\n\ +(https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com)\n\ for duplicates. Include error messages and the following diagnostic in your report. Thank you. doclet.File_not_found=File not found: {0} doclet.Copy_Overwrite_warning=File {0} not copied to {1} due to existing file with same name... diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties 2023-01-10 13:21:55.000000000 +0000 @@ -45,7 +45,7 @@ doclet.exception.write.file=\u5199\u5165\u6587\u4EF6\u65F6\u51FA\u9519: {0}\n\t({1}) doclet.exception.read.resource=\u8BFB\u53D6\u7CFB\u7EDF\u8D44\u6E90\u65F6\u51FA\u9519: {0}\n\t({1}) doclet.internal.exception=\u51FA\u73B0\u5185\u90E8\u5F02\u5E38\u9519\u8BEF\u3002\n\t({0}) -doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 +doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (https://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (https://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 doclet.File_not_found=\u627E\u4E0D\u5230\u6587\u4EF6: {0} doclet.Copy_Overwrite_warning=\u672A\u5C06\u6587\u4EF6{0}\u590D\u5236\u5230 {1}, \u56E0\u4E3A\u73B0\u6709\u6587\u4EF6\u5177\u6709\u76F8\u540C\u540D\u79F0... doclet.Copy_Ignored_warning=\u672A\u590D\u5236\u6587\u4EF6 {0}\uFF1A\u540D\u79F0\u65E0\u6548 diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_ja.properties 2023-01-10 13:21:55.000000000 +0000 @@ -191,7 +191,7 @@ main.unknown.error=\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F main.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F main.unexpected.exception=\u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u6355\u6349\u3055\u308C\u307E\u3057\u305F: {0} -doclet.internal.report.bug=Bug Database (http://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(http://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 +doclet.internal.report.bug=Bug Database (https://bugs.java.com)\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java bug\u30EC\u30DD\u30FC\u30C8\u30FB\u30DA\u30FC\u30B8\n(https://bugreport.java.com)\u3067javadoc\u30C4\u30FC\u30EB\u306B\u5BFE\u3059\u308Bbug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\n\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u30A8\u30E9\u30FC\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 main.not_a_doclet=\u30AF\u30E9\u30B9{0}\u306F\u6709\u52B9\u306A\u30C9\u30C3\u30AF\u30EC\u30C3\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\n\u30CE\u30FC\u30C8: JDK 13\u304B\u3089\u3001com.sun.javadoc API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u304F\u306A\u308A\u307E\u3057\u305F\u3002 javadoc.class_not_found=\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002 javadoc.error=\u30A8\u30E9\u30FC diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties 2023-01-10 13:21:55.000000000 +0000 @@ -304,7 +304,7 @@ main.unexpected.exception=an unexpected exception was caught: {0} doclet.internal.report.bug=\ Please file a bug against the javadoc tool via the Java bug reporting page\n\ -(http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)\n\ +(https://bugreport.java.com) after checking the Bug Database (https://bugs.java.com)\n\ for duplicates. Include error messages and the following diagnostic in your report. Thank you. main.not_a_doclet=\ Class {0} is not a valid doclet.\n\ diff -Nru openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties --- openjdk-17-17.0.5+8/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_zh_CN.properties 2023-01-10 13:21:55.000000000 +0000 @@ -191,7 +191,7 @@ main.unknown.error=\u51FA\u73B0\u672A\u77E5\u9519\u8BEF main.internal.error=\u51FA\u73B0\u5185\u90E8\u9519\u8BEF main.unexpected.exception=\u6355\u83B7\u5230\u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF: {0} -doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (http://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (http://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 +doclet.internal.report.bug=\u5982\u679C\u5728 Bug Database (https://bugs.java.com) \u4E2D\u6CA1\u6709\u627E\u5230\u91CD\u590D\u9879, \n\u8BF7\u901A\u8FC7 Java Bug \u62A5\u544A\u9875 (https://bugreport.java.com) \u9488\u5BF9\u8BE5 \njavadoc \u5DE5\u5177\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u9519\u8BEF\u6D88\u606F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 main.not_a_doclet=\u7C7B {0} \u4E0D\u662F\u6709\u6548 doclet\u3002\n\u6CE8\u610F\uFF1A\u4ECE JDK 13 \u5F00\u59CB\uFF0C\u4E0D\u518D\u652F\u6301 com.sun.javadoc API\u3002 javadoc.class_not_found=\u627E\u4E0D\u5230\u7C7B{0}\u3002 javadoc.error=\u9519\u8BEF diff -Nru openjdk-17-17.0.5+8/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/InverseDepsAnalyzer.java openjdk-17-17.0.6+10/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/InverseDepsAnalyzer.java --- openjdk-17-17.0.5+8/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/InverseDepsAnalyzer.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/InverseDepsAnalyzer.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -145,9 +145,12 @@ .forEach(m -> { builder.addNode(m); m.descriptor().requires().stream() - .map(Requires::name) - .map(configuration::findModule) // must be present - .forEach(v -> builder.addEdge(v.get(), m)); + // filter "requires static" if the module is not resolved in the configuration + .filter(req -> !req.modifiers().contains(Requires.Modifier.STATIC) + || configuration.findModule(req.name()).isPresent()) + .map(Requires::name) + .map(configuration::findModule) // must be present + .forEach(v -> builder.addEdge(v.get(), m)); }); // add the dependences from the analysis diff -Nru openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/classTrack.c openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/classTrack.c --- openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/classTrack.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/classTrack.c 2023-01-10 13:21:55.000000000 +0000 @@ -37,6 +37,7 @@ #include "util.h" #include "bag.h" #include "classTrack.h" +#include "eventHandler.h" #define NOT_TAGGED 0 @@ -46,64 +47,14 @@ static jvmtiEnv* trackingEnv; /* - * A bag containing all the deleted classes' signatures. Must be accessed under - * classTrackLock. + * Invoke the callback when classes are freed. */ -struct bag* deletedSignatures; - -/* - * Lock to keep integrity of deletedSignatures. - */ -static jrawMonitorID classTrackLock; - -/* - * Invoke the callback when classes are freed, find and record the signature - * in deletedSignatures. Those are only used in addPreparedClass() by the - * same thread. - */ -static void JNICALL +void JNICALL cbTrackingObjectFree(jvmtiEnv* jvmti_env, jlong tag) { - debugMonitorEnter(classTrackLock); - if (deletedSignatures == NULL) { - debugMonitorExit(classTrackLock); - return; - } - *(char**)bagAdd(deletedSignatures) = (char*)jlong_to_ptr(tag); - - debugMonitorExit(classTrackLock); -} - -/* - * Called after class unloads have occurred. - * The signatures of classes which were unloaded are returned. - */ -struct bag * -classTrack_processUnloads(JNIEnv *env) -{ - if (deletedSignatures == NULL) { - return NULL; - } - - /* Allocate new bag outside classTrackLock lock to avoid deadlock. - * - * Note: jvmtiAllocate/jvmtiDeallocate() may be blocked by ongoing safepoints. - * It is dangerous to call them (via bagCreateBag/bagDestroyBag()) while holding monitor(s), - * because jvmti may post events, e.g. JVMTI_EVENT_OBJECT_FREE at safepoints and event processing - * code may acquire the same monitor(s), e.g. classTrackLock in cbTrackingObjectFree(), - * which can lead to deadlock. - */ - struct bag* new_bag = bagCreateBag(sizeof(char*), 10); - debugMonitorEnter(classTrackLock); - struct bag* deleted = deletedSignatures; - deletedSignatures = new_bag; - debugMonitorExit(classTrackLock); - return deleted; + eventHandler_synthesizeUnloadEvent((char*)jlong_to_ptr(tag), getEnv()); } -/* - * Add a class to the prepared class table. - */ void classTrack_addPreparedClass(JNIEnv *env_unused, jclass klass) { @@ -162,8 +113,6 @@ void classTrack_initialize(JNIEnv *env) { - deletedSignatures = NULL; - classTrackLock = debugMonitorCreate("Deleted class tag lock"); trackingEnv = getSpecialJvmti(); if (trackingEnv == NULL) { EXIT_ERROR(AGENT_ERROR_INTERNAL, "Failed to allocate tag-tracking jvmtiEnv"); @@ -195,44 +144,3 @@ EXIT_ERROR(error,"loaded classes array"); } } - -/* - * Called to activate class-tracking when a listener registers for EI_GC_FINISH. - */ -void -classTrack_activate(JNIEnv *env) -{ - // Allocate bag outside classTrackLock lock to avoid deadlock. - // See comments in classTrack_processUnloads() for details. - struct bag* new_bag = bagCreateBag(sizeof(char*), 1000); - debugMonitorEnter(classTrackLock); - deletedSignatures = new_bag; - debugMonitorExit(classTrackLock); -} - -static jboolean -cleanDeleted(void *signatureVoid, void *arg) -{ - char* sig = *(char**)signatureVoid; - jvmtiDeallocate(sig); - return JNI_TRUE; -} - -/* - * Called when agent detaches. - */ -void -classTrack_reset(void) -{ - debugMonitorEnter(classTrackLock); - struct bag* to_delete = deletedSignatures; - deletedSignatures = NULL; - debugMonitorExit(classTrackLock); - - // Deallocate bag outside classTrackLock to avoid deadlock. - // See comments in classTrack_processUnloads() for details. - if (to_delete != NULL) { - bagEnumerateOver(to_delete, cleanDeleted, NULL); - bagDestroyBag(to_delete); - } -} diff -Nru openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c --- openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c 2023-01-10 13:21:55.000000000 +0000 @@ -792,7 +792,6 @@ threadControl_reset(); util_reset(); commonRef_reset(env); - classTrack_reset(); /* * If this is a server, we are now ready to accept another connection. diff -Nru openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c --- openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.c 2023-01-10 13:21:55.000000000 +0000 @@ -457,16 +457,10 @@ } } -/* A bagEnumerateFunction. Create a synthetic class unload event - * for every class no longer present. Analogous to event_callback - * combined with a handler in a unload specific (no event - * structure) kind of way. - */ -static jboolean -synthesizeUnloadEvent(void *signatureVoid, void *envVoid) +/* Create a synthetic class unload event for the specified signature. */ +jboolean +eventHandler_synthesizeUnloadEvent(char *signature, JNIEnv *env) { - JNIEnv *env = (JNIEnv *)envVoid; - char *signature = *(char **)signatureVoid; char *classname; HandlerNode *node; jbyte eventSessionID = currentSessionID; @@ -560,39 +554,10 @@ currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env); JNI_FUNC_PTR(env,ExceptionClear)(env); - /* See if a garbage collection finish event happened earlier. - * - * Note: The "if" is an optimization to avoid entering the lock on every - * event; garbageCollected may be zapped before we enter - * the lock but then this just becomes one big no-op. - */ - if ( garbageCollected > 0 ) { - struct bag *unloadedSignatures = NULL; - - /* We want to compact the hash table of all - * objects sent to the front end by removing objects that have - * been collected. - */ + /* See if a garbage collection finish event happened earlier. */ + if ( garbageCollected > 0) { commonRef_compact(); - - /* We also need to simulate the class unload events. */ - - debugMonitorEnter(handlerLock); - - /* Clear garbage collection counter */ garbageCollected = 0; - - /* Analyze which class unloads occurred */ - unloadedSignatures = classTrack_processUnloads(env); - - debugMonitorExit(handlerLock); - - /* Generate the synthetic class unload events and/or just cleanup. */ - if ( unloadedSignatures != NULL ) { - (void)bagEnumerateOver(unloadedSignatures, synthesizeUnloadEvent, - (void *)env); - bagDestroyBag(unloadedSignatures); - } } thread = evinfo->thread; @@ -1627,9 +1592,6 @@ node->handlerID = external? ++requestIdCounter : 0; error = eventFilterRestricted_install(node); - if (node->ei == EI_GC_FINISH) { - classTrack_activate(getEnv()); - } if (error == JVMTI_ERROR_NONE) { insert(getHandlerChain(node->ei), node); } diff -Nru openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.h openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.h --- openjdk-17-17.0.5+8/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.h 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jdwp.agent/share/native/libjdwp/eventHandler.h 2023-01-10 13:21:55.000000000 +0000 @@ -76,6 +76,7 @@ void eventHandler_lock(void); void eventHandler_unlock(void); +jboolean eventHandler_synthesizeUnloadEvent(char *signature, JNIEnv *env); jclass getMethodClass(jvmtiEnv *jvmti_env, jmethodID method); diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java --- openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/RandomAccessFileInstrumentor.java 2023-01-10 13:21:55.000000000 +0000 @@ -156,7 +156,7 @@ write(b); bytesWritten = b.length; } finally { - long duration = EventHandler.timestamp(); + long duration = EventHandler.timestamp() - start; if (handler.shouldCommit(duration)) { handler.write(start, duration, path, bytesWritten); } diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java --- openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -269,9 +269,12 @@ if (staleMetadata) { storeDescriptorInJVM(); } - awaitUniqueTimestamp(); jvm.setOutput(filename); - long nanos = jvm.getChunkStartNanos(); + // Each chunk needs a unique start timestamp and + // if the clock resolution is low, two chunks may + // get the same timestamp. Utils.getChunkStartNanos() + // ensures the timestamp is unique for the next chunk + long chunkStart = Utils.getChunkStartNanos(); if (filename != null) { RepositoryFiles.notifyNewFile(); } @@ -282,29 +285,7 @@ } unregistered = false; } - return Utils.epochNanosToInstant(nanos); - } - - // Each chunk needs a unique start timestamp and - // if the clock resolution is low, two chunks may - // get the same timestamp. - private void awaitUniqueTimestamp() { - if (outputChange == null) { - outputChange = Instant.now(); - return; - } - while (true) { - Instant time = Instant.now(); - if (!time.equals(outputChange)) { - outputChange = time; - return; - } - try { - Thread.sleep(0, 100); - } catch (InterruptedException iex) { - // ignore - } - } + return Utils.epochNanosToInstant(chunkStart); } private void unregisterUnloaded() { diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java --- openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java 2023-01-10 13:21:55.000000000 +0000 @@ -249,7 +249,7 @@ } currentChunk = newChunk; jvm.beginRecording(); - startNanos = jvm.getChunkStartNanos(); + startNanos = Utils.getChunkStartNanos(); startTime = Utils.epochNanosToInstant(startNanos); if (currentChunk != null) { currentChunk.setStartTime(startTime); @@ -270,7 +270,7 @@ startTime = MetadataRepository.getInstance().setOutput(p); newChunk.setStartTime(startTime); } - startNanos = jvm.getChunkStartNanos(); + startNanos = Utils.getChunkStartNanos(); startTime = Utils.epochNanosToInstant(startNanos); recording.setStartTime(startTime); recording.setState(RecordingState.RUNNING); @@ -317,7 +317,7 @@ } } OldObjectSample.emit(recording); - recording.setFinalStartnanos(jvm.getChunkStartNanos()); + recording.setFinalStartnanos(Utils.getChunkStartNanos()); if (endPhysical) { RequestEngine.doChunkEnd(); diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java --- openjdk-17-17.0.5+8/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -96,6 +96,7 @@ * The possible data race is benign and is worth of not introducing any contention here. */ private static Metrics[] metrics; + private static Instant lastTimestamp; public static void checkAccessFlightRecorder() throws SecurityException { @SuppressWarnings("removal") @@ -841,4 +842,30 @@ public static long timeToNanos(Instant timestamp) { return timestamp.getEpochSecond() * 1_000_000_000L + timestamp.getNano(); } + + public static long getChunkStartNanos() { + long nanos = JVM.getJVM().getChunkStartNanos(); + // JVM::getChunkStartNanos() may return a bumped timestamp, +1 ns or +2 ns. + // Spin here to give Instant.now() a chance to catch up. + awaitUniqueTimestamp(); + return nanos; + } + + private static void awaitUniqueTimestamp() { + if (lastTimestamp == null) { + lastTimestamp = Instant.now(); // lazy initialization + } + while (true) { + Instant time = Instant.now(); + if (!time.equals(lastTimestamp)) { + lastTimestamp = time; + return; + } + try { + Thread.sleep(0, 100); + } catch (InterruptedException iex) { + // ignore + } + } + } } diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/conf/jfr/default.jfc openjdk-17-17.0.6+10/src/jdk.jfr/share/conf/jfr/default.jfc --- openjdk-17-17.0.5+8/src/jdk.jfr/share/conf/jfr/default.jfc 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/conf/jfr/default.jfc 2023-01-10 13:21:55.000000000 +0000 @@ -521,6 +521,10 @@ false + + true + + true beginChunk diff -Nru openjdk-17-17.0.5+8/src/jdk.jfr/share/conf/jfr/profile.jfc openjdk-17-17.0.6+10/src/jdk.jfr/share/conf/jfr/profile.jfc --- openjdk-17-17.0.5+8/src/jdk.jfr/share/conf/jfr/profile.jfc 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jfr/share/conf/jfr/profile.jfc 2023-01-10 13:21:55.000000000 +0000 @@ -521,6 +521,10 @@ false + + true + + true beginChunk diff -Nru openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties --- openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties 2023-01-10 13:21:55.000000000 +0000 @@ -55,7 +55,7 @@ main.opt.verbose=\ -v\u3001--verbose \u8A73\u7D30\u306A\u30C8\u30EC\u30FC\u30B9\u3092\u6709\u52B9\u306B\u3057\u307E\u3059 -main.msg.bug=jlink\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java Bug Database (http://bugreport.java.com/bugreport/)\u3067bug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 +main.msg.bug=jlink\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u91CD\u8907\u304C\u306A\u3044\u304B\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001Java Bug Database (https://bugreport.java.com/bugreport/)\u3067bug\u306E\u767B\u9332\u3092\u304A\u9858\u3044\u3044\u305F\u3057\u307E\u3059\u3002\u30EC\u30DD\u30FC\u30C8\u306B\u306F\u3001\u305D\u306E\u30D7\u30ED\u30B0\u30E9\u30E0\u3068\u6B21\u306E\u8A3A\u65AD\u5185\u5BB9\u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002\u3054\u5354\u529B\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002 main.extended.help=\u4F7F\u7528\u53EF\u80FD\u306A\u30D7\u30E9\u30B0\u30A4\u30F3\u306E\u30EA\u30B9\u30C8: diff -Nru openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties --- openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties 2023-01-10 13:21:55.000000000 +0000 @@ -92,7 +92,7 @@ main.msg.bug=\ An exception has occurred in jlink. \ -Please file a bug at the Java Bug Database (http://bugreport.java.com/bugreport/) \ +Please file a bug at the Java Bug Database (https://bugreport.java.com/bugreport/) \ after checking the database for duplicates. \ Include your program and the following diagnostic in your report. Thank you. diff -Nru openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties --- openjdk-17-17.0.5+8/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties 2023-01-10 13:21:55.000000000 +0000 @@ -55,7 +55,7 @@ main.opt.verbose=\ -v, --verbose \u542F\u7528\u8BE6\u7EC6\u8DDF\u8E2A -main.msg.bug=jlink \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Java Bug Database (http://bugreport.java.com/bugreport/) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF, \u8BF7\u5728\u8BE5\u6570\u636E\u5E93\u4E2D\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 +main.msg.bug=jlink \u4E2D\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\u3002\u5982\u679C\u5728 Java Bug Database (https://bugreport.java.com/bugreport/) \u4E2D\u6CA1\u6709\u627E\u5230\u8BE5\u9519\u8BEF, \u8BF7\u5728\u8BE5\u6570\u636E\u5E93\u4E2D\u5EFA\u7ACB Bug\u3002\u8BF7\u5728\u62A5\u544A\u4E2D\u9644\u4E0A\u60A8\u7684\u7A0B\u5E8F\u548C\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002\u8C22\u8C22\u3002 main.extended.help=\u53EF\u7528\u63D2\u4EF6\u5217\u8868: diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_hr_HR.properties openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_hr_HR.properties --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_hr_HR.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/CurrencyNames_hr_HR.properties 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2023, 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 @@ -35,4 +35,5 @@ # This notice and attribution to Taligent may not be removed. # Taligent is a registered trademark of Taligent, Inc. +EUR=\u20AC HRK=Kn diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_de.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Franz\u00f6sisch-Guiana Sommerzeit", "GFST", "Franz\u00F6sisch-Guiana Zeit", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Suriname Zeit", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_es.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Hora de verano de la Guayana Francesa", "GFST", "Hora de la Guayana Francesa", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Hora de Surinam", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_fr.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Heure d'\u00e9t\u00e9 de Guyane fran\u00e7aise", "GFST", "Heure de Guyane fran\u00E7aise", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Heure du Surinam", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_it.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Ora estiva della Guyana Francese", "GFST", "Ora della Guyana Francese", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Ora di Suriname", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ja.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "\u4ecf\u9818\u30ae\u30a2\u30ca\u590f\u6642\u9593", "GFST", "\u30D5\u30E9\u30F3\u30B9\u9818\u30AE\u30A2\u30CA\u6642\u9593", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"\u30b9\u30ea\u30ca\u30e0\u6642\u9593", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_ko.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "\ud504\ub791\uc2a4\ub839 \uae30\uc544\ub098 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "GFST", "\uD504\uB791\uC2A4\uB839 \uAE30\uC544\uB098 \uD45C\uC900\uC2DC", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"\uc218\ub9ac\ub0a8 \uc2dc\uac04", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_pt_BR.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Fuso hor\u00e1rio de ver\u00e3o da Guiana Francesa", "GFST", "Hor\u00E1rio da Guiana Francesa", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Fuso hor\u00e1rio do Suriname", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_sv.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "Franska Guyana, sommartid", "GFST", "Franska Guyana-tid", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"Surinam, normaltid", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_CN.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "\u6cd5\u5c5e\u572d\u4e9a\u90a3\u590f\u4ee4\u65f6", "GFST", "\u6CD5\u5C5E\u572D\u4E9A\u90A3\u65F6\u95F4", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"\u82cf\u5229\u5357\u65f6\u95f4", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java --- openjdk-17-17.0.5+8/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.localedata/share/classes/sun/util/resources/ext/TimeZoneNames_zh_TW.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -427,7 +427,8 @@ "\u6cd5\u5c6c\u572d\u4e9e\u90a3\u590f\u4ee4\u6642\u9593", "GFST", "\u6CD5\u5C6C\u572D\u4E9E\u90A3\u6642\u9593", "GFT"}}, {"America/Cayman", EST}, - {"America/Chihuahua", MST}, + {"America/Chihuahua", CST}, + {"America/Ciudad_Juarez", MST}, {"America/Creston", MST}, {"America/Coral_Harbour", EST}, {"America/Cordoba", AGT}, @@ -516,7 +517,7 @@ {"America/North_Dakota/Center", CST}, {"America/North_Dakota/New_Salem", CST}, {"America/Nuuk", WGT}, - {"America/Ojinaga", MST}, + {"America/Ojinaga", CST}, {"America/Panama", EST}, {"America/Pangnirtung", EST}, {"America/Paramaribo", new String[] {"\u8607\u5229\u5357\u6642\u9593", "SRT", diff -Nru openjdk-17-17.0.5+8/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java openjdk-17-17.0.6+10/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java --- openjdk-17-17.0.5+8/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -925,9 +925,6 @@ private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory { private final String bindAddress; - private final String[] enabledCipherSuites; - private final String[] enabledProtocols; - private final boolean needClientAuth; private final SSLContext context; private HostAwareSslSocketFactory(String[] enabledCipherSuites, @@ -942,11 +939,9 @@ String[] enabledProtocols, boolean sslNeedClientAuth, String bindAddress) throws IllegalArgumentException { - this.context = ctx; + super(ctx, enabledCipherSuites, enabledProtocols, sslNeedClientAuth); this.bindAddress = bindAddress; - this.enabledProtocols = enabledProtocols; - this.enabledCipherSuites = enabledCipherSuites; - this.needClientAuth = sslNeedClientAuth; + this.context = ctx; checkValues(ctx, enabledCipherSuites, enabledProtocols); } @@ -956,14 +951,15 @@ try { InetAddress addr = InetAddress.getByName(bindAddress); return new SslServerSocket(port, 0, addr, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), + this.getNeedClientAuth()); } catch (UnknownHostException e) { return new SslServerSocket(port, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), this.getNeedClientAuth()); } } else { return new SslServerSocket(port, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), this.getNeedClientAuth()); } } diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/JndiLoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/JndiLoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/JndiLoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/JndiLoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, 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 @@ -469,11 +469,18 @@ cleanState(); throw new LoginException ("Subject is Readonly"); } - subject.getPrincipals().remove(userPrincipal); - subject.getPrincipals().remove(UIDPrincipal); - subject.getPrincipals().remove(GIDPrincipal); - for (int i = 0; i < supplementaryGroups.size(); i++) { - subject.getPrincipals().remove(supplementaryGroups.get(i)); + if (userPrincipal != null) { + subject.getPrincipals().remove(userPrincipal); + } + if (UIDPrincipal != null) { + subject.getPrincipals().remove(UIDPrincipal); + } + if (GIDPrincipal != null) { + subject.getPrincipals().remove(GIDPrincipal); + } + for (UnixNumericGroupPrincipal gp : supplementaryGroups) { + // gp is never null + subject.getPrincipals().remove(gp); } diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -862,23 +862,25 @@ certP = null; status = INITIALIZED; // destroy the private credential - Iterator it = subject.getPrivateCredentials().iterator(); - while (it.hasNext()) { - Object obj = it.next(); - if (privateCredential.equals(obj)) { - privateCredential = null; - try { - ((Destroyable)obj).destroy(); - if (debug) - debugPrint("Destroyed private credential, " + - obj.getClass().getName()); - break; - } catch (DestroyFailedException dfe) { - LoginException le = new LoginException - ("Unable to destroy private credential, " - + obj.getClass().getName()); - le.initCause(dfe); - throw le; + if (privateCredential != null) { + Iterator it = subject.getPrivateCredentials().iterator(); + while (it.hasNext()) { + Object obj = it.next(); + if (privateCredential.equals(obj)) { + privateCredential = null; + try { + ((Destroyable) obj).destroy(); + if (debug) + debugPrint("Destroyed private credential, " + + obj.getClass().getName()); + break; + } catch (DestroyFailedException dfe) { + LoginException le = new LoginException + ("Unable to destroy private credential, " + + obj.getClass().getName()); + le.initCause(dfe); + throw le; + } } } } diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1206,8 +1206,10 @@ throw new LoginException("Subject is Readonly"); } - subject.getPrincipals().remove(kerbClientPrinc); - // Let us remove all Kerberos credentials stored in the Subject + if (kerbClientPrinc != null) { + subject.getPrincipals().remove(kerbClientPrinc); + } + // Let us remove all Kerberos credentials stored in the Subject Iterator it = subject.getPrivateCredentials().iterator(); while (it.hasNext()) { Object o = it.next(); diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/LdapLoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/LdapLoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/LdapLoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/LdapLoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, 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 @@ -696,8 +696,12 @@ throw new LoginException ("Subject is read-only"); } Set principals = subject.getPrincipals(); - principals.remove(ldapPrincipal); - principals.remove(userPrincipal); + if (ldapPrincipal != null) { + principals.remove(ldapPrincipal); + } + if (userPrincipal != null) { + principals.remove(userPrincipal); + } if (authzIdentity != null) { principals.remove(authzPrincipal); } diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTLoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTLoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTLoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTLoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, 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,29 +349,30 @@ throw new LoginException ("Subject is ReadOnly"); } Set principals = subject.getPrincipals(); - if (principals.contains(userPrincipal)) { + if (userPrincipal != null && principals.contains(userPrincipal)) { principals.remove(userPrincipal); } - if (principals.contains(userSID)) { + if (userSID != null && principals.contains(userSID)) { principals.remove(userSID); } - if (principals.contains(userDomain)) { + if (userDomain != null && principals.contains(userDomain)) { principals.remove(userDomain); } - if (principals.contains(domainSID)) { + if (domainSID != null && principals.contains(domainSID)) { principals.remove(domainSID); } - if (principals.contains(primaryGroup)) { + if (primaryGroup != null && principals.contains(primaryGroup)) { principals.remove(primaryGroup); } - for (int i = 0; groups != null && i < groups.length; i++) { - if (principals.contains(groups[i])) { - principals.remove(groups[i]); + if (groups != null) { + for (NTSidGroupPrincipal gp : groups) { + // gp is never null + principals.remove(gp); } } Set pubCreds = subject.getPublicCredentials(); - if (pubCreds.contains(iToken)) { + if (iToken != null && pubCreds.contains(iToken)) { pubCreds.remove(iToken); } diff -Nru openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixLoginModule.java openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixLoginModule.java --- openjdk-17-17.0.5+8/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixLoginModule.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixLoginModule.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2022, 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 @@ -277,11 +277,18 @@ ("logout Failed: Subject is Readonly"); } // remove the added Principals from the Subject - subject.getPrincipals().remove(userPrincipal); - subject.getPrincipals().remove(UIDPrincipal); - subject.getPrincipals().remove(GIDPrincipal); - for (int i = 0; i < supplementaryGroups.size(); i++) { - subject.getPrincipals().remove(supplementaryGroups.get(i)); + if (userPrincipal != null) { + subject.getPrincipals().remove(userPrincipal); + } + if (UIDPrincipal != null) { + subject.getPrincipals().remove(UIDPrincipal); + } + if (GIDPrincipal != null) { + subject.getPrincipals().remove(GIDPrincipal); + } + for (UnixNumericGroupPrincipal gp : supplementaryGroups) { + // gp is never null + subject.getPrincipals().remove(gp); } // clean out state diff -Nru openjdk-17-17.0.5+8/test/hotspot/gtest/metaspace/test_metaspacearena.cpp openjdk-17-17.0.6+10/test/hotspot/gtest/metaspace/test_metaspacearena.cpp --- openjdk-17-17.0.5+8/test/hotspot/gtest/metaspace/test_metaspacearena.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/gtest/metaspace/test_metaspacearena.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -739,3 +739,50 @@ word_size_for_level(CHUNK_LEVEL_4M), false); } */ + +// Test that repeated allocation-deallocation cycles with the same block size +// do not increase metaspace usage after the initial allocation (the deallocated +// block should be reused by the next allocation). +static void test_repeatedly_allocate_and_deallocate(bool is_topmost) { + if (Settings::handle_deallocations()) { + // Test various sizes, including (important) the max. possible block size = 1 root chunk + for (size_t blocksize = Metaspace::max_allocation_word_size(); blocksize >= 1; blocksize /= 2) { + size_t used1 = 0, used2 = 0, committed1 = 0, committed2 = 0; + MetaWord* p = NULL, *p2 = NULL; + + MetaspaceGtestContext context; + MetaspaceArenaTestHelper helper(context, Metaspace::StandardMetaspaceType, false); + + // First allocation + helper.allocate_from_arena_with_tests_expect_success(&p, blocksize); + if (!is_topmost) { + // another one on top, size does not matter. + helper.allocate_from_arena_with_tests_expect_success(0x10); + } + + // Measure + helper.usage_numbers_with_test(&used1, &committed1, NULL); + + // Dealloc, alloc several times with the same size. + for (int i = 0; i < 5; i ++) { + helper.deallocate_with_tests(p, blocksize); + helper.allocate_from_arena_with_tests_expect_success(&p2, blocksize); + // We should get the same pointer back. + EXPECT_EQ(p2, p); + } + + // Measure again + helper.usage_numbers_with_test(&used2, &committed2, NULL); + EXPECT_EQ(used2, used1); + EXPECT_EQ(committed1, committed2); + } + } +} + +TEST_VM(metaspace, MetaspaceArena_test_repeatedly_allocate_and_deallocate_top_allocation) { + test_repeatedly_allocate_and_deallocate(true); +} + +TEST_VM(metaspace, MetaspaceArena_test_repeatedly_allocate_and_deallocate_nontop_allocation) { + test_repeatedly_allocate_and_deallocate(false); +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/BadStateAtLongCmp.jasm openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/BadStateAtLongCmp.jasm --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/BadStateAtLongCmp.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/BadStateAtLongCmp.jasm 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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. + */ + +super public class BadStateAtLongCmp + version 52:0 +{ + public static Field field:I; + + public Method "":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + /* Same as: + public static void test() { + long l = 0; + do { + l++; + field++; + } while (l < 1000); + } + but with field++ between the lcmp and iflt bytecodes. + */ + public static Method test:"()V" + stack 4 locals 2 + { + lconst_0; + lstore_0; + L2: stack_frame_type append; + locals_map long; + lload_0; + lconst_1; + ladd; + lstore_0; + lload_0; + ldc2_w long 1000l; + lcmp; + getstatic Field field:"I"; + iconst_1; + iadd; + putstatic Field field:"I"; + iflt L2; + return; + } + +} // end Class BadStateAtLongCmp diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheck.jasm openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheck.jasm --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheck.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheck.jasm 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, 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. + */ + +package compiler/c1; + +super public class KlassAccessCheck + version 51:0 +{ + + public static Method testNewInstance:"()V" + stack 2 locals 0 + { + new class compiler/c1/types/PackagePrivateClass; + return; + } + + + public static Method testNewArray:"()[Ljava/lang/Object;" + stack 1 locals 0 + { + iconst_1; + anewarray class compiler/c1/types/PackagePrivateClass; + areturn; + } + + public static Method testMultiNewArray:"()[[Ljava/lang/Object;" + stack 2 locals 1 + { + iconst_1; + iconst_1; + multianewarray class "[[Lcompiler/c1/types/PackagePrivateClass;", 2; + areturn; + } + + public static Method testCheckCast:"(Ljava/lang/Object;)Ljava/lang/Object;" + stack 1 locals 2 + { + aload_0; + checkcast class compiler/c1/types/PackagePrivateClass; + areturn; + } + + public static Method testCheckCastArr:"(Ljava/lang/Object;)Ljava/lang/Object;" + stack 1 locals 2 + { + aload_0; + checkcast class "[Lcompiler/c1/types/PackagePrivateClass;"; + areturn; + } + + public static Method testInstanceOf:"(Ljava/lang/Object;)Z" + stack 1 locals 2 + { + aload_0; + instanceof class compiler/c1/types/PackagePrivateClass; + ireturn; + } + + public static Method testInstanceOfArr:"(Ljava/lang/Object;)Z" + stack 1 locals 2 + { + aload_0; + instanceof class "[Lcompiler/c1/types/PackagePrivateClass;"; + ireturn; + } +} // end Class KlassAccessCheck diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheckPackagePrivate.jasm openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheckPackagePrivate.jasm --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheckPackagePrivate.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheckPackagePrivate.jasm 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +package compiler/c1/types; + +super class PackagePrivateClass + version 51:0 +{} + diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheckTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheckTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/KlassAccessCheckTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/KlassAccessCheckTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022, 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 8293044 + * @requires vm.compiler1.enabled + * @compile KlassAccessCheckPackagePrivate.jasm + * @compile KlassAccessCheck.jasm + * @run main/othervm -Xbatch -XX:TieredStopAtLevel=1 compiler.c1.KlassAccessCheckTest + */ + +package compiler.c1; + +public class KlassAccessCheckTest { + static void test(Runnable r) { + for (int i = 0; i < 1000; ++i) { + try { + r.run(); + throw new AssertionError("No IllegalAccessError thrown"); + } catch (IllegalAccessError e) { + // Expected + } catch (AssertionError e) { + throw e; // rethrow + } catch (Throwable e) { + throw new AssertionError("Wrong exception thrown", e); + } + } + } + + public static void main(String[] args) { + test(() -> KlassAccessCheck.testNewInstance()); + test(() -> KlassAccessCheck.testNewArray()); + test(() -> KlassAccessCheck.testMultiNewArray()); + test(() -> KlassAccessCheck.testCheckCast(42)); + test(() -> KlassAccessCheck.testCheckCastArr(new Integer[0])); + test(() -> KlassAccessCheck.testInstanceOf(42)); + test(() -> KlassAccessCheck.testInstanceOfArr(new Integer[0])); + System.out.println("TEST PASSED"); + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/TestBadStateAtLongCmp.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/TestBadStateAtLongCmp.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/TestBadStateAtLongCmp.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/TestBadStateAtLongCmp.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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 8290451 + * @summary Incorrect result when switching to C2 OSR compilation from C1 + * @compile BadStateAtLongCmp.jasm + * @run main/othervm -Xbatch TestBadStateAtLongCmp + */ + +public class TestBadStateAtLongCmp { + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + BadStateAtLongCmp.test(); + } + int expected = 20_000 * 1000; + if (BadStateAtLongCmp.field != expected) { + throw new RuntimeException("test failed: " + BadStateAtLongCmp.field + " != " + expected); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/TestPinnedIntrinsics.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/TestPinnedIntrinsics.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c1/TestPinnedIntrinsics.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c1/TestPinnedIntrinsics.java 2023-01-10 13:21:55.000000000 +0000 @@ -24,10 +24,9 @@ /* * @test * @bug 8184271 - * @summary Test correct scheduling of System.nanoTime and System.currentTimeMillis C1 intrinsics. + * @summary Test correct scheduling of System.nanoTime C1 intrinsic. * @run main/othervm -XX:TieredStopAtLevel=1 -Xbatch * -XX:CompileCommand=dontinline,compiler.c1.TestPinnedIntrinsics::checkNanoTime - * -XX:CompileCommand=dontinline,compiler.c1.TestPinnedIntrinsics::checkCurrentTimeMillis * compiler.c1.TestPinnedIntrinsics */ @@ -47,22 +46,9 @@ } } - private static void testCurrentTimeMillis() { - long start = System.currentTimeMillis(); - long end = System.currentTimeMillis(); - checkCurrentTimeMillis(end - start); - } - - private static void checkCurrentTimeMillis(long diff) { - if (diff < 0) { - throw new RuntimeException("testCurrentTimeMillis failed with " + diff); - } - } - public static void main(String[] args) { for (int i = 0; i < 100_000; ++i) { testNanoTime(); - testCurrentTimeMillis(); } } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/aarch64/TestFarJump.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022, BELLSOFT. 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. + */ +package compiler.c2.aarch64; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.*; + +/* + * @test + * @bug 8280872 + * @summary Far call to runtime stub should be generated with single instruction for CodeHeap up to 250MB + * @library /test/lib / + * + * @requires vm.flagless + * @requires os.arch=="aarch64" + * @requires vm.debug == false + * @requires vm.compiler2.enabled + * + * @run driver compiler.c2.aarch64.TestFarJump + */ +public class TestFarJump { + + // ADRP instruction encoding: + // |31 30 29 28|27 26 25 24|23 22 21 20|19 18 17 16|15 14 13 12|11 10 09 08|07 06 05 04|03 02 01 10| + // | 1|immlo| 1 0 0 0 0| immhi | Rd | + static boolean isADRP(int encoding) { + final int mask = 0b1001_1111; + final int val = 0b1001_0000; + return ((encoding >> 24) & mask) == val; + } + + // Looking for adrp instruction in binary/text assembly output: + // 0x0000ffff7ff1b7d0: c8ff ffd0 | 0801 1091 | 0001 1fd6 + // 0x0000ffff6bf20ee0: adrp x8, 0x0000ffff6bef1000 + static boolean containsADRP(String input) { + int index = input.indexOf(": "); + if (index == -1) { + return false; + } + input = input.substring(index + 1); + if (input.contains("adrp")) { + return true; + } + Pattern pattern = Pattern.compile("[0-9a-f ]*"); + Matcher matcher = pattern.matcher(input); + while (matcher.find()) { + String match = matcher.group(); + match = match.replace(" " , ""); + if (match.length() != 8) { + continue; + } + int dump = (int)Long.parseLong(match, 16); + int encoding = Integer.reverseBytes(dump); + // Check the first instruction only. The raw pointer can be confused with the encoded adrp instruction: + // emit_exception_handler() = far_call() + should_not_reach_here() = ADRP + ADD + BLR + DCPS1 + raw_pointer + return isADRP(encoding); + } + return false; + } + + static void runVM(boolean bigCodeHeap) throws Exception { + String className = TestFarJump.class.getName(); + String[] procArgs = { + "-XX:-Inline", + "-Xcomp", + "-Xbatch", + "-XX:+TieredCompilation", + "-XX:+SegmentedCodeCache", + "-XX:CompileOnly=" + className + "::main", + "-XX:ReservedCodeCacheSize=" + (bigCodeHeap ? "256M" : "200M"), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+PrintAssembly", + className}; + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + List lines = output.asLines(); + + ListIterator itr = lines.listIterator(); + while (itr.hasNext()) { + String line = itr.next(); + if (line.contains("[Exception Handler]")) { + String next1 = itr.next(); + String next2 = itr.next(); + System.out.println(line); + System.out.println(next1); + System.out.println(next2); + boolean containsADRP = containsADRP(next1) || containsADRP(next2); + if (bigCodeHeap && !containsADRP) { + throw new RuntimeException("ADRP instruction is expected on far jump"); + } + if (!bigCodeHeap && containsADRP) { + throw new RuntimeException("for CodeHeap < 250MB the far jump is expected to be encoded with a single branch instruction"); + } + return; + } + } + throw new RuntimeException("Assembly output: exception Handler is not found"); + } + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + // Main VM: fork VM with options + runVM(true); + runVM(false); + return; + } + if (args.length > 0) { + // We are in a forked VM. Just exit + System.out.println("Ok"); + } + } +} + diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/cr6865031/Test.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/cr6865031/Test.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/cr6865031/Test.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/cr6865031/Test.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright 2009 Goldman Sachs International. All Rights Reserved. + * Copyright (C) 2022 THL A29 Limited, a Tencent company. 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 @@ -27,6 +28,7 @@ * @bug 6865031 * @summary Application gives bad result (throws bad exception) with compressed oops * + * @requires vm.bits == 64 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops * -XX:HeapBaseMinAddress=32g -XX:-LoopUnswitching * -XX:CompileCommand=inline,compiler.c2.cr6865031.AbstractMemoryEfficientList::equals diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/irTests/CmpUWithZero.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/irTests/CmpUWithZero.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/irTests/CmpUWithZero.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/irTests/CmpUWithZero.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * bug 8290529 + * @summary verify that x 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsFor() { + for (int i = 0; i < 2; i++) { + barrier = 0x42; // something that can't be optimized out + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsWhile() { + int i = 0; + while (i < 2) { + barrier = 0x42; + i++; + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsDoWhile() { + int i = 0; + do { + synchronized(object) {} // so loop head is not cloned by ciTypeFlow + barrier = 0x42; + i++; + } while (i < 2); + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threadIterationsFor() { + for (int i = 0; i < 2; i++) { + barrier = 0x42; // something that can't be optimized out + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threeIterationsWhile() { + int i = 0; + while (i < 2) { + barrier = 0x42; + i++; + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threeIterationsDoWhile() { + int i = 0; + do { + synchronized(object) {} // so loop head is not cloned by ciTypeFlow + barrier = 0x42; + i++; + } while (i < 2); + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/Test7179138_1.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/Test7179138_1.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/Test7179138_1.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/Test7179138_1.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,9 @@ * compiler.c2.Test7179138_1 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation * -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN compiler.c2.Test7179138_1 + * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+StressIGVN -XX:+AlwaysIncrementalInline + * compiler.c2.Test7179138_1 * * @author Skip Balk */ diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/TestUnsignedCompareIntoEqualityNotCanonical.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/TestUnsignedCompareIntoEqualityNotCanonical.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/c2/TestUnsignedCompareIntoEqualityNotCanonical.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/c2/TestUnsignedCompareIntoEqualityNotCanonical.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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 8290529 + * @summary C2: assert(BoolTest(btest).is_canonical()) failure + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation TestUnsignedCompareIntoEqualityNotCanonical + */ + + +public class TestUnsignedCompareIntoEqualityNotCanonical { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(0); + test(1); + } + } + + private static int test(int x) { + if (Integer.compareUnsigned(0, x) >= 0) { + return 42; + } + return -42; + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/ccp/TestInfiniteIGVNAfterCCP.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/ccp/TestInfiniteIGVNAfterCCP.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/ccp/TestInfiniteIGVNAfterCCP.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/ccp/TestInfiniteIGVNAfterCCP.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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 8290711 + * @summary assert(false) failed: infinite loop in PhaseIterGVN::optimize + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation TestInfiniteIGVNAfterCCP + */ + + +import java.util.function.BooleanSupplier; + +public class TestInfiniteIGVNAfterCCP { + private static int inc; + private static volatile boolean barrier; + + static class A { + int field1; + int field2; + } + + public static void main(String[] args) { + A a = new A(); + for (int i = 0; i < 20_000; i++) { + test(false, a, false); + inc = 0; + testHelper(true, () -> inc < 10, a, 4, true); + inc = 0; + testHelper(true, () -> inc < 10, a, 4, false); + testHelper(false, () -> inc < 10, a, 42, false); + } + } + + private static void test(boolean flag2, A a, boolean flag1) { + int i = 2; + for (; i < 4; i *= 2); + testHelper(flag2, () -> true, a, i, flag1); + } + + private static void testHelper(boolean flag2, BooleanSupplier f, A a, int i, boolean flag1) { + if (i == 4) { + if (a == null) { + + } + } else { + a = null; + } + if (flag2) { + while (true) { + synchronized (new Object()) { + + } + if (!f.getAsBoolean()) { + break; + } + if (flag1) { + if (a == null) { + + } + } + barrier = true; + inc++; + if (inc % 2 == 0) { + a.field1++; + } + } + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/aes/Test8292158.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/aes/Test8292158.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/aes/Test8292158.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/aes/Test8292158.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022, 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 + * @key randomness + * @bug 8292158 + * @summary AES-CTR cipher state corruption with AVX-512 + * @library /test/lib / + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * + * @run main/othervm -Xbatch + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * compiler.codegen.aes.Test8292158 + */ + +package compiler.codegen.aes; + +import java.util.Arrays; +import java.util.Random; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import compiler.whitebox.CompilerWhiteBoxTest; +import jdk.test.lib.Utils; +import sun.hotspot.code.Compiler; +import jtreg.SkippedException; + +public class Test8292158 { + private static final String ALGO = "AES/CTR/NoPadding"; + private static final int LOOPS = 100000; + private static final int LEN = 15; + + public static void main(String[] args) throws Exception { + if (!Compiler.isIntrinsicAvailable(CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION, "com.sun.crypto.provider.CounterMode", "implCrypt", byte[].class, int.class, int.class, byte[].class, int.class)) { + throw new SkippedException("AES-CTR intrinsic is not available"); + } + + Random random = Utils.getRandomInstance(); + + byte[] keyBytes = new byte[32]; + random.nextBytes(keyBytes); + SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); + + byte[] ivBytes = new byte[16]; + random.nextBytes(ivBytes); + IvParameterSpec iv = new IvParameterSpec(ivBytes); + + Cipher encryptCipher = Cipher.getInstance(ALGO); + Cipher decryptCipher = Cipher.getInstance(ALGO); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, iv); + decryptCipher.init(Cipher.DECRYPT_MODE, key, iv); + + byte[] original = new byte[LEN]; + byte[] encrypted = new byte[LEN]; + byte[] decrypted = new byte[LEN]; + + for (int i = 0; i < LOOPS; i++) { + random.nextBytes(original); + encryptCipher.doFinal(original, 0, LEN, encrypted); + + // Cipher must be used at least 3 times + decryptCipher.update(encrypted, 0, 1, decrypted, 0); + decryptCipher.update(encrypted, 1, 1, decrypted, 1); + decryptCipher.doFinal(encrypted, 2, LEN - 2, decrypted, 2); + + if (!Arrays.equals(original, decrypted)) { + throw new Exception("array mismatch"); + } + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/ShiftByZero.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/ShiftByZero.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/ShiftByZero.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/ShiftByZero.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022, 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 8288445 + * @summary Test shift by 0 + * @run main/othervm -Xbatch -XX:-TieredCompilation + * compiler.codegen.ShiftByZero + */ + +package compiler.codegen; + +public class ShiftByZero { + + public static final int N = 64; + + public static int[] i32 = new int[N]; + + public static void bMeth() { + int shift = i32[0]; + // This loop is to confuse the optimizer, so that "shift" is + // optimized to 0 only after loop vectorization. + for (int i8 = 279; i8 > 1; --i8) { + shift <<= 6; + } + // low 6 bits of shift are 0, so shift can be + // simplified to constant 0 + { + for (int i = 0; i < N; ++i) { + i32[i] += i32[i] >>= shift; + } + for (int i = 0; i < N; ++i) { + i32[i] += i32[i] >>>= shift; + } + for (int i = 0; i < N; ++i) { + i32[i] >>>= shift; + } + for (int i = 0; i < N; ++i) { + i32[i] >>= shift; + } + for (int i = 0; i < N; ++i) { + i32[i] <<= shift; + } + } + } + + public static void main(String[] strArr) { + for (int i = 0; i < 20_000; i++) { + bMeth(); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/ShiftTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/ShiftTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/ShiftTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/ShiftTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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,13 +23,17 @@ /* * @test - * @bug 4093292 + * @bug 4093292 8280511 * @summary Test for correct code generation by the JIT + * @library /test/lib * @run main compiler.codegen.ShiftTest + * @run main/othervm -XX:-TieredCompilation compiler.codegen.ShiftTest */ package compiler.codegen; +import jdk.test.lib.Asserts; + public class ShiftTest { static final int w = 32; @@ -63,7 +67,133 @@ System.err.println("Test passed"); } + private static int[] ispecial = { + 0, Integer.MAX_VALUE, -Integer.MAX_VALUE, Integer.MIN_VALUE, -42, 42, -1, 1 + }; + + private static long[] lspecial = { + 0, Long.MAX_VALUE, -Long.MAX_VALUE, Long.MIN_VALUE, Integer.MAX_VALUE, -Integer.MAX_VALUE, Integer.MIN_VALUE, -42, 42, -1, 1 + }; + + private static int[] ispecial_LeftShift_expected = { + 0, 32, -32, 0, 1344, -1344, 32, -32 + }; + + private static int[] ispecial_UnsignedRightShift_expected = { + 0, -33554431, -33554432, -33554432 ,-67108863, 0, -67108863, 0 + }; + + private static int[] ispecial_SignedRightShift_expected = { + 0, -16777215, 16777216, 16777216, 1, 0, 1, 0 + }; + + private static int[] ispecial_LeftShiftCorner_expected = { + 0, -2147483647, 2147483647, -2147483648, 42, -42, 1, -1 + }; + + private static int[] ispecial_UnsignedRightShiftCorner_expected = { + 0, -1073741823, -1073741824, -1073741824, -2147483627, -21, -2147483647, 0 + }; + + private static int[] ispecial_SignedRightShiftCorner_expected = { + 0, -536870911, 536870912, 536870912, 11, -10, 1, 0 + }; + + private static long[] lspecial_LeftShift_expected = { + 0, 256, -256, 0, -549755813632L, 549755813632L, 549755813888L, 10752, -10752, 256, -256 + }; + + private static long[] lspecial_UnsignedRightShift_expected = { + 0, -18014398509481983L, -18014398509481984L, -18014398509481984L, -4194303, -36028797014769664L, -36028797014769664L, -36028797018963967L, 0, -36028797018963967L, 0 + }; + + private static long[] lspecial_SignedRightShift_expected = { + 0, -9007199254740991L, 9007199254740992L, 9007199254740992L, -2097151, 2097152, 2097152, 1, 0, 1, 0 + }; + + private static long[] lspecial_LeftShiftCorner_expected = { + 0, -9223372036854775807L, 9223372036854775807L, -9223372036854775808L, -2147483647, 2147483647, 2147483648L, 42, -42, 1, -1 + }; + + private static long[] lspecial_UnsignedRightShiftCorner_expected = { + 0, -4611686018427387903L, -4611686018427387904L, -4611686018427387904L, -1073741823, -9223372035781033984L, -9223372035781033984L, -9223372036854775787L, -21, -9223372036854775807L, 0 + }; + + private static long[] lspecial_SignedRightShiftCorner_expected = { + 0, -2305843009213693951L, 2305843009213693952L, 2305843009213693952L, -536870911, 536870912, 536870912, 11, -10, 1, 0 + }; + + private static int negLeftShiftInt(int input) { + return -(input << 5); + } + + private static int negUnsignedRightShiftInt(int input) { + return -(input >>> 6); + } + + private static int negSignedRightShiftInt(int input) { + return -(input >> 7); + } + + private static int negLeftShiftICorner(int input) { + return -(input << 32); + } + + private static int negUnsignedRightShiftICorner(int input) { + return -(input >>> 33); + } + + private static int negSignedRightShiftICorner(int input) { + return -(input >> 34); + } + + private static long negLeftShiftLong(long input) { + return -(input << 8); + } + + private static long negUnsignedRightShiftLong(long input) { + return -(input >>> 9); + } + + private static long negSignedRightShiftLong(long input) { + return -(input >> 10); + } + + private static long negLeftShiftLCorner(long input) { + return -(input << 64); + } + + private static long negUnsignedRightShiftLCorner(long input) { + return -(input >>> 65); + } + + private static long negSignedRightShiftLCorner(long input) { + return -(input >> 66); + } + + private static void testNegShift() { + for (int i = 0; i < 20_000; i++) { + for (int j = 0; j < ispecial.length; j++) { + Asserts.assertEquals(negLeftShiftInt(ispecial[j]), ispecial_LeftShift_expected[j]); + Asserts.assertEquals(negUnsignedRightShiftInt(ispecial[j]), ispecial_UnsignedRightShift_expected[j]); + Asserts.assertEquals(negSignedRightShiftInt(ispecial[j]), ispecial_SignedRightShift_expected[j]); + Asserts.assertEquals(negLeftShiftICorner(ispecial[j]), ispecial_LeftShiftCorner_expected[j]); + Asserts.assertEquals(negUnsignedRightShiftICorner(ispecial[j]), ispecial_UnsignedRightShiftCorner_expected[j]); + Asserts.assertEquals(negSignedRightShiftICorner(ispecial[j]), ispecial_SignedRightShiftCorner_expected[j]); + } + for (int j = 0; j < lspecial.length; j++) { + Asserts.assertEquals(negLeftShiftLong(lspecial[j]), lspecial_LeftShift_expected[j]); + Asserts.assertEquals(negUnsignedRightShiftLong(lspecial[j]), lspecial_UnsignedRightShift_expected[j]); + Asserts.assertEquals(negSignedRightShiftLong(lspecial[j]), lspecial_SignedRightShift_expected[j]); + Asserts.assertEquals(negLeftShiftLCorner(lspecial[j]), lspecial_LeftShiftCorner_expected[j]); + Asserts.assertEquals(negUnsignedRightShiftLCorner(lspecial[j]), lspecial_UnsignedRightShiftCorner_expected[j]); + Asserts.assertEquals(negSignedRightShiftLCorner(lspecial[j]), lspecial_SignedRightShiftCorner_expected[j]); + } + } + } + public static void main(String[] args) throws Exception { doTest(0x496def29b74be041L); + testNegShift(); } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/TestCharVect2.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/TestCharVect2.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/codegen/TestCharVect2.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/codegen/TestCharVect2.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021, 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 @@ -27,6 +27,14 @@ * @summary incorrect results of char vectors right shift operation * * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::test() -Xmx128m compiler.codegen.TestCharVect2 + */ + +/** + * @test + * @bug 8001183 + * @summary incorrect results of char vectors right shift operation + * @requires vm.compiler2.enabled | vm.graal.enabled + * * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::test() -Xmx128m -XX:MaxVectorSize=8 compiler.codegen.TestCharVect2 * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::test() -Xmx128m -XX:MaxVectorSize=16 compiler.codegen.TestCharVect2 * @run main/othervm -Xbatch -XX:CompileCommand=exclude,*::test() -Xmx128m -XX:MaxVectorSize=32 compiler.codegen.TestCharVect2 diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java 2023-01-10 13:21:55.000000000 +0000 @@ -48,6 +48,7 @@ import java.util.Base64.Encoder; import java.util.Objects; import java.util.Random; +import java.util.Arrays; import compiler.whitebox.CompilerWhiteBoxTest; import sun.hotspot.code.Compiler; @@ -79,9 +80,9 @@ private static void warmup() { final int warmupCount = 20_000; - final int bufSize = 60; + final int bufSize = 15308; byte[] srcBuf = new byte[bufSize]; - byte[] encBuf = new byte[(bufSize / 3) * 4]; + byte[] encBuf = new byte[((bufSize + 2) / 3) * 4]; byte[] decBuf = new byte[bufSize]; ran.nextBytes(srcBuf); @@ -163,10 +164,13 @@ assertEqual(resEncodeStr, encodedStr); // test int decode(byte[], byte[]) - resArr = new byte[srcArr.length]; + // JDK-8273108: Test for output buffer overrun + resArr = new byte[srcArr.length + 2]; + resArr[srcArr.length + 1] = (byte) 167; len = decoder.decode(encodedArr, resArr); assertEqual(len, srcArr.length); - assertEqual(resArr, srcArr); + assertEqual(Arrays.copyOfRange(resArr, 0, srcArr.length), srcArr); + assertEqual(resArr[srcArr.length + 1], (byte) 167); // test byte[] decode(byte[]) resArr = decoder.decode(encodedArr); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+AbortVMOnCompilationFailure + * -XX:CompileCommand=compileonly,compiler.intrinsics.bmi.*::* * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI2Instructions * compiler.intrinsics.bmi.verifycode.BzhiTestI2L */ diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldHelper.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldHelper.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldHelper.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldHelper.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022, 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. + */ + +package jdk.vm.ci.hotspot; + +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.ResolvedJavaField; + +public class HotSpotResolvedJavaFieldHelper { + public static ResolvedJavaField createField(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) { + return new HotSpotResolvedJavaFieldImpl(holder, type, offset, modifiers, index); + } + + public static int getIndex(ResolvedJavaField field) { + return ((HotSpotResolvedJavaFieldImpl) field).getIndex(); + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotResolvedJavaFieldTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotResolvedJavaFieldTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotResolvedJavaFieldTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotResolvedJavaFieldTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022, 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. + */ +package jdk.vm.ci.hotspot.test; + +import static java.lang.reflect.Modifier.FINAL; +import static java.lang.reflect.Modifier.PRIVATE; +import static java.lang.reflect.Modifier.PROTECTED; +import static java.lang.reflect.Modifier.PUBLIC; +import static java.lang.reflect.Modifier.STATIC; +import static java.lang.reflect.Modifier.TRANSIENT; +import static java.lang.reflect.Modifier.VOLATILE; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.junit.Assert; +import org.junit.Test; + +import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaField; +import jdk.vm.ci.hotspot.HotSpotVMConfigAccess; +import jdk.vm.ci.meta.JavaType; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.runtime.JVMCI; + +/** + * + * @test + * @requires vm.jvmci + * @summary Tests HotSpotResolvedJavaField functionality + * @library ../../../../../ + * @modules jdk.internal.vm.ci/jdk.vm.ci.meta + * jdk.internal.vm.ci/jdk.vm.ci.runtime + * jdk.internal.vm.ci/jdk.vm.ci.hotspot + * @run junit/othervm --add-opens=jdk.internal.vm.ci/jdk.vm.ci.hotspot=ALL-UNNAMED -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.hotspot.test.HotSpotResolvedJavaFieldTest + */ +public class HotSpotResolvedJavaFieldTest { + + private static final Class[] classesWithInternalFields = {Class.class, ClassLoader.class}; + + private static final Method createFieldMethod; + private static final Field indexField; + + static { + Method m = null; + Field f = null; + try { + Class typeImpl = Class.forName("jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl"); + m = typeImpl.getDeclaredMethod("createField", JavaType.class, int.class, int.class, int.class); + m.setAccessible(true); + Class fieldImpl = Class.forName("jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl"); + f = fieldImpl.getDeclaredField("index"); + f.setAccessible(true); + } catch (Exception e) { + throw new AssertionError(e); + } + + createFieldMethod = m; + indexField = f; + } + + /** + * Same as {@code HotSpotModifiers.jvmFieldModifiers()} but works when using a JVMCI version + * prior to the introduction of that method. + */ + private int jvmFieldModifiers() { + HotSpotJVMCIRuntime runtime = runtime(); + HotSpotVMConfigAccess access = new HotSpotVMConfigAccess(runtime.getConfigStore()); + int accEnum = access.getConstant("JVM_ACC_ENUM", Integer.class, 0x4000); + int accSynthetic = access.getConstant("JVM_ACC_SYNTHETIC", Integer.class, 0x1000); + return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | accEnum | accSynthetic; + } + + HotSpotJVMCIRuntime runtime() { + return (HotSpotJVMCIRuntime) JVMCI.getRuntime(); + } + + MetaAccessProvider getMetaAccess() { + return runtime().getHostJVMCIBackend().getMetaAccess(); + } + + /** + * Tests that {@link HotSpotResolvedJavaField#getModifiers()} only includes the modifiers + * returned by {@link Field#getModifiers()}. Namely, it must not include + * {@code HotSpotResolvedJavaField#FIELD_INTERNAL_FLAG}. + */ + @Test + public void testModifiersForInternal() { + for (Class c : classesWithInternalFields) { + ResolvedJavaType type = getMetaAccess().lookupJavaType(c); + for (ResolvedJavaField field : type.getInstanceFields(false)) { + if (field.isInternal()) { + Assert.assertEquals(0, ~jvmFieldModifiers() & field.getModifiers()); + } + } + } + } + + /** + * Tests that {@code HotSpotResolvedObjectTypeImpl#createField(String, JavaType, long, int)} + * always returns an {@linkplain ResolvedJavaField#equals(Object) equivalent} object for an + * internal field. + * + * @throws InvocationTargetException + * @throws IllegalArgumentException + * @throws IllegalAccessException + */ + @Test + public void testEquivalenceForInternalFields() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + for (Class c : classesWithInternalFields) { + ResolvedJavaType type = getMetaAccess().lookupJavaType(c); + for (ResolvedJavaField field : type.getInstanceFields(false)) { + if (field.isInternal()) { + HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field; + int index = indexField.getInt(expected); + ResolvedJavaField actual = (ResolvedJavaField) createFieldMethod.invoke(type, expected.getType(), expected.getOffset(), expected.getModifiers(), index); + Assert.assertEquals(expected, actual); + } + } + } + } + + @Test + public void testIsInObject() { + for (Field f : String.class.getDeclaredFields()) { + HotSpotResolvedJavaField rf = (HotSpotResolvedJavaField) getMetaAccess().lookupJavaField(f); + Assert.assertEquals(rf.toString(), rf.isInObject(runtime().getHostJVMCIBackend().getConstantReflection().forString("a string")), !rf.isStatic()); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotResolvedJavaField.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotResolvedJavaField.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotResolvedJavaField.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotResolvedJavaField.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022, 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 + * @requires vm.jvmci + * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot + * jdk.internal.vm.ci/jdk.vm.ci.meta + * @library /compiler/jvmci/common/patches + * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldHelper + * @run testng/othervm + * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler + * jdk.vm.ci.hotspot.test.TestHotSpotResolvedJavaField + */ + +package jdk.vm.ci.hotspot.test; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldHelper; +import jdk.vm.ci.meta.ResolvedJavaField; + +public class TestHotSpotResolvedJavaField { + + @Test + public void testIndex() { + int max = Character.MAX_VALUE; + int[] valid = {0, 1, max - 1, max}; + for (int index : valid) { + ResolvedJavaField field = HotSpotResolvedJavaFieldHelper.createField(null, null, 0, 0, index); + Assert.assertEquals(HotSpotResolvedJavaFieldHelper.getIndex(field), index); + } + } + + @Test + public void testOffset() { + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + int[] valid = {min, min + 1, -2, 0, 1, max - 1, max}; + for (int offset : valid) { + ResolvedJavaField field = HotSpotResolvedJavaFieldHelper.createField(null, null, offset, 0, 0); + Assert.assertEquals(field.getOffset(), offset); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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,9 +25,9 @@ * @test * @requires vm.jvmci * @library ../../../../../ - * @ignore 8249621 * @modules jdk.internal.vm.ci/jdk.vm.ci.meta * jdk.internal.vm.ci/jdk.vm.ci.runtime + * jdk.internal.vm.ci/jdk.vm.ci.common * java.base/jdk.internal.misc * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestResolvedJavaField */ @@ -37,6 +37,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; @@ -46,6 +48,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.HashSet; import java.util.Map; @@ -54,6 +57,9 @@ import org.junit.Assert; import org.junit.Test; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -106,6 +112,54 @@ } } + @Test + public void getDeclaringClassTest() { + for (Map.Entry e : fields.entrySet()) { + ResolvedJavaField field = e.getValue(); + ResolvedJavaType actual = field.getDeclaringClass(); + ResolvedJavaType expect = metaAccess.lookupJavaType(e.getKey().getDeclaringClass()); + assertEquals(field.toString(), expect, actual); + } + } + + @Test + public void getOffsetTest() { + for (Map.Entry e : fields.entrySet()) { + Field javaField = e.getKey(); + ResolvedJavaField field = e.getValue(); + int actual = field.getOffset(); + long expect = field.isStatic() ? unsafe.staticFieldOffset(javaField) : unsafe.objectFieldOffset(javaField); + assertEquals(field.toString(), expect, actual); + } + } + + @Test + public void isFinalTest() { + for (Map.Entry e : fields.entrySet()) { + ResolvedJavaField field = e.getValue(); + boolean actual = field.isFinal(); + boolean expect = Modifier.isFinal(e.getKey().getModifiers()); + assertEquals(field.toString(), expect, actual); + } + } + + @Test + public void isInternalTest() { + for (Class c : classes) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + for (ResolvedJavaField field : type.getInstanceFields(false)) { + if (field.isInternal()) { + try { + c.getDeclaredField(field.getName()); + throw new AssertionError("got reflection object for internal field: " + field); + } catch (NoSuchFieldException e) { + // expected + } + } + } + } + } + private Method findTestMethod(Method apiMethod) { String testName = apiMethod.getName() + "Test"; for (Method m : getClass().getDeclaredMethods()) { @@ -118,10 +172,6 @@ // @formatter:off private static final String[] untestedApiMethods = { - "getDeclaringClass", - "getOffset", - "isInternal", - "isFinal" }; // @formatter:on @@ -221,6 +271,70 @@ field.getAnnotations(); } } + + @Test + public void getConstantValueTest() { + ConstantReflectionProvider cr = constantReflection; + Map expects = Map.of( + "INT", JavaConstant.forInt(42), + "SHORT", JavaConstant.forInt(43), + "CHAR", JavaConstant.forInt(44), + "BYTE", JavaConstant.forInt(45), + "FLOAT", JavaConstant.forFloat(46.46F), + "LONG", JavaConstant.forLong(47L), + "DOUBLE", JavaConstant.forDouble(48.48D)); + ResolvedJavaType type = metaAccess.lookupJavaType(FieldsWithConstantValueAttributes.class); + for (ResolvedJavaField field : type.getStaticFields()) { + JavaConstant actual = field.getConstantValue(); + String name = field.getName(); + if (name.endsWith("2")) { + assertNull(field.toString(), actual); + } else if (name.equals("STRING")) { + JavaConstant expect = cr.forString("STRING_VALUE"); + assertEquals(field.toString(), expect, actual); + + // String ConstantValues are interned so should not + // be identical to a newly allocated String + expect = cr.forString(new String("STRING_VALUE")); + assertNotEquals(field.toString(), expect, actual); + } else { + JavaConstant expect = expects.get(name); + assertEquals(field.toString(), expect, actual); + } + } + } +} + +class FieldsWithConstantValueAttributes { + public static final String STRING = "STRING_VALUE"; + public static final int INT = 42; + public static final short SHORT = 43; + public static final char CHAR = 44; + public static final byte BYTE = 45; + public static final float FLOAT = 46.46F; + public static final long LONG = 47L; + public static final double DOUBLE = 48.48D; + + public static final String STRING2; + public static final int INT2; + public static final short SHORT2; + public static final char CHAR2; + public static final byte BYTE2; + public static final float FLOAT2; + public static final long LONG2; + public static final double DOUBLE2; + + static { + JVMCIError.shouldNotReachHere("should not be initialized"); + STRING2 = STRING; + INT2 = INT; + SHORT2 = SHORT; + BYTE2 = BYTE; + CHAR2 = CHAR; + FLOAT2 = FLOAT; + LONG2 = LONG; + DOUBLE2 = DOUBLE; + } } class TypeWithUnresolvedFieldType { diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, 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,13 +46,16 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -78,17 +81,13 @@ */ @Test public void getCodeTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); + for (ResolvedJavaMethod m : joinValues(methods, constructors)) { + String ms = m.toString(); byte[] code = m.getCode(); if (code == null) { - assertTrue(m.getCodeSize() == 0); + assertEquals(ms, m.getCodeSize(), 0); } else { - if (m.isAbstract()) { - assertTrue(code.length == 0); - } else if (!m.isNative()) { - assertTrue(code.length > 0); - } + assertTrue(ms, code.length > 0); } } } @@ -98,26 +97,25 @@ */ @Test public void getCodeSizeTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); + ResolvedJavaType unlinkedType = metaAccess.lookupJavaType(UnlinkedType.class); + assertTrue(!unlinkedType.isLinked()); + for (ResolvedJavaMethod m : addExecutables(joinValues(methods, constructors), unlinkedType, false)) { int codeSize = m.getCodeSize(); - if (m.isAbstract()) { - assertTrue(codeSize == 0); - } else if (!m.isNative()) { - assertTrue(codeSize > 0); + String ms = m.toString(); + if (m.isAbstract() || m.isNative()) { + assertEquals(ms, codeSize, 0); + } else if (!m.getDeclaringClass().isLinked()) { + assertEquals(ms, -1, codeSize); + } else { + assertTrue(ms, codeSize > 0); } } + assertTrue(!unlinkedType.isLinked()); } @Test public void getModifiersTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - int expected = e.getKey().getModifiers(); - int actual = m.getModifiers(); - assertEquals(String.format("%s: 0x%x != 0x%x", m, expected, actual), expected, actual); - } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { ResolvedJavaMethod m = e.getValue(); int expected = e.getKey().getModifiers(); int actual = m.getModifiers(); @@ -130,15 +128,11 @@ */ @Test public void isClassInitializerTest() { - for (Map.Entry e : methods.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { // Class initializers are hidden from reflection ResolvedJavaMethod m = e.getValue(); assertFalse(m.isClassInitializer()); } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertFalse(m.isClassInitializer()); - } } @Test @@ -155,11 +149,7 @@ @Test public void isSyntheticTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertEquals(e.getKey().isSynthetic(), m.isSynthetic()); - } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { ResolvedJavaMethod m = e.getValue(); assertEquals(e.getKey().isSynthetic(), m.isSynthetic()); } @@ -179,11 +169,7 @@ @Test public void isVarArgsTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertEquals(e.getKey().isVarArgs(), m.isVarArgs()); - } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { ResolvedJavaMethod m = e.getValue(); assertEquals(e.getKey().isVarArgs(), m.isVarArgs()); } @@ -191,11 +177,7 @@ @Test public void isSynchronizedTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized()); - } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { ResolvedJavaMethod m = e.getValue(); assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized()); } @@ -262,7 +244,7 @@ @Test public void getConstantPoolTest() { - for (Map.Entry e : methods.entrySet()) { + for (Map.Entry e : join(methods, constructors).entrySet()) { ResolvedJavaMethod m = e.getValue(); ConstantPool cp = m.getConstantPool(); assertTrue(cp.length() > 0); @@ -399,16 +381,22 @@ } } + public static List addExecutables(List to, ResolvedJavaType declaringType, boolean forceLink) { + to.addAll(List.of(declaringType.getDeclaredMethods(forceLink))); + to.addAll(List.of(declaringType.getDeclaredConstructors(forceLink))); + return to; + } + @Test public void hasBytecodesTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertTrue(m.hasBytecodes() == (m.isConcrete() && !m.isNative())); - } - for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertTrue(m.hasBytecodes()); + ResolvedJavaType unlinkedType = metaAccess.lookupJavaType(UnlinkedType.class); + assertTrue(!unlinkedType.isLinked()); + for (ResolvedJavaMethod m : addExecutables(joinValues(methods, constructors), unlinkedType, false)) { + boolean expect = m.getDeclaringClass().isLinked() && m.isConcrete() && !m.isNative(); + boolean actual = m.hasBytecodes(); + assertEquals(m.toString(), expect, actual); } + assertTrue(!unlinkedType.isLinked()); } @Test @@ -430,7 +418,13 @@ } } - static class UnlinkedType { + abstract static class UnlinkedType { + abstract void abstractMethod(); + + void concreteMethod() { + } + + native void nativeMethod(); } /** @@ -513,4 +507,22 @@ } } } + + @SafeVarargs + public static Map join(Map... maps) { + Map res = new HashMap<>(); + for (Map e : maps) { + res.putAll(e); + } + return res; + } + + @SafeVarargs + public static List joinValues(Map... maps) { + List res = new ArrayList<>(); + for (Map e : maps) { + res.addAll(e.values()); + } + return res; + } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java 2023-01-10 13:21:55.000000000 +0000 @@ -136,6 +136,8 @@ public static final String MEMBAR_STORESTORE = START + "MemBarStoreStore" + MID + END; public static final String SAFEPOINT = START + "SafePoint" + MID + END; + public static final String CMP_U = START + "CmpU" + MID + END; + public static final String CMP_I = START + "CmpI" + MID + END; public static final String MUL_L = START + "MulL" + MID + END; public static final String POPCOUNT_L = START + "PopCountL" + MID + END; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/loopopts/TestPhiInSkeletonPredicateExpression.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/loopopts/TestPhiInSkeletonPredicateExpression.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/loopopts/TestPhiInSkeletonPredicateExpression.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/loopopts/TestPhiInSkeletonPredicateExpression.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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 8291599 + * @summary Assertion in PhaseIdealLoop::skeleton_predicate_has_opaque after JDK-8289127 + * @requires vm.compiler2.enabled + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:LoopMaxUnroll=0 TestPhiInSkeletonPredicateExpression + */ + +public class TestPhiInSkeletonPredicateExpression { + private static int[] array1; + private static int[] array2; + private static int off; + private static volatile int barrier; + + public static void main(String[] args) { + int[] array = new int[2000]; + array1 = array; + array2 = array; + for (int i = 0; i < 20_000; i++) { + test1(1000, false); + test1(1000, true); + test2(1000, false); + test2(1000, true); + } + } + + private static int test1(int stop, boolean flag) { + int v = 0; + + for (int j = 1; j < 10; j *= 2) { + int[] array; + if (flag) { + if (array1 == null) { + + } + array = array1; + barrier = 0x42; + } else { + if (array2 == null) { + + } + array = array2; + barrier = 0x42; + } + + int i = 0; + do { + synchronized (new Object()) { + } + v += array[i + off]; + i++; + } while (i < stop); + } + return v; + } + + private static int test2(int stop, boolean flag) { + int v = 0; + + int[] array; + if (flag) { + if (array1 == null) { + + } + array = array1; + barrier = 0x42; + } else { + if (array2 == null) { + + } + array = array2; + barrier = 0x42; + } + + int i = 0; + do { + synchronized (new Object()) { + } + v += array[i + off]; + i++; + } while (i < stop); + return v; + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/loopstripmining/TestLSMBadControlOverride.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/loopstripmining/TestLSMBadControlOverride.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/loopstripmining/TestLSMBadControlOverride.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/loopstripmining/TestLSMBadControlOverride.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. 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 8290781 + * @summary Segfault at PhaseIdealLoop::clone_loop_handle_data_uses + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation TestLSMBadControlOverride + */ + +public class TestLSMBadControlOverride { + private static volatile int barrier; + + public static void main(String[] args) { + int[] array = new int[100]; + int[] small = new int[10]; + for (int i = 0; i < 20_000; i++) { + test(array, array, true, true); + test(array, array, true, false); + test(array, array, false, false); + try { + test(small, array,true, true); + } catch (ArrayIndexOutOfBoundsException aieoobe) { + + } + } + } + + private static int test(int[] array, int[] array2, boolean flag1, boolean flag2) { + int i; + int v = 0; + int v1 = 0; + for (i = 0; i < 100; i++) { + v1 = array[i]; + } + v += v1; + if (flag1) { + if (flag2) { + barrier = 42; + } + } + for (int j = 0; j < 100; j++) { + array[j] = j; + v += array[i-1]; + } + return v; + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/runtime/Test6826736.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/runtime/Test6826736.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/runtime/Test6826736.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/runtime/Test6826736.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2022, 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 @@ -26,6 +26,7 @@ * @bug 6826736 * @summary CMS: core dump with -XX:+UseCompressedOops * + * @requires vm.bits == 64 * @run main/othervm/timeout=600 -XX:+IgnoreUnrecognizedVMOptions -Xbatch * -XX:+ScavengeALot -XX:+UseCompressedOops -XX:HeapBaseMinAddress=32g * -XX:CompileThreshold=100 -XX:-BlockLayoutRotateLoops diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/stringopts/SideEffectBeforeConstructor.jasm openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/stringopts/SideEffectBeforeConstructor.jasm --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/stringopts/SideEffectBeforeConstructor.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/stringopts/SideEffectBeforeConstructor.jasm 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, 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. + */ + +super public class compiler/stringopts/SideEffectBeforeConstructor + version 51:0 +{ + public static Field result:I; + + static Method "":"()V" + stack 2 locals 0 + { + iconst_0; + putstatic Field result:"I"; + return; + } + public Method "":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + public static Method test:"(Ljava/lang/String;)V" + stack 4 locals 1 + { + new class java/lang/StringBuffer; + dup; + getstatic Field result:"I"; + iconst_1; + iadd; + putstatic Field result:"I"; + aload_0; + invokespecial Method java/lang/StringBuffer."":"(Ljava/lang/String;)V"; + invokevirtual Method java/lang/StringBuffer.toString:"()Ljava/lang/String;"; + return; + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/stringopts/TestSideEffectBeforeConstructor.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/stringopts/TestSideEffectBeforeConstructor.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/stringopts/TestSideEffectBeforeConstructor.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/stringopts/TestSideEffectBeforeConstructor.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022, 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 8290705 + * @summary Test correctness of the string concatenation optimization with + * a store between StringBuffer allocation and constructor invocation. + * @compile SideEffectBeforeConstructor.jasm + * @run main/othervm -Xbatch compiler.stringopts.TestSideEffectBeforeConstructor + */ + +package compiler.stringopts; + +public class TestSideEffectBeforeConstructor { + + public static void main(String[] args) { + for (int i = 0; i < 100_000; ++i) { + try { + SideEffectBeforeConstructor.test(null); + } catch (NullPointerException npe) { + // Expected + } + } + if (SideEffectBeforeConstructor.result != 100_000) { + throw new RuntimeException("Unexpected result: " + SideEffectBeforeConstructor.result); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2022, Arm Limited. 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. + */ + +package compiler.vectorapi; + +import jdk.incubator.vector.LongVector; +import jdk.incubator.vector.VectorSpecies; + +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * @test + * @bug 8282528 + * @summary AArch64: Incorrect replicate2L_zero rule + * @library /test/lib + * @requires os.arch == "aarch64" + * @modules jdk.incubator.vector + * @run testng/othervm -XX:UseSVE=0 -XX:-TieredCompilation -XX:CompileThreshold=100 compiler.vectorapi.VectorReplicateLongSpecialImmTest + */ +public class VectorReplicateLongSpecialImmTest { + + private static final VectorSpecies lspec = LongVector.SPECIES_128; + private static final int INVOC_COUNT = 1000; + + private static void assertEquals(LongVector lv, long expected) { + Assert.assertEquals(lv.lane(0), expected); + Assert.assertEquals(lv.lane(1), expected); + } + + @Test + public void testReplicateL_Imm() { + for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) { + // On AArch64 ReplicateL will generate movi, which requires the 64-bit + // imm must be in the form of + // 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh' + assertEquals(LongVector.broadcast(lspec, 0x0000000000000000L), 0x0000000000000000L); + assertEquals(LongVector.broadcast(lspec, 0x00000000000000FFL), 0x00000000000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x000000000000FF00L), 0x000000000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x000000000000FFFFL), 0x000000000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000000000FF0000L), 0x0000000000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x0000000000FF00FFL), 0x0000000000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000000000FFFF00L), 0x0000000000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000000000FFFFFFL), 0x0000000000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00000000FF000000L), 0x00000000FF000000L); + assertEquals(LongVector.broadcast(lspec, 0x00000000FF0000FFL), 0x00000000FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00000000FF00FF00L), 0x00000000FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00000000FF00FFFFL), 0x00000000FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00000000FFFF0000L), 0x00000000FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00000000FFFF00FFL), 0x00000000FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00000000FFFFFF00L), 0x00000000FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00000000FFFFFFFFL), 0x00000000FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FF00000000L), 0x000000FF00000000L); + assertEquals(LongVector.broadcast(lspec, 0x000000FF000000FFL), 0x000000FF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FF0000FF00L), 0x000000FF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x000000FF0000FFFFL), 0x000000FF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FF00FF0000L), 0x000000FF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x000000FF00FF00FFL), 0x000000FF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FF00FFFF00L), 0x000000FF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x000000FF00FFFFFFL), 0x000000FF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFF000000L), 0x000000FFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFF0000FFL), 0x000000FFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFF00FF00L), 0x000000FFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFF00FFFFL), 0x000000FFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFFFF0000L), 0x000000FFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFFFF00FFL), 0x000000FFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFFFFFF00L), 0x000000FFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x000000FFFFFFFFFFL), 0x000000FFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF0000000000L), 0x0000FF0000000000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00000000FFL), 0x0000FF00000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF000000FF00L), 0x0000FF000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF000000FFFFL), 0x0000FF000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF0000FF0000L), 0x0000FF0000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF0000FF00FFL), 0x0000FF0000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF0000FFFF00L), 0x0000FF0000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF0000FFFFFFL), 0x0000FF0000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FF000000L), 0x0000FF00FF000000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FF0000FFL), 0x0000FF00FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FF00FF00L), 0x0000FF00FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FF00FFFFL), 0x0000FF00FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FFFF0000L), 0x0000FF00FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FFFF00FFL), 0x0000FF00FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FFFFFF00L), 0x0000FF00FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FF00FFFFFFFFL), 0x0000FF00FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF00000000L), 0x0000FFFF00000000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF000000FFL), 0x0000FFFF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF0000FF00L), 0x0000FFFF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF0000FFFFL), 0x0000FFFF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF00FF0000L), 0x0000FFFF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF00FF00FFL), 0x0000FFFF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF00FFFF00L), 0x0000FFFF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFF00FFFFFFL), 0x0000FFFF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFF000000L), 0x0000FFFFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFF0000FFL), 0x0000FFFFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFF00FF00L), 0x0000FFFFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFF00FFFFL), 0x0000FFFFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFFFF0000L), 0x0000FFFFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFFFF00FFL), 0x0000FFFFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFFFFFF00L), 0x0000FFFFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x0000FFFFFFFFFFFFL), 0x0000FFFFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF000000000000L), 0x00FF000000000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000000000FFL), 0x00FF0000000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00000000FF00L), 0x00FF00000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00000000FFFFL), 0x00FF00000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF000000FF0000L), 0x00FF000000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF000000FF00FFL), 0x00FF000000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF000000FFFF00L), 0x00FF000000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF000000FFFFFFL), 0x00FF000000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FF000000L), 0x00FF0000FF000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FF0000FFL), 0x00FF0000FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FF00FF00L), 0x00FF0000FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FF00FFFFL), 0x00FF0000FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FFFF0000L), 0x00FF0000FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FFFF00FFL), 0x00FF0000FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FFFFFF00L), 0x00FF0000FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF0000FFFFFFFFL), 0x00FF0000FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF00000000L), 0x00FF00FF00000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF000000FFL), 0x00FF00FF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF0000FF00L), 0x00FF00FF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF0000FFFFL), 0x00FF00FF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF00FF0000L), 0x00FF00FF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF00FF00FFL), 0x00FF00FF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF00FFFF00L), 0x00FF00FF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FF00FFFFFFL), 0x00FF00FF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFF000000L), 0x00FF00FFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFF0000FFL), 0x00FF00FFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFF00FF00L), 0x00FF00FFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFF00FFFFL), 0x00FF00FFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFFFF0000L), 0x00FF00FFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFFFF00FFL), 0x00FF00FFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFFFFFF00L), 0x00FF00FFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FF00FFFFFFFFFFL), 0x00FF00FFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF0000000000L), 0x00FFFF0000000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00000000FFL), 0x00FFFF00000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF000000FF00L), 0x00FFFF000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF000000FFFFL), 0x00FFFF000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF0000FF0000L), 0x00FFFF0000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF0000FF00FFL), 0x00FFFF0000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF0000FFFF00L), 0x00FFFF0000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF0000FFFFFFL), 0x00FFFF0000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FF000000L), 0x00FFFF00FF000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FF0000FFL), 0x00FFFF00FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FF00FF00L), 0x00FFFF00FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FF00FFFFL), 0x00FFFF00FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FFFF0000L), 0x00FFFF00FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FFFF00FFL), 0x00FFFF00FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FFFFFF00L), 0x00FFFF00FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFF00FFFFFFFFL), 0x00FFFF00FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF00000000L), 0x00FFFFFF00000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF000000FFL), 0x00FFFFFF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF0000FF00L), 0x00FFFFFF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF0000FFFFL), 0x00FFFFFF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF00FF0000L), 0x00FFFFFF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF00FF00FFL), 0x00FFFFFF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF00FFFF00L), 0x00FFFFFF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFF00FFFFFFL), 0x00FFFFFF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFF000000L), 0x00FFFFFFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFF0000FFL), 0x00FFFFFFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFF00FF00L), 0x00FFFFFFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFF00FFFFL), 0x00FFFFFFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFFFF0000L), 0x00FFFFFFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFFFF00FFL), 0x00FFFFFFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFFFFFF00L), 0x00FFFFFFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0x00FFFFFFFFFFFFFFL), 0x00FFFFFFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00000000000000L), 0xFF00000000000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF000000000000FFL), 0xFF000000000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000000000FF00L), 0xFF0000000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000000000FFFFL), 0xFF0000000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00000000FF0000L), 0xFF00000000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00000000FF00FFL), 0xFF00000000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00000000FFFF00L), 0xFF00000000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00000000FFFFFFL), 0xFF00000000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FF000000L), 0xFF000000FF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FF0000FFL), 0xFF000000FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FF00FF00L), 0xFF000000FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FF00FFFFL), 0xFF000000FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FFFF0000L), 0xFF000000FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FFFF00FFL), 0xFF000000FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FFFFFF00L), 0xFF000000FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF000000FFFFFFFFL), 0xFF000000FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF00000000L), 0xFF0000FF00000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF000000FFL), 0xFF0000FF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF0000FF00L), 0xFF0000FF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF0000FFFFL), 0xFF0000FF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF00FF0000L), 0xFF0000FF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF00FF00FFL), 0xFF0000FF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF00FFFF00L), 0xFF0000FF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FF00FFFFFFL), 0xFF0000FF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFF000000L), 0xFF0000FFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFF0000FFL), 0xFF0000FFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFF00FF00L), 0xFF0000FFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFF00FFFFL), 0xFF0000FFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFFFF0000L), 0xFF0000FFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFFFF00FFL), 0xFF0000FFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFFFFFF00L), 0xFF0000FFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF0000FFFFFFFFFFL), 0xFF0000FFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF0000000000L), 0xFF00FF0000000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00000000FFL), 0xFF00FF00000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF000000FF00L), 0xFF00FF000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF000000FFFFL), 0xFF00FF000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF0000FF0000L), 0xFF00FF0000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF0000FF00FFL), 0xFF00FF0000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF0000FFFF00L), 0xFF00FF0000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF0000FFFFFFL), 0xFF00FF0000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FF000000L), 0xFF00FF00FF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FF0000FFL), 0xFF00FF00FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FF00FF00L), 0xFF00FF00FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FF00FFFFL), 0xFF00FF00FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FFFF0000L), 0xFF00FF00FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FFFF00FFL), 0xFF00FF00FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FFFFFF00L), 0xFF00FF00FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FF00FFFFFFFFL), 0xFF00FF00FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF00000000L), 0xFF00FFFF00000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF000000FFL), 0xFF00FFFF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF0000FF00L), 0xFF00FFFF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF0000FFFFL), 0xFF00FFFF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF00FF0000L), 0xFF00FFFF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF00FF00FFL), 0xFF00FFFF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF00FFFF00L), 0xFF00FFFF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFF00FFFFFFL), 0xFF00FFFF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFF000000L), 0xFF00FFFFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFF0000FFL), 0xFF00FFFFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFF00FF00L), 0xFF00FFFFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFF00FFFFL), 0xFF00FFFFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFFFF0000L), 0xFF00FFFFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFFFF00FFL), 0xFF00FFFFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFFFFFF00L), 0xFF00FFFFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFF00FFFFFFFFFFFFL), 0xFF00FFFFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF000000000000L), 0xFFFF000000000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000000000FFL), 0xFFFF0000000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00000000FF00L), 0xFFFF00000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00000000FFFFL), 0xFFFF00000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF000000FF0000L), 0xFFFF000000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF000000FF00FFL), 0xFFFF000000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF000000FFFF00L), 0xFFFF000000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF000000FFFFFFL), 0xFFFF000000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FF000000L), 0xFFFF0000FF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FF0000FFL), 0xFFFF0000FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FF00FF00L), 0xFFFF0000FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FF00FFFFL), 0xFFFF0000FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FFFF0000L), 0xFFFF0000FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FFFF00FFL), 0xFFFF0000FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FFFFFF00L), 0xFFFF0000FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF0000FFFFFFFFL), 0xFFFF0000FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF00000000L), 0xFFFF00FF00000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF000000FFL), 0xFFFF00FF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF0000FF00L), 0xFFFF00FF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF0000FFFFL), 0xFFFF00FF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF00FF0000L), 0xFFFF00FF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF00FF00FFL), 0xFFFF00FF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF00FFFF00L), 0xFFFF00FF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FF00FFFFFFL), 0xFFFF00FF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFF000000L), 0xFFFF00FFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFF0000FFL), 0xFFFF00FFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFF00FF00L), 0xFFFF00FFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFF00FFFFL), 0xFFFF00FFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFFFF0000L), 0xFFFF00FFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFFFF00FFL), 0xFFFF00FFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFFFFFF00L), 0xFFFF00FFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFF00FFFFFFFFFFL), 0xFFFF00FFFFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF0000000000L), 0xFFFFFF0000000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00000000FFL), 0xFFFFFF00000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF000000FF00L), 0xFFFFFF000000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF000000FFFFL), 0xFFFFFF000000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF0000FF0000L), 0xFFFFFF0000FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF0000FF00FFL), 0xFFFFFF0000FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF0000FFFF00L), 0xFFFFFF0000FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF0000FFFFFFL), 0xFFFFFF0000FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FF000000L), 0xFFFFFF00FF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FF0000FFL), 0xFFFFFF00FF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FF00FF00L), 0xFFFFFF00FF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FF00FFFFL), 0xFFFFFF00FF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FFFF0000L), 0xFFFFFF00FFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FFFF00FFL), 0xFFFFFF00FFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FFFFFF00L), 0xFFFFFF00FFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFF00FFFFFFFFL), 0xFFFFFF00FFFFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF00000000L), 0xFFFFFFFF00000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF000000FFL), 0xFFFFFFFF000000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF0000FF00L), 0xFFFFFFFF0000FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF0000FFFFL), 0xFFFFFFFF0000FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF00FF0000L), 0xFFFFFFFF00FF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF00FF00FFL), 0xFFFFFFFF00FF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF00FFFF00L), 0xFFFFFFFF00FFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFF00FFFFFFL), 0xFFFFFFFF00FFFFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFF000000L), 0xFFFFFFFFFF000000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFF0000FFL), 0xFFFFFFFFFF0000FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFF00FF00L), 0xFFFFFFFFFF00FF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFF00FFFFL), 0xFFFFFFFFFF00FFFFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFFFF0000L), 0xFFFFFFFFFFFF0000L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFFFF00FFL), 0xFFFFFFFFFFFF00FFL); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFFFFFF00L), 0xFFFFFFFFFFFFFF00L); + assertEquals(LongVector.broadcast(lspec, 0xFFFFFFFFFFFFFFFFL), 0xFFFFFFFFFFFFFFFFL); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/cgroup/CgroupSubsystemFactory.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/cgroup/CgroupSubsystemFactory.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/cgroup/CgroupSubsystemFactory.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/cgroup/CgroupSubsystemFactory.java 2023-01-10 13:21:55.000000000 +0000 @@ -62,11 +62,19 @@ private Path cgroupv1MntInfoZeroHierarchy; private Path cgroupv2CgInfoZeroHierarchy; private Path cgroupv2MntInfoZeroHierarchy; + private Path cgroupv2MntInfoDouble; + private Path cgroupv2MntInfoDouble2; private Path cgroupv1CgInfoNonZeroHierarchy; private Path cgroupv1MntInfoNonZeroHierarchyOtherOrder; private Path cgroupv1MntInfoNonZeroHierarchy; private Path cgroupv1MntInfoDoubleCpuset; private Path cgroupv1MntInfoDoubleCpuset2; + private Path cgroupv1MntInfoDoubleMemory; + private Path cgroupv1MntInfoDoubleMemory2; + private Path cgroupv1MntInfoDoubleCpu; + private Path cgroupv1MntInfoDoubleCpu2; + private Path cgroupv1MntInfoDoublePids; + private Path cgroupv1MntInfoDoublePids2; private Path cgroupv1MntInfoSystemdOnly; private String mntInfoEmpty = ""; private Path cgroupV1SelfCgroup; @@ -160,6 +168,15 @@ private String mntInfoCgroupv1MoreCpusetLine = "121 32 0:37 / /cpusets rw,relatime shared:69 - cgroup none rw,cpuset\n"; private String mntInfoCgroupv1DoubleCpuset = mntInfoCgroupv1MoreCpusetLine + mntInfoHybrid; private String mntInfoCgroupv1DoubleCpuset2 = mntInfoHybrid + mntInfoCgroupv1MoreCpusetLine; + private String mntInfoCgroupv1MoreMemoryLine = "1100 1098 0:28 / /memory rw,nosuid,nodev,noexec,relatime master:6 - cgroup cgroup rw,memory\n"; + private String mntInfoCgroupv1DoubleMemory = mntInfoCgroupv1MoreMemoryLine + mntInfoHybrid; + private String mntInfoCgroupv1DoubleMemory2 = mntInfoHybrid + mntInfoCgroupv1MoreMemoryLine; + private String mntInfoCgroupv1DoubleCpuLine = "1101 1098 0:29 / /cpu,cpuacct rw,nosuid,nodev,noexec,relatime master:7 - cgroup cgroup rw,cpu,cpuacct\n"; + private String mntInfoCgroupv1DoubleCpu = mntInfoCgroupv1DoubleCpuLine + mntInfoHybrid; + private String mntInfoCgroupv1DoubleCpu2 = mntInfoHybrid + mntInfoCgroupv1DoubleCpuLine; + private String mntInfoCgroupv1DoublePidsLine = "1107 1098 0:35 / /pids rw,nosuid,nodev,noexec,relatime master:13 - cgroup cgroup rw,pids\n"; + private String mntInfoCgroupv1DoublePids = mntInfoCgroupv1DoublePidsLine + mntInfoHybrid; + private String mntInfoCgroupv1DoublePids2 = mntInfoHybrid + mntInfoCgroupv1DoublePidsLine; private String cgroupsNonZeroHierarchy = "#subsys_name hierarchy num_cgroups enabled\n" + "cpuset 3 1 1\n" + @@ -175,7 +192,11 @@ "hugetlb 6 1 1\n" + "pids 9 80 1"; // hierarchy has to match procSelfCgroupHybridContent private String mntInfoCgroupsV2Only = - "28 21 0:25 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:4 - cgroup2 none rw,seclabel,nsdelegate"; + "28 21 0:25 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:4 - cgroup2 none rw,seclabel,nsdelegate\n"; + private String mntInfoCgroupsV2MoreLine = + "240 232 0:24 /../.. /cgroup-in ro,relatime - cgroup2 cgroup2 rw,nsdelegate\n"; + private String mntInfoCgroupsV2Double = mntInfoCgroupsV2MoreLine + mntInfoCgroupsV2Only; + private String mntInfoCgroupsV2Double2 = mntInfoCgroupsV2Only + mntInfoCgroupsV2MoreLine; private String mntInfoCgroupsV1SystemdOnly = "35 26 0:26 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd\n" + "26 18 0:19 / /sys/fs/cgroup rw,relatime - tmpfs none rw,size=4k,mode=755\n"; @@ -217,6 +238,12 @@ cgroupv2MntInfoZeroHierarchy = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2"); Files.writeString(cgroupv2MntInfoZeroHierarchy, mntInfoCgroupsV2Only); + cgroupv2MntInfoDouble = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2_double"); + Files.writeString(cgroupv2MntInfoDouble, mntInfoCgroupsV2Double); + + cgroupv2MntInfoDouble2 = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2_double2"); + Files.writeString(cgroupv2MntInfoDouble2, mntInfoCgroupsV2Double2); + cgroupv1CgInfoNonZeroHierarchy = Paths.get(existingDirectory.toString(), "cgroups_non_zero"); Files.writeString(cgroupv1CgInfoNonZeroHierarchy, cgroupsNonZeroHierarchy); @@ -244,6 +271,24 @@ cgroupv1MntInfoDoubleCpuset2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpuset2"); Files.writeString(cgroupv1MntInfoDoubleCpuset2, mntInfoCgroupv1DoubleCpuset2); + cgroupv1MntInfoDoubleMemory = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_memory"); + Files.writeString(cgroupv1MntInfoDoubleMemory, mntInfoCgroupv1DoubleMemory); + + cgroupv1MntInfoDoubleMemory2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_memory2"); + Files.writeString(cgroupv1MntInfoDoubleMemory2, mntInfoCgroupv1DoubleMemory2); + + cgroupv1MntInfoDoubleCpu = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpu"); + Files.writeString(cgroupv1MntInfoDoubleCpu, mntInfoCgroupv1DoubleCpu); + + cgroupv1MntInfoDoubleCpu2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpu2"); + Files.writeString(cgroupv1MntInfoDoubleCpu2, mntInfoCgroupv1DoubleCpu2); + + cgroupv1MntInfoDoublePids = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_pids"); + Files.writeString(cgroupv1MntInfoDoublePids, mntInfoCgroupv1DoublePids); + + cgroupv1MntInfoDoublePids2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_pids2"); + Files.writeString(cgroupv1MntInfoDoublePids2, mntInfoCgroupv1DoublePids2); + cgroupv1MntInfoSystemdOnly = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_systemd_only"); Files.writeString(cgroupv1MntInfoSystemdOnly, mntInfoCgroupsV1SystemdOnly); @@ -291,14 +336,14 @@ System.out.println("testCgroupv1JoinControllerMounts PASSED!"); } - public void testCgroupv1MultipleCpusetMounts(WhiteBox wb, Path mountInfo) { + public void testCgroupv1MultipleControllerMounts(WhiteBox wb, Path mountInfo) { String procCgroups = cgroupv1CgInfoNonZeroHierarchy.toString(); String procSelfCgroup = cgroupV1SelfCgroup.toString(); String procSelfMountinfo = mountInfo.toString(); int retval = wb.validateCgroup(procCgroups, procSelfCgroup, procSelfMountinfo); - Asserts.assertEQ(CGROUPS_V1, retval, "Multiple cpuset controllers, but only one in /sys/fs/cgroup"); + Asserts.assertEQ(CGROUPS_V1, retval, "Multiple controllers, but only one in /sys/fs/cgroup"); Asserts.assertTrue(isValidCgroup(retval)); - System.out.println("testCgroupv1MultipleCpusetMounts PASSED!"); + System.out.println("testCgroupv1MultipleControllerMounts PASSED!"); } public void testCgroupv1SystemdOnly(WhiteBox wb) { @@ -341,10 +386,10 @@ System.out.println("testCgroupv1MissingMemoryController PASSED!"); } - public void testCgroupv2(WhiteBox wb) { + public void testCgroupv2(WhiteBox wb, Path mountInfo) { String procCgroups = cgroupv2CgInfoZeroHierarchy.toString(); String procSelfCgroup = cgroupV2SelfCgroup.toString(); - String procSelfMountinfo = cgroupv2MntInfoZeroHierarchy.toString(); + String procSelfMountinfo = mountInfo.toString(); int retval = wb.validateCgroup(procCgroups, procSelfCgroup, procSelfMountinfo); Asserts.assertEQ(CGROUPS_V2, retval, "Expected"); Asserts.assertTrue(isValidCgroup(retval)); @@ -388,13 +433,21 @@ try { test.testCgroupv1SystemdOnly(wb); test.testCgroupv1NoMounts(wb); - test.testCgroupv2(wb); + test.testCgroupv2(wb, test.cgroupv2MntInfoZeroHierarchy); + test.testCgroupv2(wb, test.cgroupv2MntInfoDouble); + test.testCgroupv2(wb, test.cgroupv2MntInfoDouble2); test.testCgroupV1Hybrid(wb); test.testCgroupV1HybridMntInfoOrder(wb); test.testCgroupv1MissingMemoryController(wb); test.testCgroupv2NoCgroup2Fs(wb); - test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset); - test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset2); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpuset); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpuset2); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleMemory); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleMemory2); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpu); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpu2); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoublePids); + test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoublePids2); test.testCgroupv1JoinControllerCombo(wb); test.testNonZeroHierarchyOnlyFreezer(wb); } finally { diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/DockerBasicTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/DockerBasicTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/DockerBasicTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/DockerBasicTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -53,6 +53,7 @@ try { testJavaVersion(); testHelloDocker(); + testJavaVersionWithCgMounts(); } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { DockerTestUtils.removeDockerImage(imageNameAndTag); @@ -81,4 +82,17 @@ .shouldHaveExitValue(0) .shouldContain("Hello Docker"); } + + + private static void testJavaVersionWithCgMounts() throws Exception { + DockerRunOptions opts = + new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version") + .addDockerOpts("-v", "/sys/fs/cgroup:/cgroups-in:ro"); + + // Duplicated cgroup mounts should be handled by the container detection + // code and should not cause any error/warning output. + DockerTestUtils.dockerRunJava(opts) + .shouldHaveExitValue(0) + .shouldNotMatch("\\[os,container *\\]"); + } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java 2023-01-10 13:21:55.000000000 +0000 @@ -75,10 +75,11 @@ testActiveProcessorCount(2, 2); // cpu quota and period - testCpuQuotaAndPeriod(50*1000, 100*1000); - testCpuQuotaAndPeriod(100*1000, 100*1000); - testCpuQuotaAndPeriod(150*1000, 100*1000); - testCpuQuotaAndPeriod(400*1000, 100*1000); + testCpuQuotaAndPeriod(50*1000, 100*1000, false); + testCpuQuotaAndPeriod(100*1000, 100*1000, false); + testCpuQuotaAndPeriod(150*1000, 100*1000, false); + testCpuQuotaAndPeriod(400*1000, 100*1000, false); + testCpuQuotaAndPeriod(50*1000, 100*1000, true /* additional cgroup mount */); testOperatingSystemMXBeanAwareness("0.5", "1"); testOperatingSystemMXBeanAwareness("1.0", "1"); @@ -174,7 +175,7 @@ } - private static void testCpuQuotaAndPeriod(int quota, int period) + private static void testCpuQuotaAndPeriod(int quota, int period, boolean addCgmounts) throws Exception { Common.logNewTestCase("test cpu quota and period: "); System.out.println("quota = " + quota); @@ -188,6 +189,10 @@ .addDockerOpts("--cpu-period=" + period) .addDockerOpts("--cpu-quota=" + quota); + if (addCgmounts) { + opts = opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroups-in:ro"); + } + Common.run(opts) .shouldMatch("CPU Period is.*" + period) .shouldMatch("CPU Quota is.*" + quota) diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java 2023-01-10 13:21:55.000000000 +0000 @@ -24,6 +24,7 @@ /* * @test + * @bug 8146115 8292083 * @key cgroups * @summary Test JVM's memory resource awareness when running inside docker container * @requires docker.support @@ -41,9 +42,18 @@ import jdk.test.lib.containers.docker.DockerTestUtils; import jdk.test.lib.process.OutputAnalyzer; +import static jdk.test.lib.Asserts.assertNotNull; + public class TestMemoryAwareness { private static final String imageName = Common.imageName("memory"); + private static String getHostMaxMemory() throws Exception { + DockerRunOptions opts = Common.newOpts(imageName); + String goodMem = Common.run(opts).firstMatch("total physical memory: (\\d+)", 1); + assertNotNull(goodMem, "no match for 'total physical memory' in trace output"); + return goodMem; + } + public static void main(String[] args) throws Exception { if (!DockerTestUtils.canTestDocker()) { return; @@ -53,10 +63,11 @@ DockerTestUtils.buildJdkContainerImage(imageName); try { - testMemoryLimit("100m", "104857600"); - testMemoryLimit("500m", "524288000"); - testMemoryLimit("1g", "1073741824"); - testMemoryLimit("4g", "4294967296"); + testMemoryLimit("100m", "104857600", false); + testMemoryLimit("500m", "524288000", false); + testMemoryLimit("1g", "1073741824", false); + testMemoryLimit("4g", "4294967296", false); + testMemoryLimit("100m", "104857600", true /* additional cgroup mount */); testMemorySoftLimit("500m", "524288000"); testMemorySoftLimit("1g", "1073741824"); @@ -76,6 +87,15 @@ "1G", Integer.toString(((int) Math.pow(2, 20)) * 1024), "1500M", Integer.toString(((int) Math.pow(2, 20)) * (1500 - 1024)) ); + testOperatingSystemMXBeanAwareness( + "100M", Integer.toString(((int) Math.pow(2, 20)) * 100), + "200M", Integer.toString(((int) Math.pow(2, 20)) * (200 - 100)), + true /* additional cgroup fs mounts */ + ); + final String hostMaxMem = getHostMaxMemory(); + testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem); + testMetricsIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem); + testContainerMemExceedsPhysical(hostMaxMem); } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { DockerTestUtils.removeDockerImage(imageName); @@ -84,7 +104,7 @@ } - private static void testMemoryLimit(String valueToSet, String expectedTraceValue) + private static void testMemoryLimit(String valueToSet, String expectedTraceValue, boolean addCgmounts) throws Exception { Common.logNewTestCase("memory limit: " + valueToSet); @@ -92,10 +112,28 @@ DockerRunOptions opts = Common.newOpts(imageName) .addDockerOpts("--memory", valueToSet); + if (addCgmounts) { + opts = opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroups-in:ro"); + } + Common.run(opts) .shouldMatch("Memory Limit is:.*" + expectedTraceValue); } + // JDK-8292083 + // Ensure that Java ignores container memory limit values above the host's physical memory. + private static void testContainerMemExceedsPhysical(final String hostMaxMem) + throws Exception { + Common.logNewTestCase("container memory limit exceeds physical memory"); + String badMem = hostMaxMem + "0"; + // set a container memory limit to the bad value + DockerRunOptions opts = Common.newOpts(imageName) + .addDockerOpts("--memory", badMem); + + Common.run(opts) + .shouldMatch("container memory limit (ignored: " + badMem + "|unlimited: -1), using host value " + hostMaxMem); + } + private static void testMemorySoftLimit(String valueToSet, String expectedTraceValue) throws Exception { @@ -137,6 +175,12 @@ private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory, String swapAllocation, String expectedSwap) throws Exception { + testOperatingSystemMXBeanAwareness(memoryAllocation, expectedMemory, swapAllocation, expectedSwap, false); + } + + private static void testOperatingSystemMXBeanAwareness(String memoryAllocation, String expectedMemory, + String swapAllocation, String expectedSwap, boolean addCgroupMounts) throws Exception { + Common.logNewTestCase("Check OperatingSystemMXBean"); DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean") @@ -148,6 +192,10 @@ // diagnostics .addJavaOpts("--add-exports") .addJavaOpts("java.base/jdk.internal.platform=ALL-UNNAMED"); + if (addCgroupMounts) { + // Extra cgroup mount should be ignored by product code + opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroup-in:ro"); + } OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts); out.shouldHaveExitValue(0) @@ -174,4 +222,23 @@ } } + + // JDK-8292541: Ensure OperatingSystemMXBean ignores container memory limits above the host's physical memory. + private static void testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem) + throws Exception { + String badMem = hostMaxMem + "0"; + testOperatingSystemMXBeanAwareness(badMem, hostMaxMem, badMem, hostMaxMem); + } + + // JDK-8292541: Ensure Metrics ignores container memory limits above the host's physical memory. + private static void testMetricsIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem) + throws Exception { + Common.logNewTestCase("Metrics ignore container memory limit exceeding physical memory"); + String badMem = hostMaxMem + "0"; + DockerRunOptions opts = Common.newOpts(imageName) + .addJavaOpts("-XshowSettings:system") + .addDockerOpts("--memory", badMem); + + DockerTestUtils.dockerRunJava(opts).shouldMatch("Memory Limit: Unlimited"); + } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2023-01-10 13:21:55.000000000 +0000 @@ -81,10 +81,19 @@ Common.addWhiteBoxOpts(opts); OutputAnalyzer out = Common.run(opts); - out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit) + // in case of warnings like : "Your kernel does not support swap limit + // capabilities or the cgroup is not mounted. Memory limited without swap." + // we only have Memory and Swap Limit is: in the output + try { + out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit) .shouldContain( "Memory and Swap Limit has been reset to " + expectedResetLimit + " because swappiness is 0") .shouldContain("Memory & Swap Limit: " + expectedLimit); + } catch (RuntimeException ex) { + System.out.println("Expected Memory and Swap Limit output missing."); + System.out.println("You may need to add 'cgroup_enable=memory swapaccount=1' to the Linux kernel boot parameters."); + throw ex; + } } private static void testOSBeanSwappinessMemory(String memoryAllocation, String swapAllocation, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMisc.java openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMisc.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/containers/docker/TestMisc.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/containers/docker/TestMisc.java 2023-01-10 13:21:55.000000000 +0000 @@ -123,6 +123,19 @@ for (String s : expectedToContain) { out.shouldContain(s); } + String str = out.getOutput(); + if (str.contains("cgroupv1")) { + out.shouldContain("kernel_memory_usage_in_bytes"); + out.shouldContain("kernel_memory_max_usage_in_bytes"); + out.shouldContain("kernel_memory_limit_in_bytes"); + } else { + if (str.contains("cgroupv2")) { + out.shouldContain("memory_swap_current_in_bytes"); + out.shouldContain("memory_swap_max_limit_in_bytes"); + } else { + throw new RuntimeException("Output has to contain information about cgroupv1 or cgroupv2"); + } + } } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java 2023-01-10 13:21:55.000000000 +0000 @@ -36,7 +36,7 @@ * gc.epsilon.TestMemoryMXBeans * -1 256 * - * @run main/othervm -Xmx256m -Xmx256m + * @run main/othervm -Xms256m -Xmx256m * -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC * gc.epsilon.TestMemoryMXBeans * 256 256 diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/mixedgc/TestOldGenCollectionUsage.java 2023-01-10 13:21:55.000000000 +0000 @@ -118,9 +118,6 @@ if (collectionCount <= 0) { throw new RuntimeException("Collection count <= 0"); } - if (collectionTime <= 0) { - throw new RuntimeException("Collector has not run"); - } MixedGCProvoker.provokeMixedGC(liveOldObjects); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData27.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, 2022, 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. + */ + +package gc.g1; + +/** + * @test TestShrinkAuxiliaryData27 + * @key randomness + * @bug 8038423 8061715 8078405 + * @summary Checks that decommitment occurs for JVM with different + * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values + * @requires vm.gc.G1 + * @library /test/lib + * @library / + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData27 + */ +public class TestShrinkAuxiliaryData27 { + + public static void main(String[] args) throws Exception { + new TestShrinkAuxiliaryData(27).test(); + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData30.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, 2021, 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. - */ - -package gc.g1; - -/** - * @test TestShrinkAuxiliaryData30 - * @key randomness - * @bug 8038423 8061715 8078405 - * @summary Checks that decommitment occurs for JVM with different - * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values - * @requires vm.gc.G1 - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData30 - */ -public class TestShrinkAuxiliaryData30 { - - public static void main(String[] args) throws Exception { - new TestShrinkAuxiliaryData(30).test(); - } -} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gc/stringdedup/TestStringDeduplicationTools.java 2023-01-10 13:21:55.000000000 +0000 @@ -27,8 +27,12 @@ * Common code for string deduplication tests */ +import com.sun.management.GarbageCollectionNotificationInfo; import java.lang.reflect.*; +import java.lang.management.*; import java.util.*; +import javax.management.*; +import javax.management.openmbean.*; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import sun.misc.*; @@ -89,21 +93,58 @@ } } + private static volatile int gcCount; + private static NotificationListener listener = new NotificationListener() { + @Override + public void handleNotification(Notification n, Object o) { + if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) { + GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData()); + // Shenandoah and Z GC also report GC pauses, skip them + if (info.getGcName().startsWith("Shenandoah") || info.getGcName().startsWith("ZGC")) { + if ("end of GC cycle".equals(info.getGcAction())) { + gcCount++; + } + } else { + gcCount++; + } + } + } + }; + + private static void registerGCListener() { + for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) { + ((NotificationEmitter)bean).addNotificationListener(listener, null, null); + } + } + + private static void unregisterGCListener() { + for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) { + try { + ((NotificationEmitter) bean).removeNotificationListener(listener, null, null); + } catch (Exception e) { + } + } + } + private static void doYoungGc(int numberOfTimes) { - // Provoke at least numberOfTimes young GCs final int objectSize = 128; - final int maxObjectInYoung = (Xmn * MB) / objectSize; List> newStrings = new ArrayList>(); - for (int i = 0; i < numberOfTimes; i++) { + + // Provoke at least numberOfTimes young GCs + gcCount = 0; + registerGCListener(); + while (gcCount < numberOfTimes) { + int currentCount = gcCount; // Create some more strings for every collection, to ensure // there will be deduplication work that will be reported. newStrings.add(createStrings(SmallNumberOfStrings, SmallNumberOfStrings)); - System.out.println("Begin: Young GC " + (i + 1) + "/" + numberOfTimes); - for (int j = 0; j < maxObjectInYoung + 1; j++) { + System.out.println("Begin: Young GC " + (currentCount + 1) + "/" + numberOfTimes); + while (currentCount == gcCount) { dummy = new byte[objectSize]; } - System.out.println("End: Young GC " + (i + 1) + "/" + numberOfTimes); + System.out.println("End: Young GC " + (currentCount + 1) + "/" + numberOfTimes); } + unregisterGCListener(); } private static void forceDeduplication(int ageThreshold, String gcType) { diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/gtest/GTestWrapper.java openjdk-17-17.0.6+10/test/hotspot/jtreg/gtest/GTestWrapper.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/gtest/GTestWrapper.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/gtest/GTestWrapper.java 2023-01-10 13:21:55.000000000 +0000 @@ -83,7 +83,7 @@ command.add("-jdk"); command.add(Utils.TEST_JDK); command.add("--gtest_output=xml:" + resultFile); - command.add("--gtest_catch_exceptions=0" + resultFile); + command.add("--gtest_catch_exceptions=0"); for (String a : args) { command.add(a); } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/ProblemList.txt openjdk-17-17.0.6+10/test/hotspot/jtreg/ProblemList.txt --- openjdk-17-17.0.5+8/test/hotspot/jtreg/ProblemList.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/ProblemList.txt 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2022, 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 @@ -50,22 +50,24 @@ compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x -compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64 -compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64 -compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64 -compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64 -compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64 +compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64,generic-i586 +compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64,generic-i586 compiler/c2/Test8004741.java 8235801 generic-all compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-x64 +compiler/onSpinWait/TestOnSpinWaitAArch64DefaultFlags.java 8277503 linux-aarch64 + ############################################################################# @@ -81,6 +83,8 @@ gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64 +applications/jcstress/acqrel.java 8277434 linux-aarch64 + ############################################################################# # :hotspot_runtime @@ -97,6 +101,7 @@ runtime/os/TestTracePageSizes.java#with-G1 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#with-Parallel 8267460 linux-aarch64 runtime/os/TestTracePageSizes.java#with-Serial 8267460 linux-aarch64 +runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64 ############################################################################# @@ -112,10 +117,13 @@ serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 serviceability/jvmti/CompiledMethodLoad/Zombie.java 8245877 linux-aarch64 -serviceability/sa/ClhsdbCDSCore.java 8269982 macosx-aarch64 -serviceability/sa/ClhsdbFindPC.java#id1 8269982 macosx-aarch64 -serviceability/sa/ClhsdbFindPC.java#id3 8269982 macosx-aarch64 -serviceability/sa/ClhsdbPstack.java#id1 8269982 macosx-aarch64 +serviceability/sa/ClhsdbCDSCore.java 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/ClhsdbFindPC.java#id1 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/ClhsdbFindPC.java#id3 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/ClhsdbPmap.java#id1 8267433 macosx-x64 +serviceability/sa/ClhsdbPstack.java#id1 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/TestJmapCore.java 8267433 macosx-x64 +serviceability/sa/TestJmapCoreMetaspace.java 8267433 macosx-x64 ############################################################################# diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/ProblemList-Xcomp.txt openjdk-17-17.0.6+10/test/hotspot/jtreg/ProblemList-Xcomp.txt --- openjdk-17-17.0.5+8/test/hotspot/jtreg/ProblemList-Xcomp.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/ProblemList-Xcomp.txt 2023-01-10 13:21:55.000000000 +0000 @@ -27,8 +27,6 @@ # ############################################################################# -compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 8268033 generic-x64 - vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64 diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java openjdk-17-17.0.6+10/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -63,7 +63,6 @@ expStrMap.put("g1regiondetails", List.of( "Region", "Eden", - "Survivor", "StartsHumongous", "ContinuesHumongous", "Free")); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java openjdk-17-17.0.6+10/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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,6 +23,8 @@ import jdk.test.lib.apps.LingeredApp; +import java.lang.ref.Reference; + public class LingeredAppWithLargeStringArray extends LingeredApp { public static void main(String args[]) { String[] hugeArray = new String[Integer.MAX_VALUE/8]; @@ -31,5 +33,6 @@ hugeArray[i] = new String(smallArray[i%3]); } LingeredApp.main(args); + Reference.reachabilityFence(hugeArray); } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/HelloUnload.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022, 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 @@ -63,7 +63,7 @@ } URLClassLoader urlClassLoader = - new URLClassLoader("HelloClassLoader", urls, null); + new URLClassLoader("HelloClassLoader" + System.currentTimeMillis(), urls, null); Class c = Class.forName(className, true, urlClassLoader); System.out.println(c); System.out.println(c.getClassLoader()); @@ -86,22 +86,11 @@ ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here"); if (doUnload) { - String loaderName = urlClassLoader.getName(); - int loadedRefcount = wb.getSymbolRefcount(loaderName); - System.out.println("Refcount of symbol " + loaderName + " is " + loadedRefcount); - urlClassLoader = null; c = null; o = null; ClassUnloadCommon.triggerUnloading(); System.out.println("Is CustomLoadee alive? " + wb.isClassAlive(className)); ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded"); - int unloadedRefcount = wb.getSymbolRefcount(loaderName); - System.out.println("Refcount of symbol " + loaderName + " is " + unloadedRefcount); - - // refcount of a permanent symbol will not be decremented - if (loadedRefcount != 65535) { - ClassUnloadCommon.failIf(unloadedRefcount != (loadedRefcount - 1), "Refcount must be decremented"); - } } } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/CDSMHTest_generate.sh openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/CDSMHTest_generate.sh --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/CDSMHTest_generate.sh 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/CDSMHTest_generate.sh 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2022, 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 @@ -31,7 +31,7 @@ fname="$i$name_suffix" cat << EOF > $fname /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -79,6 +79,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class $i extends DynamicArchiveTestBase { @@ -102,14 +103,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesAsCollectorTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesAsCollectorTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesAsCollectorTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesAsCollectorTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesAsCollectorTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesCastFailureTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesCastFailureTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesCastFailureTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesCastFailureTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesCastFailureTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesGeneralTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesGeneralTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesGeneralTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesGeneralTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesGeneralTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesInvokersTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesInvokersTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesInvokersTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesInvokersTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesInvokersTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesPermuteArgumentsTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesPermuteArgumentsTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesPermuteArgumentsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesPermuteArgumentsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesPermuteArgumentsTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesSpreadArgumentsTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesSpreadArgumentsTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesSpreadArgumentsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/methodHandles/MethodHandlesSpreadArgumentsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -47,6 +47,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.Platform; public class MethodHandlesSpreadArgumentsTest extends DynamicArchiveTestBase { @@ -70,14 +71,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); dumpAndRun(topArchiveName, "-Xlog:cds,cds+dynamic=debug,class+load=trace", "-cp", appJar + ps + junitJar, verifyOpt, diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/CDSMHTest_generate.sh openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/CDSMHTest_generate.sh --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/CDSMHTest_generate.sh 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/CDSMHTest_generate.sh 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2022, 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 @@ -31,7 +31,7 @@ fname="$i$name_suffix" cat << EOF > $fname /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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 @@ -78,6 +78,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -106,14 +107,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesCastFailureTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesInvokersTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, 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,6 +46,7 @@ import org.junit.Test; import java.io.File; +import java.nio.file.Path; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; @@ -74,14 +75,7 @@ String verifyOpt = Platform.isDebugBuild() ? "-XX:-VerifyDependencies" : "-showversion"; - String[] classPaths = javaClassPath.split(File.pathSeparator); - String junitJar = null; - for (String path : classPaths) { - if (path.endsWith("junit.jar")) { - junitJar = path; - break; - } - } + String junitJar = Path.of(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toString(); String jars = appJar + ps + junitJar; diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,7 +28,39 @@ * VM handles normal values as well as edge values w/o a crash. * @requires vm.cds * @library /test/lib - * @run driver SharedBaseAddress + * @run driver SharedBaseAddress 0 + */ + +/** + * @test SharedBaseAddress + * @bug 8265705 8267351 + * @summary Test variety of values for SharedBaseAddress, making sure + * VM handles normal values as well as edge values w/o a crash. + * @requires vm.cds + * @library /test/lib + * @run driver SharedBaseAddress 1 + */ + +/** + * @test SharedBaseAddress + * @bug 8265705 8267351 + * @summary Test variety of values for SharedBaseAddress, making sure + * VM handles normal values as well as edge values w/o a crash. + * @requires vm.cds + * @requires vm.bits == 64 + * @library /test/lib + * @run driver SharedBaseAddress 0 provoke + */ + +/** + * @test SharedBaseAddress + * @bug 8265705 8267351 + * @summary Test variety of values for SharedBaseAddress, making sure + * VM handles normal values as well as edge values w/o a crash. + * @requires vm.cds + * @requires vm.bits == 64 + * @library /test/lib + * @run driver SharedBaseAddress 1 provoke */ import jdk.test.lib.cds.CDSTestUtils; @@ -58,18 +90,22 @@ private static String failedPattern = "os::release_memory\\(0x[0-9a-fA-F]*,\\s[0-9]*\\)\\sfailed"; public static void main(String[] args) throws Exception { - - for (int run = 0; run < 2; run ++) { - // We run twice: - // Once, where we want to increase the chance that mapping the generated archive at the designated base - // succeeds, to test Klass pointer encoding at that weird location. We do this by sizing heap + class space - // small, and by switching off compressed oops. - // On the second run, we don't do this but instead go with default parameters. This is more of a test of - // CDS' ability to recover if mapping at runtime fails. - for (String testEntry : testTable) { - String filename = "SharedBaseAddress-base" + testEntry + "-run" + run + ".jsa"; - System.out.println("sharedBaseAddress = " + testEntry); - CDSOptions opts = (new CDSOptions()) + int mid = testTable.length / 2; + int start = args[0].equals("0") ? 0 : mid; + int end = args[0].equals("0") ? mid : testTable.length; + boolean provoke = (args.length > 1 && args[1].equals("provoke")); + + // provoke == true: we want to increase the chance that mapping the generated archive at the designated base + // succeeds, to test Klass pointer encoding at that weird location. We do this by sizing heap + class space + // small, and by switching off compressed oops. + + // provoke == false: we just go with default parameters. This is more of a test of + // CDS' ability to recover if mapping at runtime fails. + for (int i = start; i < end; i++) { + String testEntry = testTable[i]; + String filename = "SharedBaseAddress-base" + testEntry + ".jsa"; + System.out.println("sharedBaseAddress = " + testEntry); + CDSOptions opts = (new CDSOptions()) .setArchiveName(filename) .addPrefix("-XX:SharedBaseAddress=" + testEntry) .addPrefix("-Xlog:cds=debug") @@ -79,18 +115,22 @@ .addPrefix("-Xlog:gc+metaspace") .addPrefix("-XX:NativeMemoryTracking=detail"); - if (run == 0 && Platform.is64bit()) { - opts.addPrefix("-Xmx128m") - .addPrefix("-XX:CompressedClassSpaceSize=32m") - .addPrefix("-XX:-UseCompressedOops"); - } - CDSTestUtils.createArchiveAndCheck(opts); - OutputAnalyzer out = CDSTestUtils.runWithArchiveAndCheck(opts); - if (testEntry.equals("0")) { - out.shouldContain("Archive(s) were created with -XX:SharedBaseAddress=0. Always map at os-selected address.") - .shouldContain("Try to map archive(s) at an alternative address") - .shouldNotMatch(failedPattern); - } + if (provoke) { + opts.addPrefix("-Xmx128m") + .addPrefix("-XX:CompressedClassSpaceSize=32m") + .addPrefix("-XX:-UseCompressedOops"); + } + if (Platform.isDebugBuild()) { + // Make VM start faster in debug build with large heap. + opts.addPrefix("-XX:-ZapUnusedHeapArea"); + } + + CDSTestUtils.createArchiveAndCheck(opts); + OutputAnalyzer out = CDSTestUtils.runWithArchiveAndCheck(opts); + if (testEntry.equals("0")) { + out.shouldContain("Archive(s) were created with -XX:SharedBaseAddress=0. Always map at os-selected address.") + .shouldContain("Try to map archive(s) at an alternative address") + .shouldNotMatch(failedPattern); } } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/GenerateOopMap/if_icmpleIsLastOpcode.jasm 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, 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. + * + */ + +// Old class file with a method whose last bytecode is an unreachable +// conditional branch. +public class if_icmpleIsLastOpcode version 49:0 { + public static Method m1:"()I" stack 1 locals 0 { + iconst_0; + ireturn; + } + + public static Method m2:"(I)V" stack 1 locals 1 { + return; + } + + public static Method test:"()V" stack 2 locals 1 { + iconst_0; + istore_0; + Loop: stack_frame_type append; + locals_map int; + iload_0; + invokestatic Method if_icmpleIsLastOpcode."m1":"()I"; + invokestatic Method if_icmpleIsLastOpcode."m2":"(I)V"; + iinc 0, 1; + ldc 100000; + if_icmple Loop; + return; + ldc 100000; + if_icmple Loop; + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/GenerateOopMap/TestGenerateOopMapCrash.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022, 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 8291459 + * @summary Test that GenerateOopMap does not crash if last bytecode is a conditional branch + * @library /test/lib / + * @requires vm.flagless + * @compile if_icmpleIsLastOpcode.jasm + * @run driver TestGenerateOopMapCrash + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +// This test was copied from compiler test TestLinkageErrorInGenerateOopMap.java. +public class TestGenerateOopMapCrash { + + public static void main(String args[]) throws Exception { + if (args.length == 0) { + // Spawn new VM instance to execute test + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:-TieredCompilation", + "-XX:CompileCommand=dontinline,if_icmpleIsLastOpcode.m*", + "-Xmx64m", + TestGenerateOopMapCrash.class.getName(), + "run"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } else { + // Execute test + if_icmpleIsLastOpcode.test(); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestContext.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestContext.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestContext.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestContext.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,9 +1,7 @@ import sun.hotspot.WhiteBox; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; public class MetaspaceTestContext { @@ -140,6 +138,9 @@ long usageMeasured = usedWords(); long committedMeasured = committedWords(); + System.out.println("context used words " + usageMeasured + ", committed words " + committedMeasured + + "."); + if (usageMeasured > committedMeasured) { throw new RuntimeException("Weirdness."); } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestManyArenasManyThreads.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestManyArenasManyThreads.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestManyArenasManyThreads.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Metaspace/elastic/MetaspaceTestManyArenasManyThreads.java 2023-01-10 13:21:55.000000000 +0000 @@ -83,6 +83,19 @@ // Stop all threads. stopAllThreads(); + // At this point a large number of Arenas will have died (see above), but we probably still have + // some live arenas left. The chunk freelist will be full of free chunks. Maybe a bit fragmented, + // with a healthy mixture of larger and smaller chunks, since we still have live arenas. + // These chunks are all committed still, since we did nothing to reclaim the storage. We now purge + // the context manually to uncommit those chunks, in order to get a realistic number for + // committed words (see checkStatistics()). + // Note: In real metaspace, this happens as part of the same GC which removes class loaders and + // frees their metaspace arenas. All within CLDG::purge(). But since this test isolates the metaspace + // context and does test it separately, GC and CLDG are not involved here. We need to purge manually. + // + // Purging uncommits all free chunks >= 64K/16K (MetaspaceReclaimPolicy=standard/aggressive). + context.purge(); + context.updateTotals(); System.out.println(" ## Finished: " + context); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, Google 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 id=default + * @bug 8292695 + * @summary Check that Ctrl-\ or Ctrl-Break (on Windows) causes HotSpot VM to print a full thread dump. + * @library /vmTestbase + * /test/lib + * @run driver TestBreakSignalThreadDump + */ + +/* + * @test id=with_jsig + * @bug 8292695 + * @summary Check that Ctrl-\ causes HotSpot VM to print a full thread dump when signal chaining is used. + * @requires os.family != "windows" & os.family != "aix" + * @library /vmTestbase + * /test/lib + * @run driver TestBreakSignalThreadDump load_libjsig + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import jdk.test.lib.Platform; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import vm.share.ProcessUtils; + +public class TestBreakSignalThreadDump { + + static class TestProcess { + static { + System.loadLibrary("ProcessUtils"); + } + + public static void main(String[] argv) throws Exception { + ProcessUtils.sendCtrlBreak(); + // Wait a bit, as JVM processes the break signal asynchronously. + Thread.sleep(1000); + System.out.println("Done!"); + } + } + + public static void main(String[] argv) throws Exception { + String main = "TestBreakSignalThreadDump$TestProcess"; + ProcessBuilder pb = ProcessTools.createTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, main); + + if (argv.length > 0 && argv[0].equals("load_libjsig")) { + prepend_jsig_lib(pb.environment()); + } + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + output.shouldContain("Full thread dump "); + output.shouldContain("java.lang.Thread.State: RUNNABLE"); + output.shouldContain("Done!"); + } + + private static void prepend_jsig_lib(Map env) { + Path libjsig = Platform.jvmLibDir().resolve("libjsig." + Platform.sharedLibraryExt()); + if (!Files.exists(libjsig)) { + throw new RuntimeException("File libjsig not found, path: " + libjsig); + } + String env_var = Platform.isOSX() ? "DYLD_INSERT_LIBRARIES" : "LD_PRELOAD"; + env.put(env_var, libjsig.toString()); + } +} diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java 2023-01-10 13:21:55.000000000 +0000 @@ -182,6 +182,15 @@ methodAddr)); runTest(withCore, cmds, expStrMap); + // Rerun above findpc command, but this time using "whatis", which is an alias for "findpc". + cmdStr = "whatis " + methodAddr; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("Method ", + "LingeredApp.steadyState", + methodAddr)); + runTest(withCore, cmds, expStrMap); + // Run findpc on a JavaThread*. We can find one in the jstack output. // The tid for a thread is it's JavaThread*. For example: // "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ... diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -47,6 +47,7 @@ import java.util.ArrayList; import jdk.test.lib.Utils; import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; import jtreg.SkippedException; public class ClhsdbScanOops { @@ -71,35 +72,54 @@ Map> expStrMap = new HashMap<>(); Map> unExpStrMap = new HashMap<>(); - String startAddress = null; - String endAddress = null; - String[] snippets = null; + String startAddress; + String endAddress; + String[] snippets; + String[] words; + String cmd; + // Run scanoops on the old gen + if (gc.contains("UseParallelGC")) { + snippets = universeOutput.split("PSOldGen \\[ "); + } else { + snippets = universeOutput.split("old \\["); + } + words = snippets[1].split(","); + // Get the addresses for Old gen + startAddress = words[0].replace("[", ""); + endAddress = words[1]; + cmd = "scanoops " + startAddress + " " + endAddress; + String output1 = test.run(theApp.getPid(), List.of(cmd), null, null); + + // Run scanoops on the eden gen if (gc.contains("UseParallelGC")) { snippets = universeOutput.split("eden = "); } else { snippets = universeOutput.split("eden \\["); } - String[] words = snippets[1].split(","); - // Get the addresses from Eden + words = snippets[1].split(","); + // Get the addresses for Eden gen startAddress = words[0].replace("[", ""); endAddress = words[1]; - String cmd = "scanoops " + startAddress + " " + endAddress; - cmds.add(cmd); + cmd = "scanoops " + startAddress + " " + endAddress; + String output2 = test.run(theApp.getPid(), List.of(cmd), null, null); - expStrMap.put(cmd, List.of - ("java/lang/Object", "java/lang/Class", "java/lang/Thread", - "java/lang/String", "\\[B", "\\[I")); + // Look for expected types in the combined eden and old gens + OutputAnalyzer out = new OutputAnalyzer(output1 + output2); + List expectStrs = List.of( + "java/lang/Object", "java/lang/Class", "java/lang/Thread", + "java/lang/String", "\\[B", "\\[I"); + for (String expectStr : expectStrs) { + out.shouldMatch(expectStr); + } - // Test the 'type' option also - // scanoops java/lang/String + // Test the 'type' option also: + // scanoops java/lang/String // Ensure that only the java/lang/String oops are printed. cmd = cmd + " java/lang/String"; - cmds.add(cmd); expStrMap.put(cmd, List.of("java/lang/String")); - unExpStrMap.put(cmd, List.of("java/lang/Thread")); - - test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap); + unExpStrMap.put(cmd, List.of("java/lang/Thread", "java/lang/Class", "java/lang/Object")); + test.run(theApp.getPid(), List.of(cmd), expStrMap, unExpStrMap); } catch (SkippedException e) { throw e; } catch (Exception ex) { diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLock.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -47,6 +47,19 @@ objectLock.start(); primitiveLock.start(); + // Wait until all threads have reached their blocked or timed wait state + while ((classLock1.getState() != Thread.State.BLOCKED && + classLock1.getState() != Thread.State.TIMED_WAITING) || + (classLock2.getState() != Thread.State.BLOCKED && + classLock2.getState() != Thread.State.TIMED_WAITING) || + (objectLock.getState() != Thread.State.TIMED_WAITING) || + (primitiveLock.getState() != Thread.State.TIMED_WAITING)) { + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + } + } + LingeredApp.main(args); } } diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/TestClassDump.java openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/TestClassDump.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/TestClassDump.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/TestClassDump.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -30,6 +30,7 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.SA.SATestUtils; +import jtreg.SkippedException; /** * @test @@ -87,6 +88,10 @@ public static void main(String[] args) throws Exception { SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work. + if (SATestUtils.needsPrivileges()) { + // This test will create files as root that cannot be easily deleted, so don't run. + throw new SkippedException("Cannot run this test on OSX if adding privileges is required."); + } LingeredApp theApp = null; try { theApp = LingeredApp.startApp(); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,8 +59,12 @@ while (itr.hasNext()) { ObjectMonitor mon = (ObjectMonitor)itr.next(); - Oop oop = heap.newOop(mon.object()); - System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + if (mon.object() == null) { + System.out.println("Monitor found: object is null"); + } else { + Oop oop = heap.newOop(mon.object()); + System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + } } } finally { agent.detach(); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC2/LoadUnloadGC2.java openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC2/LoadUnloadGC2.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC2/LoadUnloadGC2.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/gc/gctests/LoadUnloadGC2/LoadUnloadGC2.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, 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 @@ -31,11 +31,14 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm -XX:-UseGCOverheadLimit gc.gctests.LoadUnloadGC2.LoadUnloadGC2 + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.gctests.LoadUnloadGC2.LoadUnloadGC2 */ package gc.gctests.LoadUnloadGC2; +import jdk.test.whitebox.WhiteBox; import nsk.share.*; import nsk.share.test.*; import nsk.share.gc.*; @@ -44,15 +47,24 @@ import java.lang.reflect.Array; public class LoadUnloadGC2 extends GCTestBase { + private static int CYCLE = 1000; public void run() { Stresser stresser = new Stresser(runParams.getStressOptions()); stresser.start(500000); + int iteration = 0; try { + GarbageProducer garbageProducer = new GeneratedClassProducer(); while (stresser.iteration()) { - GarbageProducer garbageProducer = new GeneratedClassProducer(); - log.info("Iteration: " + stresser.getIteration()); - GarbageUtils.eatMemory(stresser, garbageProducer, 0); - garbageProducer = null; + garbageProducer.create(512L); + if(iteration++ > CYCLE) { + // Unload once every cycle. + iteration = 0; + garbageProducer = null; + // Perform GC so that + // class gets unloaded + WhiteBox.getWhiteBox().fullGC(); + garbageProducer = new GeneratedClassProducer(); + } } } finally { stresser.finish(); diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java --- openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except010.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, 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 @@ -58,6 +58,7 @@ * JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug: * #4245057 (P2/S3) VM crashes when heap is exhausted * + * @requires vm.opt.DeoptimizeALot != true * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except010 */ diff -Nru openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/nativeAndMH.cpp openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/nativeAndMH.cpp --- openjdk-17-17.0.5+8/test/hotspot/jtreg/vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/nativeAndMH.cpp 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/hotspot/jtreg/vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/nativeAndMH.cpp 2023-01-10 13:21:55.000000000 +0000 @@ -56,7 +56,8 @@ NSK_JNI_VERIFY(pEnv, NULL != (objectClass = pEnv->FindClass("java/lang/Object"))); - NSK_JNI_VERIFY(pEnv, NULL != (arguments = pEnv->NewObjectArray(ARGS_COUNT, objectClass, NULL))); + if (!NSK_JNI_VERIFY(pEnv, NULL != (arguments = pEnv->NewObjectArray(ARGS_COUNT, objectClass, NULL)))) + return NULL; NSK_JNI_VERIFY_VOID(pEnv, pEnv->SetObjectArrayElement(arguments, 0, a1)); NSK_JNI_VERIFY_VOID(pEnv, pEnv->SetObjectArrayElement(arguments, 1, a2)); diff -Nru openjdk-17-17.0.5+8/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java openjdk-17-17.0.6+10/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java --- openjdk-17-17.0.5+8/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -34,15 +34,20 @@ import org.testng.Assert; import org.testng.annotations.Listeners; import org.testng.annotations.Test; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.events.Event; import org.w3c.dom.events.EventListener; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSInput; +import org.w3c.dom.ls.LSParser; /* * @test - * @bug 8213117 8222743 + * @bug 8213117 8222743 8287076 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @modules java.xml * @modules java.xml/com.sun.org.apache.xerces.internal.dom @@ -56,6 +61,53 @@ static final int DOC1 = 1; static final int DOC2 = 2; + /* + * @bug 8287076 + * Verifies that Document::normalizeDocument returns the same result as that + * prior to JDK 10 (JDK-8181150). + * Attribute Name: + * JDK 9: NS1:wsu and NS2:wsu2 + * After the JDK 10 change: wsu and wsu2 + */ + @Test + public void testNormalizeDocument() throws Exception { + final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + final LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + final LSInput input = impl.createLSInput(); + input.setStringData(""); + final Document document = builder.parse(input); + final Element root = document.getDocumentElement(); + + // Generate a single element + final Element element = document.createElement("token"); + final Attr attr = element.getOwnerDocument().createAttributeNS("http://blah.xsd", "wsu"); + attr.setValue("Id"); + element.setAttributeNodeNS(attr); + + final Attr attr2 = element.getOwnerDocument().createAttributeNS("http://blah2.xsd", "wsu2"); + element.setAttributeNodeNS(attr2); + + final Attr attr3 = element.getOwnerDocument().createAttribute("aa"); + element.setAttributeNodeNS(attr3); + + final Attr attr4 = element.getOwnerDocument().createAttribute("zz"); + element.setAttributeNodeNS(attr4); + + final Attr attr5 = element.getOwnerDocument().createAttribute("tt"); + element.setAttributeNodeNS(attr5); + + root.appendChild(element); + + document.normalizeDocument(); + + Node wsu = element.getAttributes().getNamedItemNS("http://blah.xsd", "wsu"); + Node wsu2 = element.getAttributes().getNamedItemNS("http://blah2.xsd", "wsu2"); + + Assert.assertEquals(wsu.getNodeName(), "NS1:wsu"); + Assert.assertEquals(wsu2.getNodeName(), "NS2:wsu2"); + } + /** * Verifies the adoptNode method. Before a node from a deferred DOM can be * adopted, it needs to be fully expanded. diff -Nru openjdk-17-17.0.5+8/test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java openjdk-17-17.0.6+10/test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java --- openjdk-17-17.0.5+8/test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, 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 @@ -24,18 +24,21 @@ /** * @test * @key headful - * @bug 8007267 + * @bug 8007267 8233648 * @summary [macosx] com.apple.eawt.Application.setDefaultMenuBar is not working * @requires (os.family == "mac") - * @author leonid.romanov@oracle.com - * @modules java.desktop/sun.awt - * java.desktop/com.apple.eawt - * @run main DefaultMenuBarTest + * @modules java.desktop/com.apple.eawt + * @run main/othervm DefaultMenuBarTest */ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Robot; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.lang.reflect.Method; @@ -50,14 +53,11 @@ } System.setProperty("apple.laf.useScreenMenuBar", "true"); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(DefaultMenuBarTest::createAndShowGUI); Robot robot = new Robot(); robot.setAutoDelay(100); + robot.waitForIdle(); robot.keyPress(KeyEvent.VK_META); robot.keyPress(ks.getKeyCode()); @@ -76,13 +76,7 @@ JMenuItem newItem = new JMenuItem("Open"); newItem.setAccelerator(ks); - newItem.addActionListener( - new ActionListener(){ - public void actionPerformed(ActionEvent e) { - listenerCallCounter++; - } - } - ); + newItem.addActionListener(e -> listenerCallCounter++); menu.add(newItem); JMenuBar defaultMenu = new JMenuBar(); @@ -104,7 +98,7 @@ } } } catch (Exception e) { - e.printStackTrace(); + throw new RuntimeException(e); } } } diff -Nru openjdk-17-17.0.5+8/test/jdk/com/sun/jdi/ClassUnloadEventTest.java openjdk-17-17.0.6+10/test/jdk/com/sun/jdi/ClassUnloadEventTest.java --- openjdk-17-17.0.5+8/test/jdk/com/sun/jdi/ClassUnloadEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/com/sun/jdi/ClassUnloadEventTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2022, 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 8256811 + * @modules java.base/jdk.internal.org.objectweb.asm + * java.base/jdk.internal.misc + * @library /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm/native ClassUnloadEventTest run + */ + +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.Label; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.test.lib.classloader.ClassUnloadCommon; + +import com.sun.jdi.*; +import com.sun.jdi.connect.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.*; + +import java.util.*; +import java.io.*; + +public class ClassUnloadEventTest { + static final String CLASS_NAME_PREFIX = "SampleClass__"; + static final String CLASS_NAME_ALT_PREFIX = CLASS_NAME_PREFIX + "Alt__"; + static final int NUM_CLASSES = 10; + static final int NUM_ALT_CLASSES = NUM_CLASSES / 2; + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + try { + runDebuggee(); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } else { + runDebugger(); + } + } + + private static class TestClassLoader extends ClassLoader implements Opcodes { + private static byte[] generateSampleClass(String name) { + ClassWriter cw = new ClassWriter(0); + + cw.visit(52, ACC_SUPER | ACC_PUBLIC, name, null, "java/lang/Object", null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()V", null, null); + mv.visitCode(); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + cw.visitEnd(); + return cw.toByteArray(); + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (name.startsWith(CLASS_NAME_PREFIX)) { + byte[] bytecode = generateSampleClass(name); + return defineClass(name, bytecode, 0, bytecode.length); + } else { + return super.findClass(name); + } + } + } + + private static void runDebuggee() { + System.out.println("Running debuggee"); + ClassLoader loader = new TestClassLoader(); + for (int index = 0; index < NUM_CLASSES; index++) { + try { + if (index < NUM_ALT_CLASSES) { + Class.forName(CLASS_NAME_ALT_PREFIX + index, true, loader); + } else { + Class.forName(CLASS_NAME_PREFIX + index, true, loader); + } + } catch (Exception e) { + throw new RuntimeException("Failed to create Sample class", e); + } + } + loader = null; + + // Do a short delay to make sure that the debug agent is done processing all + // ClassPrepare events. Otherwise the debug agent might still be holding on to + // a reference to a class, which will prevent it from unloading during the GC. + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + } + + // Trigger class unloading + ClassUnloadCommon.triggerUnloading(); + + // We rely on JVMTI to post all pending ObjectFree events at VM shutdown. + // It will trigger the JDWP agent to synthesize expected ClassUnloadEvents events. + System.out.println("Exiting debuggee"); + } + + private static void runDebugger() throws Exception { + System.out.println("Running debugger"); + HashSet unloadedSampleClasses = new HashSet<>(); + HashSet unloadedSampleClasses_alt = new HashSet<>(); + VirtualMachine vm = null; + vm = connectAndLaunchVM(); + ClassUnloadRequest classUnloadRequest = vm.eventRequestManager().createClassUnloadRequest(); + classUnloadRequest.addClassFilter(CLASS_NAME_PREFIX + "*"); + classUnloadRequest.enable(); + + ClassUnloadRequest classUnloadRequest_alt = vm.eventRequestManager().createClassUnloadRequest(); + classUnloadRequest_alt.addClassFilter(CLASS_NAME_ALT_PREFIX + "*"); + classUnloadRequest_alt.enable(); + + EventSet eventSet = null; + boolean exited = false; + while (!exited && (eventSet = vm.eventQueue().remove()) != null) { + System.out.println("EventSet: " + eventSet); + for (Event event : eventSet) { + if (event instanceof ClassUnloadEvent) { + String className = ((ClassUnloadEvent)event).className(); + + // The unloaded class should always match CLASS_NAME_PREFIX. + if (className.indexOf(CLASS_NAME_PREFIX) == -1) { + throw new RuntimeException("FAILED: Unexpected unloaded class: " + className); + } + + // Unloaded classes with ALT names should only occur on the classUnloadRequest_alt. + if (event.request() == classUnloadRequest_alt) { + unloadedSampleClasses_alt.add(className); + if (className.indexOf(CLASS_NAME_ALT_PREFIX) == -1) { + throw new RuntimeException("FAILED: non-alt class unload event for classUnloadRequest_alt."); + } + } else { + unloadedSampleClasses.add(className); + } + + // If the unloaded class matches the ALT prefix, then we should have + // unload events in this EventSet for each of the two ClassUnloadRequesta. + int expectedEventSetSize; + if (className.indexOf(CLASS_NAME_ALT_PREFIX) != -1) { + expectedEventSetSize = 2; + } else { + expectedEventSetSize = 1; + } + if (eventSet.size() != expectedEventSetSize) { + throw new RuntimeException("FAILED: Unexpected eventSet size: " + eventSet.size()); + } + } + + if (event instanceof VMDeathEvent) { + exited = true; + break; + } + } + eventSet.resume(); + } + + /* Dump debuggee output. */ + Process p = vm.process(); + BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); + BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream())); + String line = in.readLine(); + while (line != null) { + System.out.println("stdout: " + line); + line = in.readLine(); + } + line = err.readLine(); + while (line != null) { + System.out.println("stderr: " + line); + line = err.readLine(); + } + + if (unloadedSampleClasses.size() != NUM_CLASSES) { + throw new RuntimeException("Wrong number of class unload events: expected " + NUM_CLASSES + " got " + unloadedSampleClasses.size()); + } + if (unloadedSampleClasses_alt.size() != NUM_ALT_CLASSES) { + throw new RuntimeException("Wrong number of alt class unload events: expected " + NUM_ALT_CLASSES + " got " + unloadedSampleClasses_alt.size()); + } + } + + private static VirtualMachine connectAndLaunchVM() throws IOException, + IllegalConnectorArgumentsException, + VMStartException { + LaunchingConnector launchingConnector = Bootstrap.virtualMachineManager().defaultConnector(); + Map arguments = launchingConnector.defaultArguments(); + arguments.get("main").setValue(ClassUnloadEventTest.class.getName()); + arguments.get("options").setValue("--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xlog:class+unload=info -Xlog:gc"); + return launchingConnector.launch(arguments); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/a11y/AccessibleActionsTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/a11y/AccessibleActionsTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/a11y/AccessibleActionsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/a11y/AccessibleActionsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -40,6 +40,8 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; import java.util.Hashtable; import java.util.concurrent.CountDownLatch; @@ -92,6 +94,32 @@ super.createUI(panel, "AccessibleActionsTest"); } + private void createEditableTextArea() { + AccessibleComponentTest.INSTRUCTIONS = "INSTRUCTIONS:\n" + + "Check a11y show context menu in editable JTextArea.\n\n" + + "Turn screen reader on and press Tab to move to the text area\n" + + "Perform the VO action \"Open a shortcut menu\" (VO+Shift+m)\n\n" + + "If the menu appears tab further and press PASS, otherwise press FAIL."; + + JTextArea textArea = new MyTextArea("some text to edit"); + JLabel label = new JLabel(textArea.getText().length() + " chars"); + label.setLabelFor(textArea); + textArea.setEditable(true); + textArea.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + label.setText(String.valueOf(textArea.getText().length()) + " chars"); + } + }); + + JPanel panel = new JPanel(); + panel.setLayout(new FlowLayout()); + panel.add(textArea); + panel.add(label); + exceptionString = "Editable text area test failed!"; + super.createUI(panel, "AccessibleTextTest"); + } + public static void main(String[] args) throws Exception { AccessibleActionsTest test = new AccessibleActionsTest(); @@ -110,6 +138,14 @@ if (!testResult) { throw new RuntimeException(a11yTest.exceptionString); } + + countDownLatch = test.createCountDownLatch(); + SwingUtilities.invokeLater(test::createEditableTextArea); + countDownLatch.await(); + + if (!testResult) { + throw new RuntimeException(a11yTest.exceptionString); + } } private class AccessibleActionsTestFrame extends JPanel { @@ -167,17 +203,70 @@ } } - private static JPopupMenu createPopup() { - JPopupMenu popup = new JPopupMenu("MENU"); - popup.add("One"); - popup.add("Two"); - popup.add("Three"); - return popup; - } + private static void changeText(JLabel label, String text) { label.setText(text); } } + + private static class MyTextArea extends JTextArea { + + public MyTextArea(String some_text_to_edit) { + } + + @Override + public AccessibleContext getAccessibleContext() { + if (accessibleContext == null) { + accessibleContext = new MyAccessibleJTextArea(); + } + return accessibleContext; + } + + private class MyAccessibleJTextArea extends JTextArea.AccessibleJTextArea { + @Override + public AccessibleAction getAccessibleAction() { + return new AccessibleAction() { + @Override + public int getAccessibleActionCount() { + AccessibleAction aa = MyAccessibleJTextArea.super.getAccessibleAction(); + if (aa == null) { + return 1; + } + int count = aa.getAccessibleActionCount(); + return aa.getAccessibleActionCount() + 1; +} + + @Override + public String getAccessibleActionDescription(int i) { + AccessibleAction aa = MyAccessibleJTextArea.super.getAccessibleAction(); + if ((aa != null) && (i >= 0) && (i < aa.getAccessibleActionCount())) { + return aa.getAccessibleActionDescription(i); + } + return AccessibleAction.TOGGLE_POPUP; + } + + @Override + public boolean doAccessibleAction(int i) { + AccessibleAction aa = MyAccessibleJTextArea.super.getAccessibleAction(); + if ((aa != null) && (i >= 0) && (i < aa.getAccessibleActionCount())) { + return aa.doAccessibleAction(i); + } + JPopupMenu popup = createPopup(); + popup.show(MyTextArea.this, 0, 0); + return true; + } + }; + } + } + } + + private static JPopupMenu createPopup() { + JPopupMenu popup = new JPopupMenu("MENU"); + popup.add("One"); + popup.add("Two"); + popup.add("Three"); + return popup; + } } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/a11y/AccessibleJPopupMenuTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/a11y/AccessibleJPopupMenuTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/a11y/AccessibleJPopupMenuTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/a11y/AccessibleJPopupMenuTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -93,7 +93,7 @@ public static void main(String[] args) throws Exception { AccessibleJPopupMenuTest a11yTest = new AccessibleJPopupMenuTest(); - CountDownLatch countDownLatch = a11yTest.createCountDownLatch(); + countDownLatch = a11yTest.createCountDownLatch(); SwingUtilities.invokeLater(a11yTest::createTest); countDownLatch.await(); diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -26,7 +26,7 @@ * @bug 8190230 8196360 * @summary [macosx] Order of overlapping of modal dialogs is wrong * @key headful - * @run main SiblingChildOrderTest + * @run main/othervm -Dsun.java2d.uiScale=1 SiblingChildOrderTest */ import java.awt.Color; diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/dnd/DropTargetInInternalFrameTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/dnd/DropTargetInInternalFrameTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/dnd/DropTargetInInternalFrameTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/dnd/DropTargetInInternalFrameTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2000, 2022, 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.Button; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetContext; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + @test + @bug 4395279 + @summary Tests that a drop target in InternalFrame functions properly + @key headful + @run main DropTargetInInternalFrameTest +*/ +public class DropTargetInInternalFrameTest implements Serializable { + private static final CountDownLatch dropLatch = new CountDownLatch(1); + private static final CountDownLatch focusLatch = new CountDownLatch(1); + private static JFrame frame; + private static JInternalFrame sourceFrame; + private static JInternalFrame targetFrame; + private static DragSourcePanel dragSourcePanel; + private static DropTargetPanel dropTargetPanel; + private static Robot robot; + + private static void createUI() { + frame = new JFrame("Test frame"); + sourceFrame = new JInternalFrame("Source"); + targetFrame = new JInternalFrame("Destination"); + dragSourcePanel = new DragSourcePanel(); + dropTargetPanel = new DropTargetPanel(dropLatch); + JDesktopPane desktopPane = new JDesktopPane(); + + sourceFrame.getContentPane().setLayout(new GridLayout(3, 1)); + + // add panels to content panes + sourceFrame.getContentPane().add(dragSourcePanel); + targetFrame.getContentPane().add(dropTargetPanel); + + sourceFrame.setSize(200, 200); + targetFrame.setSize(200, 200); + targetFrame + .setLocation(sourceFrame.getX() + sourceFrame.getWidth() + 10, + sourceFrame.getY()); + + desktopPane.add(sourceFrame); + desktopPane.add(targetFrame); + + frame.setTitle("Test frame"); + frame.setBounds(200, 200, 450, 250); + frame.getContentPane().add(desktopPane); + frame.setAlwaysOnTop(true); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + sourceFrame.setVisible(true); + targetFrame.setVisible(true); + frame.setVisible(true); + dragSourcePanel.dragSourceButton.requestFocusInWindow(); + } + + public static void main(String[] argv) throws Exception { + SwingUtilities.invokeAndWait(DropTargetInInternalFrameTest::createUI); + + robot = new Robot(); + robot.setAutoDelay(50); + robot.setAutoWaitForIdle(true); + robot.waitForIdle(); + if (!focusLatch.await(5, TimeUnit.SECONDS)) { + captureScreen(); + SwingUtilities + .invokeAndWait(DropTargetInInternalFrameTest::disposeFrame); + System.out.println( + "Test failed, waited too long for the drag button to gain focus"); + } + final AtomicReference p1Ref = new AtomicReference<>(); + final AtomicReference p2Ref = new AtomicReference<>(); + SwingUtilities.invokeAndWait(() -> { + final Point dragLocation = + dragSourcePanel.dragSourceButton.getLocationOnScreen(); + Dimension d1 = dragSourcePanel.dragSourceButton.getSize(); + dragLocation.translate(d1.width / 2, d1.height / 2); + p1Ref.set(dragLocation); + final Point dropLocation = dropTargetPanel.getLocationOnScreen(); + dropLocation.translate(d1.width / 2, d1.height / 2); + p2Ref.set(dropLocation); + }); + Point p1 = p1Ref.get(); + Point p2 = p2Ref.get(); + + dragAndDrop(p1, p2); + + if (!dropLatch.await(5, TimeUnit.SECONDS)) { + captureScreen(); + System.out.println("Test Failed, Waited too long for the Drop to complete"); + } + int calledMethods = dropTargetPanel.getCalledMethods(); + SwingUtilities + .invokeAndWait(DropTargetInInternalFrameTest::disposeFrame); + System.out.println("CalledMethods = " + calledMethods); + if ((calledMethods & DropTargetPanel.ENTER_CALLED) == 0) { + throw new RuntimeException( + "Test Failed, DropTargetListener.dragEnter() not called"); + } + if ((calledMethods & DropTargetPanel.OVER_CALLED) == 0) { + throw new RuntimeException( + "Test Failed, DropTargetListener.dragOver() not called"); + } + if ((calledMethods & DropTargetPanel.DROP_CALLED) == 0) { + throw new RuntimeException( + "Test Failed, DropTargetListener.drop() not called."); + } + + System.out.println("Test Passed"); + } + + private static void dragAndDrop(final Point p1, final Point p2) { + robot.mouseMove(p1.x, p1.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + int dx = 1; + while (p1.x < p2.x) { + p1.translate(dx, 0); + robot.mouseMove(p1.x, p1.y); + dx++; + } + robot.mouseMove(p2.x, p2.y); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + private static void captureScreen() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + try { + ImageIO.write(robot.createScreenCapture( + new Rectangle(0, 0, screenSize.width, screenSize.height)), + "png", new File("screenImage.png")); + } catch (IOException ignore) { + } + } + + private static void disposeFrame() { + sourceFrame.dispose(); + targetFrame.dispose(); + frame.dispose(); + } + + private static class DragSourcePanel extends JPanel { + + final Dimension preferredDimension = new Dimension(200, 100); + final DragSourceButton dragSourceButton = new DragSourceButton(); + + public DragSourcePanel() { + setLayout(new GridLayout(1, 1)); + dragSourceButton.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + super.focusGained(e); + focusLatch.countDown(); + } + }); + add(dragSourceButton); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + } + + private static class DropTargetPanel extends JPanel + implements DropTargetListener { + + public static final int ENTER_CALLED = 0x1; + public static final int OVER_CALLED = 0x2; + public static final int DROP_CALLED = 0x4; + private final Dimension preferredDimension = new Dimension(200, 100); + private final CountDownLatch dropLatch; + private volatile int calledMethods = 0; + + public DropTargetPanel(final CountDownLatch dropLatch) { + this.dropLatch = dropLatch; + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + calledMethods |= ENTER_CALLED; + } + + public void dragOver(DropTargetDragEvent dtde) { + calledMethods |= OVER_CALLED; + } + + public void dropActionChanged(DropTargetDragEvent dtde) { + } + + public void dragExit(DropTargetEvent dte) { + } + + public void drop(DropTargetDropEvent dtde) { + System.out.println("Drop!!!!!!!!!!!! "); + calledMethods |= DROP_CALLED; + DropTargetContext dtc = dtde.getDropTargetContext(); + + if ((dtde.getSourceActions() & DnDConstants.ACTION_COPY) != 0) { + dtde.acceptDrop(DnDConstants.ACTION_COPY); + } else { + dtde.rejectDrop(); + } + + DataFlavor[] dfs = dtde.getCurrentDataFlavors(); + Component comp = null; + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + comp = (Component) transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + add(comp); + dropLatch.countDown(); + } + + public int getCalledMethods() { + return calledMethods; + } + + } + + private static class DragSourceButton extends JButton + implements Serializable, Transferable, DragGestureListener, + DragSourceListener { + private final DataFlavor dataflavor = + new DataFlavor(Button.class, "DragSourceButton"); + + public DragSourceButton() { + this("DragSourceButton"); + } + + public DragSourceButton(String str) { + super(str); + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY, + this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(new Cursor(Cursor.HAND_CURSOR), this, this); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[]{dataflavor}; + } + + public boolean isDataFlavorSupported(DataFlavor dflavor) { + return dataflavor.equals(dflavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + Object retObj; + ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); + ObjectOutputStream ooStream = new ObjectOutputStream(baoStream); + ooStream.writeObject(this); + + ByteArrayInputStream baiStream = + new ByteArrayInputStream(baoStream.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(baiStream); + try { + retObj = ois.readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + return retObj; + } + + @Override + public void dragEnter(final DragSourceDragEvent dsde) { + + } + + @Override + public void dragOver(final DragSourceDragEvent dsde) { + + } + + @Override + public void dropActionChanged(final DragSourceDragEvent dsde) { + + } + + @Override + public void dragExit(final DragSourceEvent dse) { + + } + + @Override + public void dragDropEnd(final DragSourceDropEvent dsde) { + + } + + } + +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/event/ComponentEvent/TextAreaTextEventTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/event/ComponentEvent/TextAreaTextEventTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/event/ComponentEvent/TextAreaTextEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/event/ComponentEvent/TextAreaTextEventTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2007, 2022, 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.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +/* + * @test + * @key headful + * @bug 8296632 + * @summary Verify the content changes of a TextArea via TextListener. + * @run main TextAreaTextEventTest + */ +public class TextAreaTextEventTest { + + private static Frame frame; + private volatile static TextArea textArea; + private volatile static boolean textChanged = false; + private volatile static Point textAreaAt; + private volatile static Dimension textAreaSize; + private static Robot robot = null; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(TextAreaTextEventTest::initializeGUI); + + robot = new Robot(); + robot.setAutoDelay(100); + + robot.waitForIdle(); + EventQueue.invokeAndWait(() -> { + textAreaAt = textArea.getLocationOnScreen(); + textAreaSize = textArea.getSize(); + }); + robot.mouseMove(textAreaAt.x + textAreaSize.width / 2, + textAreaAt.y + textAreaSize.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + typeKey(KeyEvent.VK_T); + + robot.waitForIdle(); + if (!textChanged) { + throw new RuntimeException( + "FAIL: TextEvent not triggered when key 'T' typed on TextArea"); + } + + typeKey(KeyEvent.VK_E); + typeKey(KeyEvent.VK_S); + typeKey(KeyEvent.VK_T); + + textChanged = false; + typeKey(KeyEvent.VK_ENTER); + + robot.waitForIdle(); + if (!textChanged) { + throw new RuntimeException( + "FAIL: TextEvent not triggered when Enter pressed on TextArea"); + } + + textChanged = false; + robot.mouseMove(textAreaAt.x + 4, textAreaAt.y + 10); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (int i = 0; i < textAreaSize.width / 2; i++) { + robot.mouseMove(textAreaAt.x + 4 + i, textAreaAt.y + 10); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + if (textChanged) { + throw new RuntimeException( + "FAIL: TextEvent triggered when text is selected on TextArea!"); + } + + textChanged = false; + typeKey(KeyEvent.VK_F3); + + robot.waitForIdle(); + if (textChanged) { + throw new RuntimeException( + "FAIL: TextEvent triggered when special key F3 is pressed on TextArea!"); + } + System.out.println("Test passed!"); + } finally { + EventQueue.invokeAndWait(TextAreaTextEventTest::disposeFrame); + } + } + + private static void initializeGUI() { + frame = new Frame("Test Frame"); + frame.setLayout(new FlowLayout()); + textArea = new TextArea(5, 15); + textArea.addTextListener((event) -> { + System.out.println("Got a text event: " + event); + textChanged = true; + }); + frame.add(textArea); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void disposeFrame() { + if (frame != null) { + frame.dispose(); + } + } + + private static void typeKey(int key) throws Exception { + robot.keyPress(key); + robot.keyRelease(key); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/event/KeyEvent/KeyEventLocationTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/event/KeyEvent/KeyEventLocationTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/event/KeyEvent/KeyEventLocationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/event/KeyEvent/KeyEventLocationTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2002, 2022, 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 + * @key headful + * @bug 4424517 + * @summary Verify the mapping of various KeyEvents with their KeyLocations + * is as expected. + * @run main KeyEventLocationTest + */ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; + +import javax.swing.SwingUtilities; + +public class KeyEventLocationTest { + + private static volatile Frame frame; + private static volatile boolean keyPressed; + private static volatile boolean keyReleased; + private static volatile boolean keyTyped; + private static volatile Robot robot; + private static volatile int xLocation; + private static volatile int yLocation; + private static volatile int width; + private static volatile int height; + private static volatile Label label = new Label(); + private static volatile String currentString = ""; + + private static int[] keyEvents = { KeyEvent.VK_0, KeyEvent.VK_1, + KeyEvent.VK_2, KeyEvent.VK_3, KeyEvent.VK_4, KeyEvent.VK_5, + KeyEvent.VK_6, KeyEvent.VK_7, KeyEvent.VK_8, KeyEvent.VK_9, + KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, + KeyEvent.VK_E, KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, + KeyEvent.VK_I, KeyEvent.VK_J, KeyEvent.VK_K, KeyEvent.VK_L, + KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O, KeyEvent.VK_P, + KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T, + KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, + KeyEvent.VK_Y, KeyEvent.VK_Z, KeyEvent.VK_BACK_QUOTE, + KeyEvent.VK_BACK_SLASH, KeyEvent.VK_BACK_SPACE, + KeyEvent.VK_CLOSE_BRACKET, KeyEvent.VK_COMMA, KeyEvent.VK_EQUALS, + KeyEvent.VK_ESCAPE, KeyEvent.VK_MINUS, KeyEvent.VK_OPEN_BRACKET, + KeyEvent.VK_PERIOD, KeyEvent.VK_QUOTE, KeyEvent.VK_SEMICOLON, + KeyEvent.VK_SLASH, KeyEvent.VK_SPACE }; + + private static int specialKeyEvents[] = { KeyEvent.VK_F1, KeyEvent.VK_F2, + KeyEvent.VK_F3, KeyEvent.VK_F4, KeyEvent.VK_F5, KeyEvent.VK_F6, + KeyEvent.VK_F7, KeyEvent.VK_F8, KeyEvent.VK_F9, KeyEvent.VK_F10 }; + + private static void createGUI() { + frame = new Frame("Test frame"); + frame.setLayout(new BorderLayout()); + frame.setAlwaysOnTop(true); + + frame.addKeyListener(new KeyListener() { + public void keyPressed(KeyEvent event) { + try { + handleEvent("keyPressed", event); + } catch (Exception e) { + e.printStackTrace(); + } + keyPressed = true; + } + + public void keyReleased(KeyEvent event) { + try { + handleEvent("keyReleased", event); + } catch (Exception e) { + e.printStackTrace(); + } + keyReleased = true; + } + + public void keyTyped(KeyEvent event) { + try { + handleEvent("keyTyped", event); + } catch (Exception e) { + e.printStackTrace(); + } + keyTyped = true; + } + + private void handleEvent(String eventString, KeyEvent event) + throws Exception { + label.setText(eventString + " triggered for " + event); + if ((event.getID() == KeyEvent.KEY_TYPED + && event.getKeyLocation() != KeyEvent.KEY_LOCATION_UNKNOWN) + || ((event.getID() == KeyEvent.KEY_PRESSED + || event.getID() == KeyEvent.KEY_PRESSED) + && event.getKeyLocation() + != KeyEvent.KEY_LOCATION_STANDARD)) { + throw new Exception("FAIL: Incorrect KeyLocation: " + + event.getKeyLocation() + " returned when " + + eventString + " triggered for " + event.getKeyChar()); + } + } + }); + label.setText("Current Event: "); + frame.add(label, BorderLayout.SOUTH); + frame.setSize(600, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + } + + private static void doTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + SwingUtilities.invokeAndWait(() -> { + xLocation = frame.getLocationOnScreen().x; + yLocation = frame.getLocationOnScreen().y; + width = frame.getWidth(); + height = frame.getHeight(); + }); + + robot.mouseMove(xLocation + width / 2, yLocation + height / 2); + robot.mousePress(MouseEvent.BUTTON1_MASK); + robot.mouseRelease(MouseEvent.BUTTON1_MASK); + + for (int i = 0; i < keyEvents.length; i++) { + resetValues(); + robot.keyPress(keyEvents[i]); + robot.delay(200); + if (!keyPressed) { + throw new Exception( + "FAIL: keyPressed did not get triggered for " + + KeyEvent.getKeyText(keyEvents[i])); + } + robot.keyRelease(keyEvents[i]); + robot.delay(200); + if (!keyReleased) { + throw new Exception( + "FAIL: keyReleased did not get triggered for " + + KeyEvent.getKeyText(keyEvents[i])); + } + robot.delay(200); + if (!keyTyped) { + throw new Exception("FAIL: keyTyped did not get triggered for " + + KeyEvent.getKeyText(keyEvents[i])); + } + } + + for (int i = 0; i < specialKeyEvents.length; i++) { + resetValues(); + robot.keyPress(specialKeyEvents[i]); + robot.delay(200); + if (!keyPressed) { + throw new Exception("FAIL: keyPressed did not get triggered" + + " for " + KeyEvent.getKeyText(specialKeyEvents[i])); + } + robot.keyRelease(specialKeyEvents[i]); + robot.delay(200); + if (!keyReleased) { + throw new Exception("FAIL: keyReleased got triggered for " + + KeyEvent.getKeyText(specialKeyEvents[i])); + } + robot.delay(200); + if (keyTyped) { + throw new Exception("FAIL: keyTyped got triggered for " + + KeyEvent.getKeyText(specialKeyEvents[i])); + } + } + } + + private static void resetValues() { + keyPressed = false; + keyReleased = false; + keyTyped = false; + } + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createGUI()); + doTest(); + System.out.println("Test Passed"); + } finally { + if (frame != null) + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -27,15 +27,24 @@ * @bug 6385277 * @summary Tests that override redirect window gets activated on click. * @author anton.tarasov@sun.com: area=awt.focus - * @library ../../regtesthelpers - * @build Util * @run main SimpleWindowActivationTest */ -import java.awt.*; -import java.awt.event.*; -import java.util.concurrent.Callable; -import javax.swing.SwingUtilities; -import test.java.awt.regtesthelpers.Util; + +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.WindowEvent; public class SimpleWindowActivationTest { @@ -65,9 +74,11 @@ createAndShowWindow(); robot.waitForIdle(); + robot.delay(500); createAndShowFrame(); robot.waitForIdle(); + robot.delay(500); // click on Frame clickOn(getClickPoint(frame)); @@ -136,8 +147,8 @@ robot.mouseMove(point.x, point.y); robot.waitForIdle(); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); robot.waitForIdle(); } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics/LCDTextAndGraphicsState.java openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics/LCDTextAndGraphicsState.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics/LCDTextAndGraphicsState.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics/LCDTextAndGraphicsState.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, 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 @@ -21,28 +21,47 @@ * questions. */ -/** +/* * @test * @bug 6576507 * @summary Both lines of text should be readable - * @run main/manual=yesno LCDTextAndGraphicsState + * @run main/manual LCDTextAndGraphicsState */ -import java.awt.*; -import java.awt.geom.*; + +import java.awt.AlphaComposite; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.geom.RoundRectangle2D; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class LCDTextAndGraphicsState extends Component { - String text = "This test passes only if this text appears SIX TIMES"; + private static final Frame testFrame = new Frame("Composite and Text Test"); + private static final String text = "This test passes only if this text appears SIX TIMES else fail"; + private static volatile boolean testResult; + private static volatile CountDownLatch countDownLatch; public void paint(Graphics g) { - Graphics2D g2d = (Graphics2D)g.create(); g2d.setColor(Color.white); g2d.fillRect(0,0,getSize().width, getSize().height); - - test1(g.create(0, 0, 500, 200)); - test2(g.create(0, 200, 500, 200)); - test3(g.create(0, 400, 500, 200)); + test1(g.create(0, 0, 500, 100)); + test2(g.create(0, 100, 500, 100)); + test3(g.create(0, 200, 500, 100)); } public void test1(Graphics g) { @@ -50,10 +69,10 @@ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); g2d.setColor(Color.black); - g2d.drawString(text, 10, 50); + g2d.drawString(text, 10, 20); g2d.setComposite(AlphaComposite.getInstance( AlphaComposite.SRC_OVER, 0.9f)); - g2d.drawString(text, 10, 80); + g2d.drawString(text, 10, 50); } public void test2(Graphics g) { @@ -61,10 +80,10 @@ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); g2d.setColor(Color.black); - g2d.drawString(text, 10, 50); + g2d.drawString(text, 10, 20); g2d.setPaint(new GradientPaint( 0f, 0f, Color.BLACK, 100f, 100f, Color.GRAY)); - g2d.drawString(text, 10, 80); + g2d.drawString(text, 10, 50); } public void test3(Graphics g) { @@ -72,21 +91,64 @@ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); g2d.setColor(Color.black); - g2d.drawString(text, 10, 50); - Shape s = new RoundRectangle2D.Double(0, 60, 400, 50, 5, 5); + g2d.drawString(text, 10, 20); + Shape s = new RoundRectangle2D.Double(0, 30, 400, 50, 5, 5); g2d.clip(s); - g2d.drawString(text, 10, 80); + g2d.drawString(text, 10, 50); } public Dimension getPreferredSize() { - return new Dimension(500,600); + return new Dimension(500,300); } - public static void main(String[] args) throws Exception { - - Frame f = new Frame("Composite and Text Test"); - f.add(new LCDTextAndGraphicsState(), BorderLayout.CENTER); - f.pack(); - f.setVisible(true); + public static void disposeUI() { + countDownLatch.countDown(); + testFrame.dispose(); + } + + public static void createTestUI() { + testFrame.add(new LCDTextAndGraphicsState(), BorderLayout.NORTH); + Panel resultButtonPanel = new Panel(new GridLayout(1, 2)); + Button passButton = new Button("Pass"); + passButton.addActionListener((ActionEvent e) -> { + testResult = true; + disposeUI(); + }); + Button failButton = new Button("Fail"); + failButton.addActionListener(e -> { + testResult = false; + disposeUI(); + }); + resultButtonPanel.add(passButton); + resultButtonPanel.add(failButton); + + Panel controlUI = new Panel(new BorderLayout()); + TextArea instructions = new TextArea( + "Instructions:\n" + + "If you see the text six times above, press Pass.\n" + + "If not, press Fail.", + 3, + 50, + TextArea.SCROLLBARS_NONE + ); + instructions.setEditable(false); + controlUI.add(instructions, BorderLayout.CENTER); + controlUI.add(resultButtonPanel, BorderLayout.SOUTH); + + testFrame.add(controlUI, BorderLayout.SOUTH); + testFrame.pack(); + testFrame.setLocationRelativeTo(null); + testFrame.setVisible(true); + } + + public static void main(String[] args) throws InterruptedException { + countDownLatch = new CountDownLatch(1); + createTestUI(); + if (!countDownLatch.await(10, TimeUnit.MINUTES)) { + throw new RuntimeException("Timeout : No action was performed on the test UI."); + } + if (!testResult) { + throw new RuntimeException("Test failed!"); + } } } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics/TextAAHintsTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics/TextAAHintsTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics/TextAAHintsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics/TextAAHintsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, 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 @@ -21,21 +21,44 @@ * questions. */ -/** +/* * @test * @bug 6263951 * @summary Text should be B&W, grayscale, and LCD. - * @run main/manual=yesno TextAAHintsTest + * @requires (os.family != "mac") + * @run main/manual TextAAHintsTest */ -import java.awt.*; -import java.awt.geom.*; -import java.awt.image.*; + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.ImageCapabilities; +import java.awt.Panel; +import java.awt.RenderingHints; +import java.awt.TextArea; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class TextAAHintsTest extends Component { - String black = "This text should be solid black"; - String gray = "This text should be gray scale anti-aliased"; - String lcd = "This text should be LCD sub-pixel text (coloured)."; + private static final String black = "This text should be solid black"; + private static final String gray = "This text should be gray scale anti-aliased"; + private static final String lcd = "This text should be LCD sub-pixel text (coloured)."; + private static final CountDownLatch countDownLatch = new CountDownLatch(1); + private static volatile String failureReason; + private static volatile boolean testPassed = false; + private static Frame frame; public void paint(Graphics g) { @@ -64,27 +87,23 @@ g2d.drawString(black, 10, 20); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); - g2d.drawString(black, 10, 35); - - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); - g2d.drawString(gray, 10, 50); + g2d.drawString(gray, 10, 35); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - g2d.drawString(gray, 10, 65); + g2d.drawString(gray, 10, 50); /* For visual comparison, render grayscale with graphics AA off */ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - g2d.drawString(gray, 10, 80); + g2d.drawString(gray, 10, 65); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); - g2d.drawString(lcd, 10, 95); + g2d.drawString(lcd, 10, 80); } public void bufferedImageText(Graphics g) { @@ -139,11 +158,80 @@ return new Dimension(500,300); } - public static void main(String[] args) throws Exception { + public static void createTestUI() { + frame = new Frame("Composite and Text Test"); + TextAAHintsTest textAAHintsTestObject = new TextAAHintsTest(); + frame.add(textAAHintsTestObject, BorderLayout.NORTH); + + String instructions = """ + Note: Texts are rendered with different TEXT_ANTIALIASING & + VALUE_TEXT_ANTIALIAS. Text should be B&W, grayscale, and LCD. + Note: The results may be visually the same. + 1. Verify that first set of text are rendered correctly. + 2. Second set of text are created using BufferedImage of the first text. + 3. Third set of text are created using VolatileImage of the first text. + """; + TextArea instructionTextArea = new TextArea(instructions, 8, 50); + instructionTextArea.setEditable(false); + frame.add(instructionTextArea, BorderLayout.CENTER); + + Panel controlPanel = new Panel(); + Button passButton = new Button("Pass"); + passButton.addActionListener(e -> { + testPassed = true; + countDownLatch.countDown(); + frame.dispose(); + }); + Button failButton = new Button("Fail"); + failButton.addActionListener(e -> { + getFailureReason(); + testPassed = false; + countDownLatch.countDown(); + frame.dispose(); + }); + controlPanel.add(passButton); + controlPanel.add(failButton); + frame.add(controlPanel, BorderLayout.SOUTH); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void getFailureReason() { + // Show dialog to read why the testcase was failed and append the + // testcase failure reason to the output + final Dialog dialog = new Dialog(frame, "TestCase" + + " failure reason", true); + TextArea textArea = new TextArea("", 5, 60, TextArea.SCROLLBARS_BOTH); + dialog.add(textArea, BorderLayout.CENTER); + + Button okButton = new Button("OK"); + okButton.addActionListener(e1 -> { + failureReason = textArea.getText(); + dialog.dispose(); + }); + Panel ctlPanel = new Panel(); + ctlPanel.add(okButton); + dialog.add(ctlPanel, BorderLayout.SOUTH); + dialog.setLocationRelativeTo(null); + dialog.pack(); + dialog.setVisible(true); + } + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(TextAAHintsTest::createTestUI); + if (!countDownLatch.await(2, TimeUnit.MINUTES)) { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + throw new RuntimeException("Timeout : No action was taken on the test."); + } - Frame f = new Frame("Composite and Text Test"); - f.add(new TextAAHintsTest(), BorderLayout.CENTER); - f.pack(); - f.setVisible(true); + if (!testPassed) { + throw new RuntimeException("Test failed : Reason : " + failureReason); + } } } + diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Graphics2D/CopyAreaOOB.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021 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 @@ -36,15 +36,9 @@ public class CopyAreaOOB extends Canvas { - private static boolean done; + private static Robot robot = null; public void paint(Graphics g) { - synchronized (this) { - if (done) { - return; - } - } - int w = getWidth(); int h = getHeight(); @@ -64,10 +58,23 @@ Toolkit.getDefaultToolkit().sync(); - synchronized (this) { - done = true; - notifyAll(); + BufferedImage capture = null; + try { + Thread.sleep(500); + if (robot == null) robot = new Robot(); + Point pt1 = getLocationOnScreen(); + Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400); + capture = robot.createScreenCapture(rect); + } catch (Exception e) { + throw new RuntimeException("Problems handling Robot"); } + // Test pixels + testRegion(capture, "green", 0, 0, 400, 10, 0xff00ff00); + testRegion(capture, "original red", 0, 10, 50, 400, 0xffff0000); + testRegion(capture, "background", 50, 10, 60, 400, 0xff000000); + testRegion(capture, "in-between", 60, 10, 110, 20, 0xff000000); + testRegion(capture, "copied red", 60, 20, 110, 400, 0xffff0000); + testRegion(capture, "background", 110, 10, 400, 400, 0xff000000); } public Dimension getPreferredSize() { @@ -105,42 +112,11 @@ frame.setLocationRelativeTo(null); frame.setVisible(true); - // Wait until the component's been painted - synchronized (test) { - while (!done) { - try { - test.wait(); - } catch (InterruptedException e) { - throw new RuntimeException("Failed: Interrupted"); - } - } - } - try { - Thread.sleep(2000); + Thread.sleep(3000); } catch (InterruptedException ex) {} - - // Grab the screen region - BufferedImage capture = null; - try { - Robot robot = new Robot(); - Point pt1 = test.getLocationOnScreen(); - Rectangle rect = new Rectangle(pt1.x, pt1.y, 400, 400); - capture = robot.createScreenCapture(rect); - } catch (Exception e) { - throw new RuntimeException("Problems creating Robot"); - } finally { - if (!show) { - frame.dispose(); - } + if (!show) { + frame.dispose(); } - - // Test pixels - testRegion(capture, "green", 0, 0, 400, 10, 0xff00ff00); - testRegion(capture, "original red", 0, 10, 50, 400, 0xffff0000); - testRegion(capture, "background", 50, 10, 60, 400, 0xff000000); - testRegion(capture, "in-between", 60, 10, 110, 20, 0xff000000); - testRegion(capture, "copied red", 60, 20, 110, 400, 0xffff0000); - testRegion(capture, "background", 110, 10, 400, 400, 0xff000000); } } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/image/multiresolution/MultiresolutionIconTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -128,7 +128,7 @@ private boolean checkPressedColor(int x, int y, Color ok) { - r.mouseMove(x, y); + r.mouseMove(x+5, y+5); r.waitForIdle(); r.mousePress(InputEvent.BUTTON1_DOWN_MASK); r.waitForIdle(100); @@ -217,6 +217,10 @@ public static void main(String[] args) throws Exception { for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) { + // skip AquaL&F because Aqua icon darkening fails the test + if (LF.getName().equalsIgnoreCase("Mac OS X")) { + continue; + } System.out.println("\nL&F: " + LF.getName()); (new MultiresolutionIconTest(LF)).doTest(); } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Paint/PaintNativeOnUpdate.java openjdk-17-17.0.6+10/test/jdk/java/awt/Paint/PaintNativeOnUpdate.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Paint/PaintNativeOnUpdate.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Paint/PaintNativeOnUpdate.java 2023-01-10 13:21:55.000000000 +0000 @@ -36,7 +36,7 @@ * @library /lib/client * @build ExtendedRobot * @author Sergey Bylokhov - * @run main PaintNativeOnUpdate + * @run main/othervm -Dsun.java2d.uiScale=1 PaintNativeOnUpdate */ public final class PaintNativeOnUpdate extends Label { diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/print/Dialog/DialogCopies.java openjdk-17-17.0.6+10/test/jdk/java/awt/print/Dialog/DialogCopies.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/print/Dialog/DialogCopies.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/print/Dialog/DialogCopies.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, 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 @@ -21,40 +21,73 @@ * questions. */ -/** +/* * @test * @bug 6357858 * @summary Job must reports the number of copies set in the dialog. * @run main/manual DialogCopies */ -import java.awt.print.*; +import java.awt.Frame; +import java.awt.TextArea; +import java.awt.BorderLayout; +import java.awt.print.PrinterJob; public class DialogCopies { - static String[] instructions = { - "This test assumes and requires that you have a printer installed", - "When the dialog appears, increment the number of copies then press OK.", - "The test will throw an exception if you fail to do this, since", - "it cannot distinguish that from a failure", - "" - }; - - public static void main(String[] args) { - - for (int i=0;i 0) { - public static void main(String args[]) { + String instruction = """ + This is a manual test as it requires that you compare the + on-screen rendering with the printed output. + + Select the 'Print All' button to print out the test. It will + generate 4 sides of content: as it will print each of 2 sets + of transformed images in portrait, and landscape orientations. + + The sets of images are in turn made up of two similar sets of + pages: one is 'random' images, the other is 16 squares. Use the + 'Toggle Contents' button to view the screen rendering. For each + page compare the printed content to the same on-screen one + taking careful note of + a) the positions of the red/blue circles on the corners + b) that numerical text on the image is displayed similarly + e) that the green quadrilaterals match on-screen + f) that the rendering is clipped at the default (typically 1 inch) + margins of the page. + + The test PASSES if the onscreen and printed rendering match + """; + + PassFailJFrame passFailJFrame = new PassFailJFrame("Test " + + "Instruction", instruction, 15); + invokeAndWait(ClippedImages::createTestUI); + passFailJFrame.awaitAndCheck(); - ClippedImages f = new ClippedImages(); - f.setVisible(true); + } else { + System.out.println("Printer not configured or available." + + " Test cannot continue."); + PassFailJFrame.forcePass(); + } } - public ClippedImages() { - super("Clipped Src Area Image Printing Test"); + public static void createTestUI() { + Frame frame = new Frame("Clipped Src Area Image Printing Test"); c = new ClippedImageCanvas(); - add("Center", c); + frame.add(c, BorderLayout.CENTER); Button paintButton = new Button("Toggle Contents"); - paintButton.addActionListener(this); + paintButton.addActionListener((ae) -> { + c.toggleContents(); + c.repaint(); + }); Button printThisButton = new Button("Print This"); - printThisButton.addActionListener(this); + printThisButton.addActionListener((ae) -> printOne()); Button printAllButton = new Button("Print All"); - printAllButton.addActionListener(this); + printAllButton.addActionListener((ae) -> printAll()); Panel p = new Panel(); p.add(paintButton); p.add(printThisButton); p.add(printAllButton); - add("South", p); - add("North", getInstructions()); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - System.exit(0); - } - }); - - pack(); - } - - private TextArea getInstructions() { - TextArea ta = new TextArea(18, 60); - ta.setFont(new Font("Dialog", Font.PLAIN, 11)); - ta.setText - ("This is a manual test as it requires that you compare "+ - "the on-screen rendering with the printed output.\n"+ - "Select the 'Print All' button to print out the test\n"+ - "It will generate 4 sides of content: as it will print "+ - "each of 2 sets of transformed images in portrait, \n"+ - "and landscape orientations. \n"+ - "The sets of images are in turn made up\n"+ - "of two similar sets of pages: one is 'random' images,\n "+ - " the other is 16 squares.\n"+ - "Use the 'Toggle Contents' button to view the screen rendering\n"+ - "For each page compare the printed content to the same\n"+ - "on-screen one taking careful note of\n"+ - "a) the positions of the red/blue circles on the corners\n"+ - "b) that numerical text on the image is displayed similarly\n"+ - "e) that the green quadrilaterals match on-screen\n"+ - "f) that the rendering is clipped at the default (typically 1 inch) "+ - "margins of the page.\n"+ - "The test PASSES if the onscreen and printed rendering match"); - return ta; - } - - public void actionPerformed(ActionEvent e) { - - if (e.getActionCommand().equals("Print This")) { - printOne(); - } else if (e.getActionCommand().equals("Print All")) { - printAll(); - } else if (e.getActionCommand().equals("Toggle Contents")) { - c.toggleContents(); - c.repaint(); - } + frame.add(p, BorderLayout.SOUTH); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + + PassFailJFrame.addTestFrame(frame); + PassFailJFrame.positionTestFrame(frame, PassFailJFrame.Position.HORIZONTAL); } - private void printOne() { + private static void printOne() { PrinterJob pj = PrinterJob.getPrinterJob(); - PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet(); - if (pj != null && (false||pj.printDialog(attrs))) { - c.setPrinterJob(pj, false); - pj.setPrintable(c); + c.setPrinterJob(pj, false); + pj.setPrintable(c); + if (pj.printDialog(attrs)) { try { pj.print(attrs); } catch (PrinterException pe) { @@ -128,15 +143,18 @@ } finally { System.out.println("PRINT RETURNED OK."); } + } else { + throw new RuntimeException("Test failed : " + + "User selected 'Cancel' button on the print dialog"); } } - private void printAll() { + private static void printAll() { PrinterJob pj = PrinterJob.getPrinterJob(); PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet(); - if (pj != null && (false||pj.printDialog(attrs))) { - c.setPrinterJob(pj, true); - pj.setPageable(c); + c.setPrinterJob(pj, true); + pj.setPageable(c); + if (pj.printDialog(attrs)) { try { pj.print(attrs); } catch (PrinterException pe) { @@ -145,6 +163,9 @@ } finally { System.out.println("PRINT RETURNED OK."); } + } else { + throw new RuntimeException("Test failed : " + + "User selected 'Cancel' button on the print dialog"); } } } @@ -167,7 +188,7 @@ for (int y=12;y= getNumberOfPages()) { - throw new IndexOutOfBoundsException(); - } + throws IndexOutOfBoundsException { + Objects.checkIndex(pageIndex, getNumberOfPages()); PageFormat pf = myPrinterJob.defaultPage(); switch (pageIndex % 2) { - - case 0 : - pf.setOrientation(PageFormat.PORTRAIT); - break; - - case 1: - pf.setOrientation(PageFormat.LANDSCAPE); - break; + case 0 : + pf.setOrientation(PageFormat.PORTRAIT); + break; + + case 1: + pf.setOrientation(PageFormat.LANDSCAPE); + break; } return pf; } @@ -224,11 +241,9 @@ } public Printable getPrintable(int pageIndex) - throws IndexOutOfBoundsException { + throws IndexOutOfBoundsException { + Objects.checkIndex(pageIndex, getNumberOfPages()); - if (pageIndex < 0 || pageIndex >= getNumberOfPages()) { - throw new IndexOutOfBoundsException(); - } if (pageIndex < 2) { paintSquares = true; } else { @@ -286,7 +301,7 @@ for (int p=0;p dA + dD - the normal untransformed case */ + /* sA + sD -> dA + dD - the normal untransformed case */ drawImage(g, dxa, dya, dxd, dyd, sxa, sya, sxd, syd); g.translate(incX, 0); @@ -388,7 +403,6 @@ drawImage(g, dxa, dya, dxd, dyd, sxc, syc, sxb, syb); g.translate(-3*incX, incY); - /******/ /* sA + sD -> dD + dA */ drawImage(g, dxd, dyd, dxa, dya, sxa, sya, sxd, syd); @@ -406,7 +420,6 @@ drawImage(g, dxd, dyd, dxa, dya, sxc, syc, sxb, syb); g.translate(-3*incX, incY); - /******/ /* sA + sD -> dB + dC */ drawImage(g, dxb, dyb, dxc, dyc, sxa, sya, sxd, syd); @@ -424,7 +437,6 @@ drawImage(g, dxb, dyb, dxc, dyc, sxc, syc, sxb, syb); g.translate(-3*incX, incY); - /******/ /* sA + sD -> dC + dB */ @@ -445,11 +457,11 @@ - /* Size is chosen to match default imageable width of a NA letter - * page. This means there will be clipping, what is clipped will - * depend on PageFormat orientation. - */ - public Dimension getPreferredSize() { + /* Size is chosen to match default imageable width of a NA letter + * page. This means there will be clipping, what is clipped will + * depend on PageFormat orientation. + */ + public Dimension getPreferredSize() { return new Dimension(468, 468); } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2021, 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 @@ -21,85 +21,133 @@ * questions. */ -/** - * +/* * @test * @bug 4521945 7006865 * @summary Test printing images of different types. * @author prr - * @run main/manual=yesno/timeout=900 ImageTypes + * @run main/manual ImageTypes */ -import java.io.*; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.IndexColorModel; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; + import static java.awt.Color.*; -import java.awt.*; -import java.awt.geom.*; -import java.awt.event.*; -import java.awt.print.*; -import java.awt.image.*; import static java.awt.image.BufferedImage.*; -import javax.print.*; -import javax.print.attribute.*; -import javax.print.attribute.standard.*; - -public class ImageTypes extends Frame implements ActionListener { - private ImageCanvas c; +public class ImageTypes { - public static void main(String args[]) { - - ImageTypes f = new ImageTypes(); - f.show(); + private static Frame testFrame; + private static ImageCanvas imageCanvas; + private static volatile boolean testResult; + private static final CountDownLatch countDownLatch = new CountDownLatch(1); + + public static void main(String[] args) throws InterruptedException { + createTestUI(); + if (!countDownLatch.await(10, TimeUnit.MINUTES)) { + throw new RuntimeException("Timeout : No action was performed on the test UI."); + } + if (!testResult) { + throw new RuntimeException("Test failed!"); + } } - public ImageTypes () { - super("Image Types Printing Test"); - c = new ImageCanvas(); - add("Center", c); - - Button printThisButton = new Button("Print"); - printThisButton.addActionListener(this); - Panel p = new Panel(); - p.add(printThisButton); - add("South", p); - add("North", getInstructions()); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - System.exit(0); + public static void createTestUI() { + testFrame = new Frame("Image Types Printing Test"); + imageCanvas = new ImageCanvas(); + testFrame.add("Center", imageCanvas); + + Button printButton = new Button("Print"); + printButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PrinterJob pj = PrinterJob.getPrinterJob(); + if (pj.getPrintService() == null) { + System.out.println("No printers. Test cannot continue. Install " + + "printer and restart the test."); + return; } - }); + PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet(); + if (pj != null && pj.printDialog(attrs)) { + pj.setPrintable(imageCanvas); + try { + pj.print(attrs); + } catch (PrinterException pe) { + pe.printStackTrace(); + throw new RuntimeException("Exception whilst printing."); + } finally { + System.out.println("PRINT RETURNED OK."); + } + } + } + }); + + Button passButton = new Button("Pass"); + passButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + testResult = true; + countDownLatch.countDown(); + testFrame.dispose(); + } + }); - pack(); + Button failButton = new Button("Fail"); + failButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + testResult = false; + countDownLatch.countDown(); + testFrame.dispose(); + } + }); + + Panel buttonPanel = new Panel(new GridLayout(1,3)); + buttonPanel.add(printButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + testFrame.add("South", buttonPanel); + testFrame.add("North", getInstructions()); + testFrame.pack(); + testFrame.setVisible(true); } - private TextArea getInstructions() { - TextArea ta = new TextArea(10, 60); + private static TextArea getInstructions() { + String testInstruction = "This is a manual test as it requires that you compare "+ + "the on-screen rendering with the printed output.\n"+ + "Select the 'Print' button to print out the test.\n"+ + "For each image compare the printed one to the on-screen one.\n"+ + "Press Pass button if the onscreen and printed rendering " + + "match else Press fail button"; + TextArea ta = new TextArea(testInstruction,7, 60, + TextArea.SCROLLBARS_NONE); ta.setFont(new Font("Dialog", Font.PLAIN, 11)); - ta.setText - ("This is a manual test as it requires that you compare "+ - "the on-screen rendering with the printed output.\n"+ - "Select the 'Print' button to print out the test.\n"+ - "For each image compare the printed one to the on-screen one.\n"+ - "The test PASSES if the onscreen and printed rendering match."); return ta; } - - public void actionPerformed(ActionEvent e) { - PrinterJob pj = PrinterJob.getPrinterJob(); - - PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet(); - if (pj != null && pj.printDialog(attrs)) { - pj.setPrintable(c); - try { - pj.print(attrs); - } catch (PrinterException pe) { - pe.printStackTrace(); - throw new RuntimeException("Exception whilst printing."); - } finally { - System.out.println("PRINT RETURNED OK."); - } - } - } } class ImageCanvas extends Component implements Printable { @@ -111,7 +159,6 @@ int sw=99, sh=99; void paintImage(BufferedImage bi, Color c1, Color c2) { - GradientPaint tp= new GradientPaint(0.0f, 0.0f, c1, 10f, 8f, c2, true); Graphics2D g2d = (Graphics2D)bi.getGraphics(); g2d.setPaint(tp); @@ -132,7 +179,6 @@ } ImageCanvas() { - opaqueImg = new BufferedImage(sw, sh, TYPE_INT_RGB); Color o1 = new Color(0, 0, 0); Color o2 = new Color(255, 255, 255); @@ -171,9 +217,7 @@ } - public int print(Graphics g, PageFormat pgFmt, int pgIndex) { - if (pgIndex > 0) { return Printable.NO_SUCH_PAGE; } @@ -184,7 +228,6 @@ } private void drawImage(Graphics g, int biType, IndexColorModel icm) { - BufferedImage bi; if (icm != null) { bi = new BufferedImage(sw, sh, biType, icm); @@ -202,7 +245,6 @@ } public void paint(Graphics g) { - int incX = sw+10, incY = sh+10; g.translate(10, 10); @@ -259,14 +301,11 @@ g.translate(incX, 0); } - - - /* Size is chosen to match default imageable width of a NA letter - * page. This means there will be clipping, what is clipped will - * depend on PageFormat orientation. - */ - public Dimension getPreferredSize() { + /* Size is chosen to match default imageable width of a NA letter + * page. This means there will be clipping, what is clipped will + * depend on PageFormat orientation. + */ + public Dimension getPreferredSize() { return new Dimension(468, 600); } - } diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2021, 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 @@ -21,157 +21,111 @@ * questions. */ -/* @test +/* + @test @bug 6302514 - @run main/manual=yesno PageDialogTest + @run main/manual PageDialogTest @summary A toolkit modal dialog should not be blocked by Page/Print dialog. */ -import java.awt.*; -import java.awt.event.*; -import java.awt.print.*; -import javax.swing.*; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextArea; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class PageDialogTest { - public static void main(String[] args) { - String[] instructions = - { - "The test shows a Toolkit modal dialog. ", - "Click the 'Open' button. It opens a page dialog.", - "The test fails if the page dialog blocks the toolkit", - "modal dialog, otherwise it passes." - }; - - Sysout.createDialog( ); - Sysout.printInstructions( instructions ); - - Dialog td = new Dialog((Frame) null, "Toolkit modal dialog", - Dialog.ModalityType.TOOLKIT_MODAL); - td.setLayout(new FlowLayout()); - td.add(new Button("Dummy")); - Button tdb = new Button("Open"); - tdb.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent event) { - PrinterJob.getPrinterJob().pageDialog(new PageFormat()); - } + public static Frame frame; + public static Dialog dialog; + public static volatile boolean testResult; + public static final CountDownLatch countDownLatch = new CountDownLatch(1); + + public static void createUI() { + frame = new Frame("Test 6302514"); + String instructions = + "1. Click on the 'Show Dialog' button to show a 'Toolkit Modal Dialog' \n" + + "2. Click on the 'Open PageDialog' button to show 'Page Dialog'.\n" + + "3. The test fails if the page dialog blocks the toolkit\n"+ + " else test pass.\n" + + "4. Close Page dialog and 'Toolkit modal dialog'\n" + + "5. Click appropriate button to mark the test case pass or fail.\n" ; + + TextArea instructionsTextArea = new TextArea( instructions, 8, + 50, TextArea.SCROLLBARS_NONE ); + instructionsTextArea.setEditable(false); + frame.add(BorderLayout.NORTH, instructionsTextArea); + + Panel buttonPanel = new Panel(new FlowLayout()); + Button passButton = new Button("pass"); + passButton.setActionCommand("pass"); + passButton.addActionListener(e -> { + testResult = true; + countDownLatch.countDown(); + dialog.dispose(); + frame.dispose(); }); - td.add(tdb); - td.setSize(250, 150); - td.setVisible(true); - } -} - -class Sysout { - private static TestDialog dialog; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.show(); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.show(); - println( "Any messages for the tester will display here." ); - } + Button failButton = new Button("fail"); + failButton.addActionListener(e->{ + testResult = false; + countDownLatch.countDown(); + dialog.dispose(); + frame.dispose(); + }); - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } + Button showDialog = new Button("Show Dialog"); + showDialog.addActionListener(e->{ + createToolkitModalDialog(); + }); + buttonPanel.add(showDialog); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + frame.add(BorderLayout.SOUTH, buttonPanel); + frame.pack(); + frame.setVisible(true); + } + + public static void createToolkitModalDialog() { + dialog = new Dialog((Frame) null, "Toolkit modal dialog", + Dialog.ModalityType.TOOLKIT_MODAL); + dialog.setLayout(new FlowLayout()); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + super.windowClosing(e); + dialog.dispose(); + } + }); - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); + Button openPageDialogButton = new Button("Open PageDialog"); + openPageDialogButton.addActionListener(e->{ + PrinterJob.getPrinterJob().pageDialog(new PageFormat()); + }); + dialog.add(openPageDialogButton); + dialog.setSize(250, 150); + dialog.setLocationRelativeTo(null); + dialog.setVisible(true); } -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog { - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("Center", messageText); - - pack(); - - show(); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); + public static void main(String []args) throws InterruptedException { + createUI(); + if ( !countDownLatch.await(5, TimeUnit.MINUTES)) { + throw new RuntimeException("Timeout : user did not perform any " + + "action on the UI."); + } + if ( !testResult) { + throw new RuntimeException("Test failed"); + } } +} - }// TestDialog class diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/PageRangesDlgTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/PageRangesDlgTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/print/PrinterJob/PageRangesDlgTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/print/PrinterJob/PageRangesDlgTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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 @@ -21,56 +21,72 @@ * questions. */ -/** +import java.awt.Graphics; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.DialogTypeSelection; +import javax.print.attribute.standard.PageRanges; +import jtreg.SkippedException; + +/* * @test * @bug 8061267 + * @key printer + * @library /java/awt/regtesthelpers + * @library /test/lib + * @build PassFailJFrame + * @build jtreg.SkippedException * @summary The specified page range should be displayed in the dialog - * @run main/manual=yesno PageRangesDlgTest + * @run main/manual PageRangesDlgTest */ -import javax.print.*; -import javax.print.attribute.*; -import javax.print.attribute.standard.*; -import java.awt.*; -import java.awt.print.*; - public class PageRangesDlgTest implements Printable { - static String[] instr = { - "This test is to check that the print dialog displays the specified", - "page ranges. You must have a printer installed for this test.", - "It is valid only on dialogs which support page ranges", - "In each dialog, check that a page range of 2 to 3 is requested", - "Optionally press Print instead of Cancel, and verify that the", - "correct number/set of pages is printed", - }; - - public static void main(String args[]) throws Exception { - for (int i=0;i wheelRotation = e.getWheelRotation()); + button.addMouseWheelListener(e -> wheelRotation.addAndGet(e.getWheelRotation())); frame.add(button); + frame.setLocationRelativeTo(null); frame.setVisible(true); - Robot robot = new Robot(); robot.setAutoDelay(100); robot.waitForIdle(); @@ -69,12 +95,13 @@ if (i == 0) { continue; } + + wheelRotation.set(0); + robot.mouseWheel(i); robot.waitForIdle(); - if (i != wheelSign * wheelRotation) { - throw new RuntimeException("wheelRotation = " + wheelRotation - + ", expected value = " + i); - } + + waitTillSuccess(i); } } finally { if (frame != null) { diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2022, 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 @@ -51,7 +51,6 @@ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gds = ge.getScreenDevices(); for (GraphicsDevice gd : gds) { - GraphicsConfiguration gc = gd.getDefaultConfiguration(); Rectangle gcBounds = gc.getBounds(); Insets gcInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc); @@ -100,7 +99,13 @@ gcBounds.y + gcBounds.height - fBounds.y - fBounds.height, gcBounds.x + gcBounds.width - fBounds.x - fBounds.width); - if (!expected.equals(gcInsets)) + // On Windows 10 and up system allows undecorated maximized windows + // to be placed over the taskbar so calculated insets might + // be smaller than reported ones depending on the taskbar position + if (gcInsets.top < expected.top + || gcInsets.bottom < expected.bottom + || gcInsets.left < expected.left + || gcInsets.right < expected.right) { passed = false; System.err.println("Wrong insets for GraphicsConfig: " + gc); diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2022, 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 8255439 + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary To test tray icon scaling with on-the-fly DPI/Scale changes on Windows + * @run main/manual TrayIconScalingTest + * @requires (os.family == "windows") + */ + +import java.awt.AWTException; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.font.TextLayout; +import java.awt.image.BaseMultiResolutionImage; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +public class TrayIconScalingTest { + + private static SystemTray tray; + private static TrayIcon icon; + + private static final String INSTRUCTIONS = + "This test checks if the tray icon gets updated when DPI / Scale" + + " is changed on the fly.\n\n" + + "STEPS: \n\n" + + "1. Check the system tray / notification area on Windows" + + " taskbar, you should see a white icon which displays a" + + " number.\n\n" + + "2. Navigate to Settings > System > Display and change the" + + " display scale by selecting any value from" + + " Scale & Layout dropdown.\n\n"+ + "3. When the scale changes, check the white tray icon," + + " there should be no distortion, it should be displayed sharp,\n" + + " and the displayed number should correspond to the current"+ + " scale:\n" + + " 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n"+ + " If the icon is displayed sharp and without any distortion," + + " press PASS, otherwise press FAIL.\n"; + + private static final Font font = new Font("Dialog", Font.BOLD, 12); + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException { + // check if SystemTray supported on the machine + if (!SystemTray.isSupported()) { + System.out.println("SystemTray is not supported"); + return; + } + PassFailJFrame passFailJFrame = new PassFailJFrame("TrayIcon " + + "Test Instructions", INSTRUCTIONS, 8, 18, 85); + createAndShowGUI(); + try { + passFailJFrame.awaitAndCheck(); + } finally { + tray.remove(icon); + } + } + + private static void createAndShowGUI() { + ArrayList imageList = new ArrayList<>(); + for (int size = 16; size <= 48; size += 4) { + imageList.add(createIcon(size)); + } + Image mRImage = + new BaseMultiResolutionImage(imageList.toArray(new Image[0])); + + tray = SystemTray.getSystemTray(); + icon = new TrayIcon(mRImage); + + try { + tray.add(icon); + } catch (AWTException e) { + throw new RuntimeException("Error while adding icon to system tray"); + } + } + + private static Image createIcon(int size) { + BufferedImage image = new BufferedImage(size, size, + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + g.setColor(Color.WHITE); + g.fillRect(0, 0, size, size); + g.setFont(font); + g.setColor(Color.BLACK); + + TextLayout layout = new TextLayout(String.valueOf(size), + g.getFont(), g.getFontRenderContext()); + int height = (int) layout.getBounds().getHeight(); + int width = (int) layout.getBounds().getWidth(); + layout.draw(g, (size - width) / 2f - 1, (size + height) / 2f); + g.dispose(); + return image; + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java openjdk-17-17.0.6+10/test/jdk/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java 2023-01-10 13:21:55.000000000 +0000 @@ -37,7 +37,7 @@ * @author Sergey Bylokhov * @library /lib/client * @build ExtendedRobot - * @run main BackgroundIsNotUpdated + * @run main/othervm -Dsun.java2d.uiScale=1 BackgroundIsNotUpdated */ public final class BackgroundIsNotUpdated extends Window { diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, 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 @@ -21,142 +21,236 @@ * questions. */ -/** +/* * @test * @key headful - * @summary setAlwaysOnTop doesn't behave correctly in Linux/Solaris under - * certain scenarios * @bug 8021961 - * @author Semyon Sadetsky - * @run main ChildAlwaysOnTopTest + * @summary To test setAlwaysOnTop functionality. + * @run main/othervm -Dsun.java2d.uiScale=1 ChildAlwaysOnTopTest */ -import javax.swing.*; -import java.awt.*; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; + +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; public class ChildAlwaysOnTopTest { private static Window win1; private static Window win2; private static Point point; + private static Robot robot; + private static int caseNo = 0; + private static StringBuffer errorLog = new StringBuffer(); + private static String[] errorMsg= new String[] { + " Scenario 1 Failed: alwaysOnTop window is sent back by another" + + " child window with setVisible().", + " Scenario 2 Failed: alwaysOnTop window is" + + " sent back by another child window with toFront().", + " Scenario 3 Failed: Failed to unset alwaysOnTop ", + }; public static void main(String[] args) throws Exception { - if( Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() ) { + if (!Toolkit.getDefaultToolkit().isAlwaysOnTopSupported()) { + System.out.println("alwaysOnTop not supported by: "+ + Toolkit.getDefaultToolkit().getClass().getName()); + return; + } - test(null); + // CASE 1 - JDialog without parent/owner + System.out.println("Testing CASE 1: JDialog without parent/owner"); + caseNo = 1; + test(null); + System.out.println("CASE 1 Completed"); + System.out.println(); + + // CASE 2 - JDialog with JFrame as owner + System.out.println("Testing CASE 2: JDialog with JFrame as owner"); + caseNo = 2; + Window f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + try { + test(f); + } finally { + f.dispose(); + } + System.out.println("CASE 2 Completed"); + System.out.println(); - Window f = new Frame(); - f.setBackground(Color.darkGray); - f.setSize(500, 500); - try { - test(f); - } finally { - f.dispose(); - } + // CASE 3 - JDialog within another JDialog as owner + System.out.println("Testing CASE 3:Dialog within another"+ + " JDialog as owner"); + caseNo = 3; + f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + f.setVisible(true); + f = new Dialog((Frame)f); + try { + test(f); + } finally { + ((Frame)f.getParent()).dispose(); + } + System.out.println("CASE 3 Completed"); + System.out.println(); - f = new Frame(); - f.setBackground(Color.darkGray); - f.setSize(500, 500); - f.setVisible(true); - f = new Dialog((Frame)f); - try { - test(f); - } finally { - ((Frame)f.getParent()).dispose(); - } + if (errorLog.isEmpty()) { + System.out.println("All three cases passed !!"); + } + else { + throw new RuntimeException("Following cases and scenarios failed."+ + " Please check the saved screenshots.\n"+ errorLog); } - System.out.println("ok"); } public static void test(Window parent) throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - win1 = parent == null ? new JDialog() : new JDialog(parent); - win1.setName("top"); - win2 = parent == null ? new JDialog() : new JDialog(parent); - win2.setName("behind"); - win1.setSize(200, 200); - Panel panel = new Panel(); - panel.setBackground(Color.GREEN); - win1.add(panel); - panel = new Panel(); - panel.setBackground(Color.RED); - win2.add(panel); - win1.setAlwaysOnTop(true); - win2.setAlwaysOnTop(false); - win1.setVisible(true); - } - }); + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1 = parent == null ? new JDialog() : new JDialog(parent); + win1.setName("Top"); + + win2 = parent == null ? new JDialog() : new JDialog(parent); + win2.setName("Behind"); + + JLabel label = new JLabel("TOP WINDOW"); + // top window - green and smaller + win1.setSize(200, 200); + Panel panel = new Panel(); + panel.setBackground(Color.GREEN); + panel.add(label); + win1.add(panel); + win1.setAlwaysOnTop(true); + + // behind window - red and bigger + label = new JLabel("BEHIND WINDOW"); + win2.setSize(300, 300); + panel = new Panel(); + panel.setBackground(Color.RED); + panel.add(label); + win2.add(panel); - Robot robot = new Robot(); - robot.delay(500); - robot.waitForIdle(); + win1.setVisible(true); + win2.setVisible(true); + } + }); - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { + robot = new Robot(); + robot.setAutoDelay(300); + robot.waitForIdle(); + + // Scenario 1: Trying to unset the alwaysOnTop (green window) + // by setting the setVisible to true for behind (red) window + System.out.println(" >> Testing Scenario 1 ..."); + SwingUtilities.invokeAndWait(()-> { point = win1.getLocationOnScreen(); - win2.setBounds(win1.getBounds()); win2.setVisible(true); - } - }); + }); - robot.delay(500); - robot.waitForIdle(); + checkTopWindow(caseNo, 1, Color.GREEN); - Color color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.GREEN)) { - win1.dispose(); - win2.dispose(); - throw new RuntimeException("alawaysOnTop window is sent back by " + - "another child window setVisible(). " + color); - } + /*---------------------------------------------------------------*/ - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { + // Scenario 2: Trying to unset the alwaysOnTop (green window) + // by setting toFront() to true for behind (red) window + System.out.println(" >> Testing Scenario 2 ..."); + SwingUtilities.invokeAndWait(()-> { win2.toFront(); if (parent != null) { parent.setLocation(win1.getLocation()); parent.toFront(); } - } - }); + }); - robot.delay(500); - robot.waitForIdle(); + checkTopWindow(caseNo, 2, Color.GREEN); - color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.GREEN)) { - win1.dispose(); - win2.dispose(); - throw new RuntimeException("alawaysOnTop window is sent back by " + - "another child window toFront(). " + color); - } + /*----------------------------------------------------------------*/ - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - win1.setAlwaysOnTop(false); - if (parent != null) { - parent.setVisible(false); - parent.setVisible(true); + // Scenario 3: Trying to unset the alwaysOnTop (green window) + // by setting alwaysOnTop to false. The unsetting should work + // in this case and bring the red window to the top. + System.out.println(" >> Testing Scenario 3 ..."); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1.setAlwaysOnTop(false); + if (parent != null) { + parent.setVisible(false); + parent.setVisible(true); + } } - win2.toFront(); + }); + + robot.delay(300); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win2.toFront(); + } + }); + + checkTopWindow(caseNo, 3, Color.RED); + + } finally { + if (win1 != null) { + SwingUtilities.invokeAndWait(()-> win1.dispose()); + } + if (win2 != null) { + SwingUtilities.invokeAndWait(()-> win2.dispose()); } - }); + } + } + // to check if the current top window background color + // matches the expected color + private static void checkTopWindow(int caseNo, int scenarioNo, + Color expectedColor) { robot.delay(500); robot.waitForIdle(); + Color actualColor = robot.getPixelColor(point.x + 100, point.y + 100); - color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.RED)) { - throw new RuntimeException("Failed to unset alawaysOnTop " + color); + saveScreenCapture(caseNo , scenarioNo); + + if (!actualColor.equals(expectedColor)) { + System.out.println(" >> Scenario "+ scenarioNo +" FAILED !!"); + errorLog.append("Case "+ caseNo + errorMsg[scenarioNo - 1] + +" Expected Color: "+ expectedColor +" vs Actual Color: " + + actualColor +"\n"); + } + else { + System.out.println(" >> Scenario "+ scenarioNo +" Passed"); } + } - win1.dispose(); - win2.dispose(); + // For Debugging purpose - method used to save the screen capture as + // BufferedImage in the event the test fails + private static void saveScreenCapture(int caseNo, int scenarioNo) { + String filename = "img_"+ caseNo +"_"+ scenarioNo; + BufferedImage image = robot.createScreenCapture( + new Rectangle(0, 0, 500, 500)); + try { + ImageIO.write(image, "png", new File(filename)); + } catch (IOException e) { + e.printStackTrace(); + } } -} +} \ No newline at end of file diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/Common.java openjdk-17-17.0.6+10/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/Common.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/Common.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Window/ShapedAndTranslucentWindows/Common.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -47,7 +47,7 @@ static final int STATIC_BLOCKS = 30; static final Color BG_COLOR = Color.BLUE; static final Color FG_COLOR = Color.RED; - static final int delay = 55000; + static final int delay = 1000; static final SecureRandom random = new SecureRandom(); static final int dl = 100; static final Class[] WINDOWS_TO_TEST = { Window.class, Frame.class, Dialog.class }; diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -27,7 +27,7 @@ * @bug 6683728 * @summary Tests that a JApplet in a translucent JFrame works properly * @compile -XDignore.symbol.file=true TranslucentJAppletTest.java - * @run main TranslucentJAppletTest + * @run main/othervm -Dsun.java2d.uiScale=1 TranslucentJAppletTest */ import java.awt.*; diff -Nru openjdk-17-17.0.5+8/test/jdk/java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java openjdk-17-17.0.6+10/test/jdk/java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java --- openjdk-17-17.0.5+8/test/jdk/java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -26,7 +26,7 @@ * @bug 8130655 * @summary Tests that window owned by EmbeddedFrame can receive keyboard input * @requires (os.family == "mac") - * @modules java.desktop/sun.awt + * @modules java.desktop/sun.awt java.desktop/sun.lwawt.macosx:open * @library ../../regtesthelpers * @build Util * @run main WindowOwnedByEmbeddedFrameTest diff -Nru openjdk-17-17.0.5+8/test/jdk/java/io/File/GetXSpace.java openjdk-17-17.0.6+10/test/jdk/java/io/File/GetXSpace.java --- openjdk-17-17.0.5+8/test/jdk/java/io/File/GetXSpace.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/io/File/GetXSpace.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2022, 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 @@ -34,7 +34,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FilePermission; import java.io.InputStreamReader; import java.io.IOException; import java.nio.file.Files; @@ -108,8 +107,8 @@ Space(String total, String free, String name) { try { - this.total = Long.valueOf(total) * KSIZE; - this.free = Long.valueOf(free) * KSIZE; + this.total = Long.parseLong(total) * KSIZE; + this.free = Long.parseLong(free) * KSIZE; } catch (NumberFormatException x) { throw new RuntimeException("the regex should have caught this", x); } @@ -157,7 +156,7 @@ } al.add(new Space(m.group(2), m.group(3), name));; } - j = m.end() + 1; + j = m.end(); } else { throw new RuntimeException("unrecognized df output format: " + "charAt(" + j + ") = '" @@ -227,7 +226,7 @@ // On Linux, ignore the NSFE if the path is one of the // /run/user/$UID mounts created by pam_systemd(8) as it // might be deleted during the test - if (!Platform.isLinux() || s.name().indexOf("/run/user") == -1) + if (!Platform.isLinux() || !s.name().contains("/run/user")) throw new RuntimeException(nsfe); } catch (IOException e) { throw new RuntimeException(e); diff -Nru openjdk-17-17.0.5+8/test/jdk/java/lang/reflect/PublicMethods/PublicMethodsTest.java openjdk-17-17.0.6+10/test/jdk/java/lang/reflect/PublicMethods/PublicMethodsTest.java --- openjdk-17-17.0.5+8/test/jdk/java/lang/reflect/PublicMethods/PublicMethodsTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/lang/reflect/PublicMethods/PublicMethodsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -60,7 +60,7 @@ * @modules jdk.compiler * jdk.zipfs * @summary Nearly exhaustive test of Class.getMethod() and Class.getMethods() - * @run main PublicMethodsTest + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies PublicMethodsTest */ public class PublicMethodsTest { diff -Nru openjdk-17-17.0.5+8/test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java openjdk-17-17.0.6+10/test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java --- openjdk-17-17.0.5+8/test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2022, 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 8297530 + * @summary This sanity tests that OOME is correctly thrown when + * the length of the array to be allocated for a concatenation. + * Before the fix for 8297530 an IllegalArgumentException could + * erroneously be thrown when the length of the string is between + * Integer.MAX_VALUE / 2 and Integer.MAX_VALUE and the String coder + * is UTF16. + * + * @requires sun.arch.data.model == "64" + * @run main/othervm -Xverify:all -Xmx4g ImplicitStringConcatOOME + * @run main/othervm -Xverify:all -Xmx4g -XX:-CompactStrings ImplicitStringConcatOOME + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class ImplicitStringConcatOOME { + + static String s000, s001, s002, s003, s004, s005, s006, s007, s008, s009; + static String s010, s011, s012, s013, s014, s015, s016, s017, s018, s019; + static String s020, s021, s022, s023, s024, s025, s026, s027, s028, s029; + static String s030, s031, s032, s033, s034, s035, s036, s037, s038, s039; + static String s040, s041, s042, s043, s044, s045, s046, s047, s048, s049; + static String s050, s051, s052, s053, s054, s055, s056, s057, s058, s059; + static String s060, s061, s062, s063, s064, s065, s066, s067, s068, s069; + static String s070, s071, s072, s073, s074, s075, s076, s077, s078, s079; + static String s080, s081, s082, s083, s084, s085, s086, s087, s088, s089; + static String s090, s091, s092, s093, s094, s095, s096, s097, s098, s099; + + static String s100, s101, s102, s103, s104, s105, s106, s107, s108, s109; + static String s110, s111, s112, s113, s114, s115, s116, s117, s118, s119; + static String s120, s121, s122, s123, s124, s125, s126, s127, s128, s129; + static String s130, s131, s132, s133, s134, s135, s136, s137, s138, s139; + static String s140, s141, s142, s143, s144, s145, s146, s147, s148, s149; + static String s150, s151, s152, s153, s154, s155, s156, s157, s158, s159; + static String s160, s161, s162, s163, s164, s165, s166, s167, s168, s169; + static String s170, s171, s172, s173, s174, s175, s176, s177, s178, s179; + static String s180, s181, s182, s183, s184, s185, s186, s187, s188, s189; + static String s190, s191, s192, s193, s194, s195, s196, s197, s198, s199; + + static String s_utf16; + static { + String s = "10 letters".repeat(1_073_742); + for (Field f : ImplicitStringConcatOOME.class.getDeclaredFields()) { + if (Modifier.isStatic(f.getModifiers())) { + try { + f.set(null, s); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + } + s_utf16 = "\u0257"; + } + + public static void main(String[] args) throws Exception { + try { + String res = + s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 + + s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 + + s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 + + s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 + + s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 + + s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 + + s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 + + s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 + + s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 + + s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 + + + s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 + + s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 + + s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 + + s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 + + s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 + + s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 + + s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 + + s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 + + s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 + + s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199; + throw new IllegalStateException("Expected OOME"); + } catch (OutOfMemoryError e) { + // Expected + } + try { + // Compact Strings meant capacity for UTF16 strings were cut in + // half, regardless of -XX:+CompactStrings setting + String res = + s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 + + s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 + + s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 + + s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 + + s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 + + s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 + + s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 + + s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 + + s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 + + s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 + + s_utf16; + throw new IllegalStateException("Expected OOME"); + } catch (OutOfMemoryError e) { + // Expected + } + } + + public static void test(String expected, String actual) { + // Fingers crossed: String concat should work. + if (!expected.equals(actual)) { + throw new IllegalStateException("Expected = " + expected + ", actual = " + actual); + } + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/java/net/httpclient/http2/TLSConnection.java openjdk-17-17.0.6+10/test/jdk/java/net/httpclient/http2/TLSConnection.java --- openjdk-17-17.0.5+8/test/jdk/java/net/httpclient/http2/TLSConnection.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/net/httpclient/http2/TLSConnection.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, 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 @@ -166,12 +166,13 @@ System.out.println(new String(body)); } + sslSession = t.getSSLSession(); + try (OutputStream os = t.getResponseBody()) { t.sendResponseHeaders(200, BODY.length); os.write(BODY); } - sslSession = t.getSSLSession(); } SSLSession getSSLSession() { diff -Nru openjdk-17-17.0.5+8/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java openjdk-17-17.0.6+10/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java --- openjdk-17-17.0.5+8/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, 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 @@ -45,9 +45,12 @@ import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.security.cert.X509CertSelector; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; + import jdk.test.lib.security.CertUtils; public final class BuildEEBasicConstraints { @@ -65,6 +68,11 @@ PKIXBuilderParameters params = new PKIXBuilderParameters (Collections.singleton(anchor), sel); params.setRevocationEnabled(false); + + // Certs expired on 7th Nov 2022 + params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM, + Locale.US).parse("June 01, 2022")); + X509Certificate eeCert = CertUtils.getCertFromFile("ee.cer"); X509Certificate caCert = CertUtils.getCertFromFile("ca.cer"); ArrayList certs = new ArrayList(); diff -Nru openjdk-17-17.0.5+8/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java openjdk-17-17.0.6+10/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java --- openjdk-17-17.0.5+8/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/security/cert/pkix/policyChanges/TestPolicy.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2022, 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 @@ -34,6 +34,7 @@ */ import java.io.*; +import java.text.DateFormat; import java.util.*; import java.security.Security; @@ -97,6 +98,10 @@ params.setRevocationEnabled(false); params.setInitialPolicies(testCase.initialPolicies); + // Certs expired on 7th Nov 2022 + params.setDate(DateFormat.getDateInstance(DateFormat.MEDIUM, + Locale.US).parse("June 01, 2022")); + CertPath path = factory.generateCertPath(Arrays.asList(new X509Certificate[] {ee, ca})); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(path, params); diff -Nru openjdk-17-17.0.5+8/test/jdk/java/security/SignedJar/CustomClassLoader.java openjdk-17-17.0.6+10/test/jdk/java/security/SignedJar/CustomClassLoader.java --- openjdk-17-17.0.5+8/test/jdk/java/security/SignedJar/CustomClassLoader.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/security/SignedJar/CustomClassLoader.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, 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.io.IOException; +import java.io.InputStream; + +public class CustomClassLoader extends ClassLoader { + + public CustomClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + try (InputStream is = getClass().getClassLoader() + .getResourceAsStream(name + ".class")) { + byte[] buf = is.readAllBytes(); + return defineClass(name, buf, 0, buf.length); + } catch (IOException e) { + throw new ClassNotFoundException(e.getMessage()); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java openjdk-17-17.0.6+10/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java --- openjdk-17-17.0.5+8/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022, 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 8280890 + * @library /test/lib + * @build SignedJarWithCustomClassLoader CustomClassLoader + * @run main/othervm SignedJarWithCustomClassLoader + * @summary Make sure java.system.class.loader property can be used when custom + * class loader is inside signed jar + */ + +import java.nio.file.Path; +import java.nio.file.Paths; + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.compiler.InMemoryJavaCompiler; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.JarUtils; + +public class SignedJarWithCustomClassLoader { + + public static void main(String[] args) throws Exception { + + // compile the Main program + String main = """ + public class Main { + public static void main(String[] args) {} + } + """; + String testClasses = System.getProperty("test.classes", ""); + ClassFileInstaller.writeClassToDisk("Main", + InMemoryJavaCompiler.compile("Main", main), + testClasses); + + // create the jar file + Path classes = Paths.get(testClasses); + JarUtils.createJarFile(Paths.get("test.jar"), classes, + classes.resolve("CustomClassLoader.class"), + classes.resolve("Main.class")); + + // create signer's keypair + SecurityTools.keytool("-genkeypair -keyalg RSA -keystore ks " + + "-storepass changeit -dname CN=test -alias test") + .shouldHaveExitValue(0); + + // sign jar + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + "-signedjar signed.jar test.jar test") + .shouldHaveExitValue(0); + + // run app with system class loader set to custom classloader + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-cp", "signed.jar", + "-Djava.system.class.loader=CustomClassLoader", "Main"); + ProcessTools.executeProcess(pb) + .shouldHaveExitValue(0); + + // sign jar again, but this time with SHA-1 which is disabled + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + "-digestalg SHA-1 -sigalg SHA1withRSA " + + "-signedjar signed.jar test.jar test") + .shouldHaveExitValue(0); + + // run app again, should still succeed even though SHA-1 is disabled + pb = ProcessTools.createJavaProcessBuilder( + "-cp", "signed.jar", + "-Djava.system.class.loader=CustomClassLoader", "Main"); + ProcessTools.executeProcess(pb) + .shouldHaveExitValue(0); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/text/Format/NumberFormat/CurrencySymbols.properties openjdk-17-17.0.6+10/test/jdk/java/text/Format/NumberFormat/CurrencySymbols.properties --- openjdk-17-17.0.5+8/test/jdk/java/text/Format/NumberFormat/CurrencySymbols.properties 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/text/Format/NumberFormat/CurrencySymbols.properties 2023-01-10 13:21:55.000000000 +0000 @@ -79,7 +79,7 @@ fr_LU=\u20AC hi_IN=\u0930\u0942 hr=\u00A4 -hr_HR=Kn +hr_HR=\u20AC hu=\u00A4 hu_HU=Ft is=\u00A4 @@ -94,9 +94,9 @@ ko=\u00A4 ko_KR=\uFFE6 lt=\u00A4 -lt_LT=Lt;2014-12-31-22-00-00;\u20AC +lt_LT=\u20AC lv=\u00A4 -lv_LV=Ls;2013-12-31-22-00-00;\u20AC +lv_LV=\u20AC mk=\u00A4 mk_MK=Den nl=\u00A4 diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/Currency/tablea1.txt openjdk-17-17.0.6+10/test/jdk/java/util/Currency/tablea1.txt --- openjdk-17-17.0.5+8/test/jdk/java/util/Currency/tablea1.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/Currency/tablea1.txt 2023-01-10 13:21:55.000000000 +0000 @@ -1,12 +1,12 @@ # # -# Amendments up until ISO 4217 AMENDMENT NUMBER 172 -# (As of 27 June 2022) +# Amendments up until ISO 4217 AMENDMENT NUMBER 174 +# (As of 2 November 2022) # # Version FILEVERSION=3 -DATAVERSION=172 +DATAVERSION=174 # ISO 4217 currency data AF AFN 971 2 @@ -67,7 +67,7 @@ CK NZD 554 2 CR CRC 188 2 CI XOF 952 0 -HR HRK 191 2 +HR HRK 191 2 2022-12-31-23-00-00 EUR 978 2 CU CUP 192 2 CW ANG 532 2 CY EUR 978 2 diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/Currency/ValidateISO4217.java openjdk-17-17.0.6+10/test/jdk/java/util/Currency/ValidateISO4217.java --- openjdk-17-17.0.5+8/test/jdk/java/util/Currency/ValidateISO4217.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/Currency/ValidateISO4217.java 2023-01-10 13:21:55.000000000 +0000 @@ -24,7 +24,7 @@ * @test * @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759 * 8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269 - * 8208746 8209775 8264792 8274658 8283277 + * 8208746 8209775 8264792 8274658 8283277 8296239 * @summary Validate ISO 4217 data for Currency class. * @modules java.base/java.util:open * jdk.localedata @@ -34,7 +34,7 @@ * ############################################################################ * * ValidateISO4217 is a tool to detect differences between the latest ISO 4217 - * data and and Java's currency data which is based on ISO 4217. + * data and Java's currency data which is based on ISO 4217. * If there is a difference, the following file which includes currency data * may need to be updated. * src/share/classes/java/util/CurrencyData.properties diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java --- openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022, 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 8285838 + * @library /test/lib + * @summary This test will ensure that daylight savings rules are followed + * appropriately when setting a custom timezone ID via the TZ env variable. + * @requires os.family != "windows" + * @run main/othervm CustomTzIDCheckDST + */ +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.SimpleTimeZone; +import java.time.DayOfWeek; +import java.time.ZonedDateTime; +import java.time.temporal.TemporalAdjusters; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +public class CustomTzIDCheckDST { + private static String CUSTOM_TZ = "MEZ-1MESZ,M3.5.0,M10.5.0"; + public static void main(String args[]) throws Throwable { + if (args.length == 0) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(List.of("CustomTzIDCheckDST", "runTZTest")); + pb.environment().put("TZ", CUSTOM_TZ); + OutputAnalyzer output = ProcessTools.executeProcess(pb); + output.shouldHaveExitValue(0); + } else { + runTZTest(); + } + } + + /* TZ code will always be set to "MEZ-1MESZ,M3.5.0,M10.5.0". + * This ensures the transition periods for Daylights Savings should be at March's last + * Sunday and October's last Sunday. + */ + private static void runTZTest() { + Date time = new Date(); + if (new SimpleTimeZone(3600000, "MEZ-1MESZ", Calendar.MARCH, -1, Calendar.SUNDAY, 0, + Calendar.OCTOBER, -1, Calendar.SUNDAY, 0).inDaylightTime(time)) { + // We are in Daylight savings period. + if (time.toString().endsWith("GMT+02:00 " + Integer.toString(time.getYear() + 1900))) + return; + } else { + if (time.toString().endsWith("GMT+01:00 " + Integer.toString(time.getYear() + 1900))) + return; + } + + // Reaching here means time zone did not match up as expected. + throw new RuntimeException("Got unexpected timezone information: " + time); + } + + private static ZonedDateTime getLastSundayOfMonth(ZonedDateTime date) { + return date.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY)); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt --- openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt 2023-01-10 13:21:55.000000000 +0000 @@ -1,158 +1,7 @@ -Link Africa/Abidjan Africa/Accra # Ghana -Link Africa/Abidjan Africa/Bamako # Mali -Link Africa/Abidjan Africa/Banjul # The Gambia -Link Africa/Abidjan Africa/Conakry # Guinea -Link Africa/Abidjan Africa/Dakar # Senegal -Link Africa/Abidjan Africa/Freetown # Sierra Leone -Link Africa/Abidjan Africa/Lome # Togo -Link Africa/Abidjan Africa/Nouakchott # Mauritania -Link Africa/Abidjan Africa/Ouagadougou # Burkina Faso -Link Africa/Abidjan Atlantic/Reykjavik # Iceland -Link Africa/Abidjan Atlantic/St_Helena # St Helena -Link Africa/Nairobi Africa/Addis_Ababa # Ethiopia -Link Africa/Nairobi Africa/Asmara # Eritrea -Link Africa/Nairobi Africa/Dar_es_Salaam # Tanzania -Link Africa/Nairobi Africa/Djibouti -Link Africa/Nairobi Africa/Kampala # Uganda -Link Africa/Nairobi Africa/Mogadishu # Somalia -Link Africa/Nairobi Indian/Antananarivo # Madagascar -Link Africa/Nairobi Indian/Comoro -Link Africa/Nairobi Indian/Mayotte -Link Africa/Maputo Africa/Blantyre # Malawi -Link Africa/Maputo Africa/Bujumbura # Burundi -Link Africa/Maputo Africa/Gaborone # Botswana -Link Africa/Maputo Africa/Harare # Zimbabwe -Link Africa/Maputo Africa/Kigali # Rwanda -Link Africa/Maputo Africa/Lubumbashi # E Dem. Rep. of Congo -Link Africa/Maputo Africa/Lusaka # Zambia -Link Africa/Lagos Africa/Bangui # Central African Republic -Link Africa/Lagos Africa/Brazzaville # Rep. of the Congo -Link Africa/Lagos Africa/Douala # Cameroon -Link Africa/Lagos Africa/Kinshasa # Dem. Rep. of the Congo (west) -Link Africa/Lagos Africa/Libreville # Gabon -Link Africa/Lagos Africa/Luanda # Angola -Link Africa/Lagos Africa/Malabo # Equatorial Guinea -Link Africa/Lagos Africa/Niamey # Niger -Link Africa/Lagos Africa/Porto-Novo # Benin -Link Africa/Johannesburg Africa/Maseru # Lesotho -Link Africa/Johannesburg Africa/Mbabane # Eswatini -Link Asia/Yangon Indian/Cocos -Link Asia/Urumqi Antarctica/Vostok -Link Asia/Nicosia Europe/Nicosia -Link Asia/Kuching Asia/Brunei -Link Indian/Maldives Indian/Kerguelen -Link Asia/Qatar Asia/Bahrain -Link Asia/Riyadh Antarctica/Syowa -Link Asia/Riyadh Asia/Aden # Yemen -Link Asia/Riyadh Asia/Kuwait -Link Asia/Singapore Asia/Kuala_Lumpur -Link Asia/Bangkok Asia/Phnom_Penh # Cambodia -Link Asia/Bangkok Asia/Vientiane # Laos -Link Asia/Bangkok Indian/Christmas -Link Asia/Dubai Asia/Muscat # Oman -Link Asia/Dubai Indian/Mahe -Link Asia/Dubai Indian/Reunion -Link Pacific/Guam Pacific/Saipan # N Mariana Is -Link Pacific/Tarawa Pacific/Funafuti -Link Pacific/Tarawa Pacific/Majuro -Link Pacific/Tarawa Pacific/Wake -Link Pacific/Tarawa Pacific/Wallis -Link Pacific/Auckland Antarctica/McMurdo -Link Pacific/Port_Moresby Antarctica/DumontDUrville -Link Pacific/Port_Moresby Pacific/Chuuk -Link Pacific/Pago_Pago Pacific/Midway # in US minor outlying islands -Link Pacific/Guadalcanal Pacific/Pohnpei -Link Europe/London Europe/Jersey -Link Europe/London Europe/Guernsey -Link Europe/London Europe/Isle_of_Man -Link Europe/Brussels Europe/Amsterdam -Link Europe/Brussels Europe/Luxembourg -Link Europe/Prague Europe/Bratislava -Link Europe/Helsinki Europe/Mariehamn -Link Europe/Paris Europe/Monaco -Link Europe/Berlin Arctic/Longyearbyen -Link Europe/Berlin Europe/Copenhagen -Link Europe/Berlin Europe/Oslo -Link Europe/Berlin Europe/Stockholm -Link Europe/Rome Europe/Vatican -Link Europe/Rome Europe/San_Marino -Link Europe/Belgrade Europe/Ljubljana # Slovenia -Link Europe/Belgrade Europe/Podgorica # Montenegro -Link Europe/Belgrade Europe/Sarajevo # Bosnia and Herzegovina -Link Europe/Belgrade Europe/Skopje # North Macedonia -Link Europe/Belgrade Europe/Zagreb # Croatia -Link Europe/Zurich Europe/Busingen -Link Europe/Zurich Europe/Vaduz -Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents. -Link America/Phoenix America/Creston -Link America/Toronto America/Nassau -Link America/Panama America/Atikokan -Link America/Panama America/Cayman -Link America/Puerto_Rico America/Anguilla -Link America/Puerto_Rico America/Antigua -Link America/Puerto_Rico America/Aruba -Link America/Puerto_Rico America/Curacao -Link America/Puerto_Rico America/Blanc-Sablon # Quebec (Lower North Shore) -Link America/Puerto_Rico America/Dominica -Link America/Puerto_Rico America/Grenada -Link America/Puerto_Rico America/Guadeloupe -Link America/Puerto_Rico America/Kralendijk # Caribbean Netherlands -Link America/Puerto_Rico America/Lower_Princes # Sint Maarten -Link America/Puerto_Rico America/Marigot # St Martin (French part) -Link America/Puerto_Rico America/Montserrat -Link America/Puerto_Rico America/Port_of_Spain # Trinidad & Tobago -Link America/Puerto_Rico America/St_Barthelemy # St Barthélemy -Link America/Puerto_Rico America/St_Kitts # St Kitts & Nevis -Link America/Puerto_Rico America/St_Lucia -Link America/Puerto_Rico America/St_Thomas # Virgin Islands (US) -Link America/Puerto_Rico America/St_Vincent -Link America/Puerto_Rico America/Tortola # Virgin Islands (UK) Link Asia/Riyadh87 Mideast/Riyadh87 Link Asia/Riyadh88 Mideast/Riyadh88 Link Asia/Riyadh89 Mideast/Riyadh89 -Link Africa/Nairobi Africa/Asmera -Link Africa/Abidjan Africa/Timbuktu -Link America/Argentina/Catamarca America/Argentina/ComodRivadavia -Link America/Adak America/Atka -Link America/Argentina/Buenos_Aires America/Buenos_Aires -Link America/Argentina/Catamarca America/Catamarca -Link America/Panama America/Coral_Harbour -Link America/Argentina/Cordoba America/Cordoba -Link America/Tijuana America/Ensenada -Link America/Indiana/Indianapolis America/Fort_Wayne -Link America/Nuuk America/Godthab -Link America/Indiana/Indianapolis America/Indianapolis -Link America/Argentina/Jujuy America/Jujuy -Link America/Indiana/Knox America/Knox_IN -Link America/Kentucky/Louisville America/Louisville -Link America/Argentina/Mendoza America/Mendoza -Link America/Toronto America/Montreal -Link America/Rio_Branco America/Porto_Acre -Link America/Argentina/Cordoba America/Rosario -Link America/Tijuana America/Santa_Isabel -Link America/Denver America/Shiprock -Link America/Puerto_Rico America/Virgin -Link Pacific/Auckland Antarctica/South_Pole -Link Asia/Ashgabat Asia/Ashkhabad -Link Asia/Kolkata Asia/Calcutta -Link Asia/Shanghai Asia/Chongqing -Link Asia/Shanghai Asia/Chungking -Link Asia/Dhaka Asia/Dacca -Link Asia/Shanghai Asia/Harbin -Link Asia/Urumqi Asia/Kashgar -Link Asia/Kathmandu Asia/Katmandu -Link Asia/Macau Asia/Macao -Link Asia/Yangon Asia/Rangoon -Link Asia/Ho_Chi_Minh Asia/Saigon -Link Asia/Jerusalem Asia/Tel_Aviv -Link Asia/Thimphu Asia/Thimbu -Link Asia/Makassar Asia/Ujung_Pandang -Link Asia/Ulaanbaatar Asia/Ulan_Bator -Link Atlantic/Faroe Atlantic/Faeroe -Link Europe/Berlin Atlantic/Jan_Mayen -Link Australia/Sydney Australia/ACT -Link Australia/Sydney Australia/Canberra -Link Australia/Hobart Australia/Currie +Link Australia/Sydney Australia/ACT #= Australia/Canberra Link Australia/Lord_Howe Australia/LHI Link Australia/Sydney Australia/NSW Link Australia/Darwin Australia/North @@ -162,7 +11,7 @@ Link Australia/Melbourne Australia/Victoria Link Australia/Perth Australia/West Link Australia/Broken_Hill Australia/Yancowinna -Link America/Rio_Branco Brazil/Acre +Link America/Rio_Branco Brazil/Acre #= America/Porto_Acre Link America/Noronha Brazil/DeNoronha Link America/Sao_Paulo Brazil/East Link America/Manaus Brazil/West @@ -179,10 +28,13 @@ Link America/Havana Cuba Link Africa/Cairo Egypt Link Europe/Dublin Eire +Link Etc/GMT Etc/GMT+0 +Link Etc/GMT Etc/GMT-0 +Link Etc/GMT Etc/GMT0 +Link Etc/GMT Etc/Greenwich Link Etc/UTC Etc/UCT -Link Europe/London Europe/Belfast -Link Europe/Kyiv Europe/Kiev -Link Europe/Chisinau Europe/Tiraspol +Link Etc/UTC Etc/Universal +Link Etc/UTC Etc/Zulu Link Europe/London GB Link Europe/London GB-Eire Link Etc/GMT GMT+0 @@ -190,7 +42,7 @@ Link Etc/GMT GMT0 Link Etc/GMT Greenwich Link Asia/Hong_Kong Hongkong -Link Africa/Abidjan Iceland +Link Africa/Abidjan Iceland #= Atlantic/Reykjavik Link Asia/Tehran Iran Link Asia/Jerusalem Israel Link America/Jamaica Jamaica @@ -202,14 +54,8 @@ Link America/Mexico_City Mexico/General Link Pacific/Auckland NZ Link Pacific/Chatham NZ-CHAT -Link America/Denver Navajo +Link America/Denver Navajo #= America/Shiprock Link Asia/Shanghai PRC -Link Pacific/Kanton Pacific/Enderbury -Link Pacific/Honolulu Pacific/Johnston -Link Pacific/Guadalcanal Pacific/Ponape -Link Pacific/Pago_Pago Pacific/Samoa -Link Pacific/Port_Moresby Pacific/Truk -Link Pacific/Port_Moresby Pacific/Yap Link Europe/Warsaw Poland Link Europe/Lisbon Portugal Link Asia/Taipei ROC @@ -233,3 +79,169 @@ Link Etc/UTC Universal Link Europe/Moscow W-SU Link Etc/UTC Zulu +Link America/Argentina/Buenos_Aires America/Buenos_Aires +Link America/Argentina/Catamarca America/Catamarca +Link America/Argentina/Cordoba America/Cordoba +Link America/Indiana/Indianapolis America/Indianapolis +Link America/Argentina/Jujuy America/Jujuy +Link America/Indiana/Knox America/Knox_IN +Link America/Kentucky/Louisville America/Louisville +Link America/Argentina/Mendoza America/Mendoza +Link America/Puerto_Rico America/Virgin #= America/St_Thomas +Link Pacific/Pago_Pago Pacific/Samoa +Link Africa/Abidjan Africa/Accra +Link Africa/Nairobi Africa/Addis_Ababa +Link Africa/Nairobi Africa/Asmara +Link Africa/Abidjan Africa/Bamako +Link Africa/Lagos Africa/Bangui +Link Africa/Abidjan Africa/Banjul +Link Africa/Maputo Africa/Blantyre +Link Africa/Lagos Africa/Brazzaville +Link Africa/Maputo Africa/Bujumbura +Link Africa/Abidjan Africa/Conakry +Link Africa/Abidjan Africa/Dakar +Link Africa/Nairobi Africa/Dar_es_Salaam +Link Africa/Nairobi Africa/Djibouti +Link Africa/Lagos Africa/Douala +Link Africa/Abidjan Africa/Freetown +Link Africa/Maputo Africa/Gaborone +Link Africa/Maputo Africa/Harare +Link Africa/Nairobi Africa/Kampala +Link Africa/Maputo Africa/Kigali +Link Africa/Lagos Africa/Kinshasa +Link Africa/Lagos Africa/Libreville +Link Africa/Abidjan Africa/Lome +Link Africa/Lagos Africa/Luanda +Link Africa/Maputo Africa/Lubumbashi +Link Africa/Maputo Africa/Lusaka +Link Africa/Lagos Africa/Malabo +Link Africa/Johannesburg Africa/Maseru +Link Africa/Johannesburg Africa/Mbabane +Link Africa/Nairobi Africa/Mogadishu +Link Africa/Lagos Africa/Niamey +Link Africa/Abidjan Africa/Nouakchott +Link Africa/Abidjan Africa/Ouagadougou +Link Africa/Lagos Africa/Porto-Novo +Link America/Puerto_Rico America/Anguilla +Link America/Puerto_Rico America/Antigua +Link America/Puerto_Rico America/Aruba +Link America/Panama America/Atikokan +Link America/Puerto_Rico America/Blanc-Sablon +Link America/Panama America/Cayman +Link America/Phoenix America/Creston +Link America/Puerto_Rico America/Curacao +Link America/Puerto_Rico America/Dominica +Link America/Puerto_Rico America/Grenada +Link America/Puerto_Rico America/Guadeloupe +Link America/Puerto_Rico America/Kralendijk +Link America/Puerto_Rico America/Lower_Princes +Link America/Puerto_Rico America/Marigot +Link America/Puerto_Rico America/Montserrat +Link America/Toronto America/Nassau +Link America/Puerto_Rico America/Port_of_Spain +Link America/Puerto_Rico America/St_Barthelemy +Link America/Puerto_Rico America/St_Kitts +Link America/Puerto_Rico America/St_Lucia +Link America/Puerto_Rico America/St_Thomas +Link America/Puerto_Rico America/St_Vincent +Link America/Puerto_Rico America/Tortola +Link Pacific/Port_Moresby Antarctica/DumontDUrville +Link Pacific/Auckland Antarctica/McMurdo +Link Asia/Riyadh Antarctica/Syowa +Link Asia/Urumqi Antarctica/Vostok +Link Europe/Berlin Arctic/Longyearbyen +Link Asia/Riyadh Asia/Aden +Link Asia/Qatar Asia/Bahrain +Link Asia/Kuching Asia/Brunei +Link Asia/Singapore Asia/Kuala_Lumpur +Link Asia/Riyadh Asia/Kuwait +Link Asia/Dubai Asia/Muscat +Link Asia/Bangkok Asia/Phnom_Penh +Link Asia/Bangkok Asia/Vientiane +Link Africa/Abidjan Atlantic/Reykjavik +Link Africa/Abidjan Atlantic/St_Helena +Link Europe/Brussels Europe/Amsterdam +Link Europe/Prague Europe/Bratislava +Link Europe/Zurich Europe/Busingen +Link Europe/Berlin Europe/Copenhagen +Link Europe/London Europe/Guernsey +Link Europe/London Europe/Isle_of_Man +Link Europe/London Europe/Jersey +Link Europe/Belgrade Europe/Ljubljana +Link Europe/Brussels Europe/Luxembourg +Link Europe/Helsinki Europe/Mariehamn +Link Europe/Paris Europe/Monaco +Link Europe/Berlin Europe/Oslo +Link Europe/Belgrade Europe/Podgorica +Link Europe/Rome Europe/San_Marino +Link Europe/Belgrade Europe/Sarajevo +Link Europe/Belgrade Europe/Skopje +Link Europe/Berlin Europe/Stockholm +Link Europe/Zurich Europe/Vaduz +Link Europe/Rome Europe/Vatican +Link Europe/Belgrade Europe/Zagreb +Link Africa/Nairobi Indian/Antananarivo +Link Asia/Bangkok Indian/Christmas +Link Asia/Yangon Indian/Cocos +Link Africa/Nairobi Indian/Comoro +Link Indian/Maldives Indian/Kerguelen +Link Asia/Dubai Indian/Mahe +Link Africa/Nairobi Indian/Mayotte +Link Asia/Dubai Indian/Reunion +Link Pacific/Port_Moresby Pacific/Chuuk +Link Pacific/Tarawa Pacific/Funafuti +Link Pacific/Tarawa Pacific/Majuro +Link Pacific/Pago_Pago Pacific/Midway +Link Pacific/Guadalcanal Pacific/Pohnpei +Link Pacific/Guam Pacific/Saipan +Link Pacific/Tarawa Pacific/Wake +Link Pacific/Tarawa Pacific/Wallis +Link Africa/Abidjan Africa/Timbuktu +Link America/Argentina/Catamarca America/Argentina/ComodRivadavia +Link America/Adak America/Atka +Link America/Panama America/Coral_Harbour +Link America/Tijuana America/Ensenada +Link America/Indiana/Indianapolis America/Fort_Wayne +Link America/Toronto America/Montreal +Link America/Toronto America/Nipigon +Link America/Iqaluit America/Pangnirtung +Link America/Rio_Branco America/Porto_Acre +Link America/Winnipeg America/Rainy_River +Link America/Argentina/Cordoba America/Rosario +Link America/Tijuana America/Santa_Isabel +Link America/Denver America/Shiprock +Link America/Toronto America/Thunder_Bay +Link Pacific/Auckland Antarctica/South_Pole +Link Asia/Shanghai Asia/Chongqing +Link Asia/Shanghai Asia/Harbin +Link Asia/Urumqi Asia/Kashgar +Link Asia/Jerusalem Asia/Tel_Aviv +Link Europe/Berlin Atlantic/Jan_Mayen +Link Australia/Sydney Australia/Canberra +Link Australia/Hobart Australia/Currie +Link Europe/London Europe/Belfast +Link Europe/Chisinau Europe/Tiraspol +Link Europe/Kyiv Europe/Uzhgorod +Link Europe/Kyiv Europe/Zaporozhye +Link Pacific/Kanton Pacific/Enderbury +Link Pacific/Honolulu Pacific/Johnston +Link Pacific/Port_Moresby Pacific/Yap +Link Africa/Nairobi Africa/Asmera #= Africa/Asmara +Link America/Nuuk America/Godthab +Link Asia/Ashgabat Asia/Ashkhabad +Link Asia/Kolkata Asia/Calcutta +Link Asia/Shanghai Asia/Chungking #= Asia/Chongqing +Link Asia/Dhaka Asia/Dacca +Link Europe/Istanbul Asia/Istanbul +Link Asia/Kathmandu Asia/Katmandu +Link Asia/Macau Asia/Macao +Link Asia/Yangon Asia/Rangoon +Link Asia/Ho_Chi_Minh Asia/Saigon +Link Asia/Thimphu Asia/Thimbu +Link Asia/Makassar Asia/Ujung_Pandang +Link Asia/Ulaanbaatar Asia/Ulan_Bator +Link Atlantic/Faroe Atlantic/Faeroe +Link Europe/Kyiv Europe/Kiev +Link Asia/Nicosia Europe/Nicosia +Link Pacific/Guadalcanal Pacific/Ponape #= Pacific/Pohnpei +Link Pacific/Port_Moresby Pacific/Truk #= Pacific/Chuuk diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt --- openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt 2023-01-10 13:21:55.000000000 +0000 @@ -24,7 +24,8 @@ America/Cambridge_Bay MST MDT America/Cancun EST America/Chicago CST CDT -America/Chihuahua MST MDT +America/Chihuahua CST +America/Ciudad_Juarez MST MDT America/Costa_Rica CST CDT America/Danmarkshavn GMT America/Dawson MST @@ -67,18 +68,15 @@ America/Moncton AST ADT America/Monterrey CST CDT America/New_York EST EDT -America/Nipigon EST EDT America/Nome AKST AKDT America/North_Dakota/Beulah CST CDT America/North_Dakota/Center CST CDT America/North_Dakota/New_Salem CST CDT -America/Ojinaga MST MDT +America/Ojinaga CST CDT America/Panama EST -America/Pangnirtung EST EDT America/Phoenix MST America/Port-au-Prince EST EDT America/Puerto_Rico AST -America/Rainy_River CST CDT America/Rankin_Inlet CST CDT America/Regina CST America/Resolute CST CDT @@ -88,7 +86,6 @@ America/Swift_Current CST America/Tegucigalpa CST CDT America/Thule AST ADT -America/Thunder_Bay EST EDT America/Tijuana PST PDT America/Toronto EST EDT America/Vancouver PST PDT @@ -97,9 +94,7 @@ America/Yakutat AKST AKDT America/Yellowknife MST MDT Antarctica/Macquarie AEST AEDT -Asia/Amman EET EEST Asia/Beirut EET EEST -Asia/Damascus EET EEST Asia/Famagusta EET EEST Asia/Gaza EET EEST Asia/Hebron EET EEST @@ -163,11 +158,9 @@ Europe/Sofia EET EEST Europe/Tallinn EET EEST Europe/Tirane CET CEST -Europe/Uzhgorod EET EEST Europe/Vienna CET CEST Europe/Vilnius EET EEST Europe/Warsaw CET CEST -Europe/Zaporozhye EET EEST Europe/Zurich CET CEST HST HST MET MET MEST diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/VERSION openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/VERSION --- openjdk-17-17.0.5+8/test/jdk/java/util/TimeZone/TimeZoneData/VERSION 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/TimeZone/TimeZoneData/VERSION 2023-01-10 13:21:55.000000000 +0000 @@ -1 +1 @@ -tzdata2022c +tzdata2022g diff -Nru openjdk-17-17.0.5+8/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java openjdk-17-17.0.6+10/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java --- openjdk-17-17.0.5+8/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/java/util/zip/CloseInflaterDeflaterTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /** * @test - * @bug 8193682 8278794 + * @bug 8193682 8278794 8284771 * @summary Test Infinite loop while writing on closed Deflater and Inflater. * @run testng CloseInflaterDeflaterTest */ @@ -171,10 +171,11 @@ /** * Test for infinite loop by writing bytes to closed InflaterOutputStream * + * Note: Disabling this test as it is failing intermittently. * @param useCloseMethod indicates whether to use Close() or finish() method * @throws IOException if an error occurs */ - @Test(dataProvider = "testOutputStreams") + @Test(dataProvider = "testOutputStreams",enabled=false) public void testInflaterOutputStream(boolean useCloseMethod) throws IOException { InflaterOutputStream inf = new InflaterOutputStream(outStream); assertThrows(IOException.class , () -> inf.write(inputBytes, 0, INPUT_LENGTH)); diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleActionConstants.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleActionConstants.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleActionConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleActionConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 2022, 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. + */ + +/* + * @summary Constant for testing public fields in AccessibleAction. + */ + +public interface AccessibleActionConstants { + + String CLASS_NAME = "javax.accessibility.AccessibleAction"; + + /** + * Public fields values in AccessibleAction class. + */ + String[][] FIELDS = + new String[][] { { "CLICK", "click" }, { "DECREMENT", "decrement" }, + { "INCREMENT", "increment" }, { "TOGGLE_EXPAND", "toggleexpand" }, + { "TOGGLE_POPUP", "toggle popup" } }; + /** + * Old(removed) fields in AccessibleAction class. + */ + String[] OLD_FIELDS = new String[] {}; +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleContextConstants.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleContextConstants.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleContextConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleContextConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010, 2022, 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. + */ + +/* + * @summary Constant for testing public fields in AccessibleContext. + */ + +public interface AccessibleContextConstants { + + String CLASS_NAME = "javax.accessibility.AccessibleContext"; + + /** + * Public fields values in AccessibleContext class. + */ + String[][] FIELDS = new String[][] { + { "ACCESSIBLE_NAME_PROPERTY", "AccessibleName" }, + { "ACCESSIBLE_DESCRIPTION_PROPERTY", "AccessibleDescription" }, + { "ACCESSIBLE_STATE_PROPERTY", "AccessibleState" }, + { "ACCESSIBLE_VALUE_PROPERTY", "AccessibleValue" }, + { "ACCESSIBLE_SELECTION_PROPERTY", "AccessibleSelection" }, + { "ACCESSIBLE_CARET_PROPERTY", "AccessibleCaret" }, + { "ACCESSIBLE_VISIBLE_DATA_PROPERTY", "AccessibleVisibleData" }, + { "ACCESSIBLE_CHILD_PROPERTY", "AccessibleChild" }, + { "ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY", + "AccessibleActiveDescendant" }, + { "ACCESSIBLE_TABLE_CAPTION_CHANGED", "accessibleTableCaptionChanged" }, + { "ACCESSIBLE_TABLE_SUMMARY_CHANGED", "accessibleTableSummaryChanged" }, + { "ACCESSIBLE_TABLE_MODEL_CHANGED", "accessibleTableModelChanged" }, + { "ACCESSIBLE_TABLE_ROW_HEADER_CHANGED", + "accessibleTableRowHeaderChanged" }, + { "ACCESSIBLE_TABLE_ROW_DESCRIPTION_CHANGED", + "accessibleTableRowDescriptionChanged" }, + { "ACCESSIBLE_TABLE_COLUMN_HEADER_CHANGED", + "accessibleTableColumnHeaderChanged" }, + { "ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_CHANGED", + "accessibleTableColumnDescriptionChanged" }, + { "ACCESSIBLE_ACTION_PROPERTY", "accessibleActionProperty" }, + { "ACCESSIBLE_HYPERTEXT_OFFSET", "AccessibleHypertextOffset" }, + { "ACCESSIBLE_TEXT_PROPERTY", "AccessibleText" }, + { "ACCESSIBLE_INVALIDATE_CHILDREN", "accessibleInvalidateChildren" }, + { "ACCESSIBLE_TEXT_ATTRIBUTES_CHANGED", + "accessibleTextAttributesChanged" }, + { "ACCESSIBLE_COMPONENT_BOUNDS_CHANGED", + "accessibleComponentBoundsChanged" } }; + + /** + * Old(removed) fields in AccessibleContext class. + */ + String[] OLD_FIELDS = new String[] {}; +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessiblePropertiesTest.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessiblePropertiesTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessiblePropertiesTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessiblePropertiesTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010, 2022, 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 4702233 + * @summary Testing current and old(removed) public fields in AccessibleAction, + * AccessibleContext, AccessibleRelation, AccessibleRole and AccessibleState. + * @run main AccessiblePropertiesTest + */ + +import java.lang.reflect.Field; + +public class AccessiblePropertiesTest { + + private static void checkFields(String className, String[][] fields, + String[] oldFields) { + try { + Class klass = Class.forName(className); + + if (klass.getFields().length != fields.length) { + throw new RuntimeException("Fields in " + className + + " were changed. Test should be updated!"); + } + + for (int i = 0; i < fields.length; ++i) { + String key = fields[i][0]; + String value = fields[i][1]; + Field field = klass.getDeclaredField(key); + String current = field.get(String.class).toString(); + + if (!current.equals(value)) { + throw new RuntimeException( + "Field " + field.getName() + " current value=" + current + + " , expected value=" + value); + } + } + + for (int i = 0; i < oldFields.length; ++i) { + String key = oldFields[i]; + + try { + klass.getDeclaredField(key); + + throw new RuntimeException(key + " exists in " + klass); + } catch (NoSuchFieldException ignored) { + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + + checkFields(AccessibleActionConstants.CLASS_NAME, + AccessibleActionConstants.FIELDS, + AccessibleActionConstants.OLD_FIELDS); + + checkFields(AccessibleRelationConstants.CLASS_NAME, + AccessibleRelationConstants.FIELDS, + AccessibleRelationConstants.OLD_FIELDS); + + checkFields(AccessibleRoleConstants.CLASS_NAME, + AccessibleRoleConstants.FIELDS, AccessibleRoleConstants.OLD_FIELDS); + + checkFields(AccessibleStateConstants.CLASS_NAME, + AccessibleStateConstants.FIELDS, + AccessibleStateConstants.OLD_FIELDS); + + checkFields(AccessibleContextConstants.CLASS_NAME, + AccessibleContextConstants.FIELDS, + AccessibleContextConstants.OLD_FIELDS); + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleRelationConstants.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleRelationConstants.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleRelationConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleRelationConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010, 2022, 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. + */ + +/* + * @summary Constant for testing public fields in AccessibleRelation. + */ +public interface AccessibleRelationConstants { + + /** + * Fully-qualified name of the class. + */ + String CLASS_NAME = "javax.accessibility.AccessibleRelation"; + + /** + * Public fields values in AccessibleRelation class. + */ + String[][] FIELDS = new String[][] { { "CHILD_NODE_OF", "childNodeOf" }, + { "CHILD_NODE_OF_PROPERTY", "childNodeOfProperty" }, + { "CONTROLLED_BY", "controlledBy" }, + { "CONTROLLED_BY_PROPERTY", "controlledByProperty" }, + { "CONTROLLER_FOR", "controllerFor" }, + { "CONTROLLER_FOR_PROPERTY", "controllerForProperty" }, + { "EMBEDDED_BY", "embeddedBy" }, + { "EMBEDDED_BY_PROPERTY", "embeddedByProperty" }, + { "EMBEDS", "embeds" }, { "EMBEDS_PROPERTY", "embedsProperty" }, + { "FLOWS_FROM", "flowsFrom" }, + { "FLOWS_FROM_PROPERTY", "flowsFromProperty" }, + { "FLOWS_TO", "flowsTo" }, { "FLOWS_TO_PROPERTY", "flowsToProperty" }, + { "LABELED_BY", "labeledBy" }, + { "LABELED_BY_PROPERTY", "labeledByProperty" }, + { "LABEL_FOR", "labelFor" }, + { "LABEL_FOR_PROPERTY", "labelForProperty" }, + { "MEMBER_OF", "memberOf" }, + { "MEMBER_OF_PROPERTY", "memberOfProperty" }, + { "PARENT_WINDOW_OF", "parentWindowOf" }, + { "PARENT_WINDOW_OF_PROPERTY", "parentWindowOfProperty" }, + { "SUBWINDOW_OF", "subwindowOf" }, + { "SUBWINDOW_OF_PROPERTY", "subwindowOfProperty" }, }; + + /** + * Old(removed) fields in AccessibleRelation class. + */ + String[] OLD_FIELDS = new String[] {}; +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleRoleConstants.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleRoleConstants.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleRoleConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleRoleConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010, 2022, 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. + */ + +/* + * @summary Constant for testing public fields in AccessibleRole. + */ + +public interface AccessibleRoleConstants { + + /** + * Fully-qualified name of the class. + */ + String CLASS_NAME = "javax.accessibility.AccessibleRole"; + + /** + * Public fields values in AccessibleRole class. + */ + String[][] FIELDS = new String[][] { { "ALERT", "alert" }, + { "AWT_COMPONENT", "AWT component" }, { "CANVAS", "canvas" }, + { "CHECK_BOX", "check box" }, { "COLOR_CHOOSER", "color chooser" }, + { "COLUMN_HEADER", "column header" }, { "COMBO_BOX", "combo box" }, + { "DATE_EDITOR", "dateeditor" }, { "DESKTOP_ICON", "desktop icon" }, + { "DESKTOP_PANE", "desktop pane" }, { "DIALOG", "dialog" }, + { "DIRECTORY_PANE", "directory pane" }, { "EDITBAR", "editbar" }, + { "FILE_CHOOSER", "file chooser" }, { "FILLER", "filler" }, + { "FONT_CHOOSER", "fontchooser" }, { "FOOTER", "footer" }, + { "FRAME", "frame" }, { "GLASS_PANE", "glass pane" }, + { "GROUP_BOX", "groupbox" }, { "HEADER", "header" }, + { "HTML_CONTAINER", "HTML container" }, { "HYPERLINK", "hyperlink" }, + { "ICON", "icon" }, { "INTERNAL_FRAME", "internal frame" }, + { "LABEL", "label" }, { "LAYERED_PANE", "layered pane" }, + { "LIST", "list" }, { "LIST_ITEM", "list item" }, { "MENU", "menu" }, + { "MENU_BAR", "menu bar" }, { "MENU_ITEM", "menu item" }, + { "OPTION_PANE", "option pane" }, { "PAGE_TAB", "page tab" }, + { "PAGE_TAB_LIST", "page tab list" }, { "PANEL", "panel" }, + { "PARAGRAPH", "paragraph" }, { "PASSWORD_TEXT", "password text" }, + { "POPUP_MENU", "popup menu" }, { "PROGRESS_BAR", "progress bar" }, + { "PROGRESS_MONITOR", "progress monitor" }, + { "PUSH_BUTTON", "push JButton" }, { "RADIO_BUTTON", "radio JButton" }, + { "ROOT_PANE", "root pane" }, { "ROW_HEADER", "row header" }, + { "RULER", "ruler" }, { "SCROLL_BAR", "scroll bar" }, + { "SCROLL_PANE", "scroll pane" }, { "SEPARATOR", "separator" }, + { "SLIDER", "slider" }, { "SPIN_BOX", "spinbox" }, + { "SPLIT_PANE", "split pane" }, { "STATUS_BAR", "statusbar" }, + { "SWING_COMPONENT", "swing component" }, { "TABLE", "table" }, + { "TEXT", "text" }, { "TOGGLE_BUTTON", "toggle JButton" }, + { "TOOL_BAR", "tool bar" }, { "TOOL_TIP", "tool tip" }, + { "TREE", "tree" }, { "UNKNOWN", "unknown" }, + { "VIEWPORT", "viewport" }, { "WINDOW", "window" } }; + + /** + * Old(removed) fields in AccessibleRole class. + */ + String[] OLD_FIELDS = new String[] {}; +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleStateConstants.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleStateConstants.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/4702233/AccessibleStateConstants.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/4702233/AccessibleStateConstants.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010, 2022, 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. + */ + +/* + * @summary Constant for testing public fields in AccessibleState. + */ + +public interface AccessibleStateConstants { + + /** + * Fully-qualified name of the class. + */ + String CLASS_NAME = "javax.accessibility.AccessibleState"; + + /** + * Public fields values in AccessibleState class. + */ + String[][] FIELDS = new String[][] { { "ACTIVE", "active" }, + { "ARMED", "armed" }, { "BUSY", "busy" }, { "CHECKED", "checked" }, + { "COLLAPSED", "collapsed" }, { "EDITABLE", "editable" }, + { "ENABLED", "enabled" }, { "EXPANDABLE", "expandable" }, + { "EXPANDED", "expanded" }, { "FOCUSABLE", "focusable" }, + { "FOCUSED", "focused" }, { "HORIZONTAL", "horizontal" }, + { "ICONIFIED", "iconified" }, { "INDETERMINATE", "indeterminate" }, + { "MANAGES_DESCENDANTS", "manages descendants" }, { "MODAL", "modal" }, + { "MULTISELECTABLE", "multiselectable" }, + { "MULTI_LINE", "multiple line" }, { "OPAQUE", "opaque" }, + { "PRESSED", "pressed" }, { "RESIZABLE", "resizable" }, + { "SELECTABLE", "selectable" }, { "SELECTED", "selected" }, + { "SHOWING", "showing" }, { "SINGLE_LINE", "single line" }, + { "TRANSIENT", "transient" }, { "TRUNCATED", "truncated" }, + { "VERTICAL", "vertical" }, { "VISIBLE", "visible" } }; + + /** + * Old(removed) fields in AccessibleState class. + */ + String[] OLD_FIELDS = new String[] { + + // CR 4981070 INCONSISTENT was replaced by INDETERMINATE. + "INCONSISTENT" }; +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/AccessibleJTableSelectionTest.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/AccessibleJTableSelectionTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/AccessibleJTableSelectionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/AccessibleJTableSelectionTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2010, 2022, 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 + * @key headful + * @bug 4495286 + * @summary Verify that AccessibleJTable.setAccessibleSelction + * selects rows/cols if getCellSelectionEnabled() is false + * @run main AccessibleJTableSelectionTest + */ + +import java.awt.BorderLayout; +import java.awt.Robot; + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; + +public final class AccessibleJTableSelectionTest { + + private static JTable jTable; + private static JFrame jFrame; + + private static Robot robot; + + private static void createGUI() { + + Object[][] rowData = { { "RowData1", Integer.valueOf(1) }, + { "RowData2", Integer.valueOf(2) }, + { "RowData3", Integer.valueOf(3) } }; + Object[] columnData = { "Column One", "Column Two" }; + + jTable = new JTable(rowData, columnData); + jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + jTable.setRowSelectionAllowed(false); + jTable.setColumnSelectionAllowed(false); + jTable.setCellSelectionEnabled(true); + + jFrame = new JFrame(); + jFrame.add(new JScrollPane(jTable), BorderLayout.CENTER); + jFrame.setSize(200, 200); + jFrame.setLocationRelativeTo(null); + jFrame.setVisible(true); + } + + private static void doTest() throws Exception { + SwingUtilities.invokeAndWait(() -> createGUI()); + + robot = new Robot(); + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTable.requestFocus(); + jTable.getAccessibleContext().getAccessibleSelection() + .addAccessibleSelection(1); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + if (!jTable.isRowSelected(0) || !jTable.isColumnSelected(1)) { + throw new RuntimeException( + "Unexpected selection state of " + + "Table Row & Column"); + } + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTable.setRowSelectionAllowed(true); + jTable.setColumnSelectionAllowed(false); + jTable.setCellSelectionEnabled(false); + jTable.requestFocus(); + jTable.getAccessibleContext().getAccessibleSelection() + .addAccessibleSelection(3); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + if (!jTable.isRowSelected(1)) { + throw new RuntimeException( + "Unexpected selection state of " + + "Table Row & Column"); + } + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTable.setRowSelectionAllowed(false); + jTable.setColumnSelectionAllowed(true); + jTable.setCellSelectionEnabled(false); + jTable.requestFocus(); + jTable.getAccessibleContext().getAccessibleSelection() + .addAccessibleSelection(4); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + if (!jTable.isColumnSelected(0)) { + throw new RuntimeException( + "Unexpected selection state of " + + "Table Row & Column"); + } + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTable.setRowSelectionAllowed(true); + jTable.setColumnSelectionAllowed(true); + jTable.setCellSelectionEnabled(false); + jTable.requestFocus(); + jTable.getAccessibleContext().getAccessibleSelection() + .addAccessibleSelection(5); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + if (!(jTable.isRowSelected(2) && jTable.isColumnSelected(1))) { + throw new RuntimeException( + "Unexpected selection state of " + + "Table Row & Column"); + } + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTable.setCellSelectionEnabled(true); + jTable.setColumnSelectionAllowed(true); + jTable.setRowSelectionAllowed(true); + jTable.requestFocus(); + jTable.getAccessibleContext().getAccessibleSelection() + .addAccessibleSelection(4); + }); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + if (!(jTable.isRowSelected(2) && jTable.isColumnSelected(0) + && jTable.isCellSelected(2, 0))) { + throw new RuntimeException( + "Unexpected selection state of " + + "Table Row & Column"); + } + }); + } + + public static void main(final String[] argv) throws Exception { + doTest(); + SwingUtilities.invokeAndWait(() -> jFrame.dispose()); + System.out.println("Test Passed."); + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/JFileChooserAccessibleDescriptionTest.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/JFileChooserAccessibleDescriptionTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/JFileChooserAccessibleDescriptionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/JFileChooserAccessibleDescriptionTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2002, 2022, 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 4515031 + * @key headful + * @summary The JFileChooser Dialog itself has no accessible description. + * @run main JFileChooserAccessibleDescriptionTest + */ +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class JFileChooserAccessibleDescriptionTest { + private static JFrame jFrame; + private static JFileChooser jFileChooser; + private static JButton jButton; + + private static Robot robot; + private static volatile String description; + private static volatile int xLocn; + private static volatile int yLocn; + private static volatile int width; + private static volatile int height; + + public static void createGUI() { + jFrame = new JFrame("bug4515031 Frame"); + jFileChooser = new JFileChooser(); + + jButton = new JButton("Show FileChooser"); + jButton.addActionListener(e -> jFileChooser.showDialog(jFrame, null)); + jFrame.getContentPane().add(jButton); + jFrame.setSize(200, 100); + jFrame.setLocationRelativeTo(null); + jFrame.setVisible(true); + } + + public static void doTest() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> createGUI()); + robot = new Robot(); + robot.setAutoDelay(200); + robot.setAutoWaitForIdle(true); + + SwingUtilities.invokeAndWait(() -> { + xLocn = jButton.getLocationOnScreen().x; + yLocn = jButton.getLocationOnScreen().y; + width = jButton.getSize().width; + height = jButton.getSize().height; + }); + + robot.mouseMove(xLocn + width / 2, yLocn + height / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + SwingUtilities.invokeAndWait(() -> description = + jFileChooser.getAccessibleContext().getAccessibleDescription()); + + if (description != null) { + System.out.println( + "Accessibility Description " + "for JFileChooser is Set"); + } else { + throw new RuntimeException("Accessibility Description for" + + "JFileChooser is not Set"); + } + } finally { + SwingUtilities.invokeAndWait(() -> jFrame.dispose()); + } + } + + public static void main(String args[]) throws Exception { + doTest(); + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/accessibility/JScrollPaneAccessibleRelationsTest.java openjdk-17-17.0.6+10/test/jdk/javax/accessibility/JScrollPaneAccessibleRelationsTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/accessibility/JScrollPaneAccessibleRelationsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/accessibility/JScrollPaneAccessibleRelationsTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003, 2022, 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 4702690 + * @key headful + * @summary Make an automatic AccessibleRelation between + * JScrollBars and what they scroll (TP) + * @run main JScrollPaneAccessibleRelationsTest + */ +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.accessibility.AccessibleRelation; +import javax.swing.JFrame; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +public class JScrollPaneAccessibleRelationsTest +implements PropertyChangeListener { + + private static JFrame jFrame; + private static JScrollPane jScrollPane; + private static JScrollBar horizontalScrollBar; + private static JScrollBar verticalScrollBar; + + private static Object[] jScrollPaneTarget; + private static Object[] horizontalScrollBarTarget; + private static Object[] verticalScrollBarTarget; + + public static void createGUI() { + jFrame = new JFrame(); + + jScrollPane = new JScrollPane(); + horizontalScrollBar = jScrollPane.createHorizontalScrollBar(); + verticalScrollBar = jScrollPane.createVerticalScrollBar(); + jScrollPane.setHorizontalScrollBar(horizontalScrollBar); + jScrollPane.setVerticalScrollBar(verticalScrollBar); + + jFrame.getContentPane().add(jScrollPane); + } + + public static void doTest() throws Exception { + try { + SwingUtilities.invokeAndWait(() -> createGUI()); + + SwingUtilities.invokeAndWait(() -> jScrollPaneTarget = + jScrollPane.getAccessibleContext().getAccessibleRelationSet() + .get(AccessibleRelation.CONTROLLED_BY).getTarget()); + SwingUtilities.invokeAndWait( + () -> horizontalScrollBarTarget = horizontalScrollBar + .getAccessibleContext().getAccessibleRelationSet() + .get(AccessibleRelation.CONTROLLER_FOR).getTarget()); + SwingUtilities + .invokeAndWait(() -> verticalScrollBarTarget = verticalScrollBar + .getAccessibleContext().getAccessibleRelationSet() + .get(AccessibleRelation.CONTROLLER_FOR).getTarget()); + + if (!(jScrollPaneTarget[0] instanceof javax.swing.JScrollBar)) { + throw new RuntimeException("JScrollPane doesn't have " + + "JScrollBar as target for CONTROLLED_BY"); + } + if (!(jScrollPaneTarget[1] instanceof javax.swing.JScrollBar)) { + throw new RuntimeException("JScrollPane doesn't have " + + "JScrollBar as target for CONTROLLED_BY"); + } + if (!(horizontalScrollBarTarget[0] instanceof JScrollPane)) { + throw new RuntimeException("HorizontalScrollBar doesn't have " + + "JScrollPane as target for CONTROLLER_FOR"); + } + if (!(verticalScrollBarTarget[0] instanceof JScrollPane)) { + throw new RuntimeException("VerticalScrollBar doesn't have " + + "JScrollPane as target for CONTROLLER_FOR"); + } + } finally { + SwingUtilities.invokeAndWait(() -> jFrame.dispose()); + } + } + + public void propertyChange(PropertyChangeEvent e) { + if (!("AccessibleActiveDescendant".equals(e.getPropertyName()))) { + throw new RuntimeException( + "Active Descendant of JScrollBar has not changed"); + } + if (!("AccessibleSelection".equals(e.getPropertyName()))) { + throw new RuntimeException( + "Accessible Selection of JScrollBar has not changed"); + } + } + + public static void main(String[] args) throws Exception { + doTest(); + System.out.println("Test Passed."); + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java --- openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. 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 8065422 + * @summary Trailing dot in hostname causes TLS handshake to fail + * @library /javax/net/ssl/templates + * @run main/othervm --add-opens java.base/sun.security.ssl=ALL-UNNAMED + * -Djdk.net.hosts.file=hostsForExample EndingDotHostname + */ + +import javax.net.ssl.*; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class EndingDotHostname { + public static void main(String[] args) throws Exception { + System.setProperty("jdk.net.hosts.file", "hostsForExample"); + (new EndingDotHostname()).run(); + } + + public void run() throws Exception { + bootUp(); + } + + // ================================================= + // Stuffs to boot up the client-server mode testing. + private Thread serverThread = null; + private volatile Exception serverException = null; + private volatile Exception clientException = null; + + // Is the server ready to serve? + protected final CountDownLatch serverCondition = new CountDownLatch(1); + + // Is the client ready to handshake? + protected final CountDownLatch clientCondition = new CountDownLatch(1); + + // What's the server port? Use any free port by default + protected volatile int serverPort = 0; + + // Boot up the testing, used to drive remainder of the test. + private void bootUp() throws Exception { + Exception startException = null; + try { + startServer(); + startClient(); + } catch (Exception e) { + startException = e; + } + + // Wait for other side to close down. + if (serverThread != null) { + serverThread.join(); + } + + // The test is pretty much over. Which side threw an exception? + Exception local = clientException; + Exception remote = serverException; + + Exception exception = null; + + // Check various exception conditions. + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + // If there was an exception *AND* a startException, output it. + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + private void startServer() { + serverThread = new Thread(() -> { + try { + doServerSide(); + } catch (Exception e) { + // Our server thread just died. Release the client, + // if not active already... + serverException = e; + } + }); + + serverThread.start(); + } + + private void startClient() { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + + protected void doServerSide() throws Exception { + // kick off the server side service + SSLContext context = SSLExampleCert.createServerSSLContext(); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(); + sslServerSocket.bind(new InetSocketAddress( + InetAddress.getLoopbackAddress(), 0)); + serverPort = sslServerSocket.getLocalPort(); + + // Signal the client, the server is ready to accept connection. + serverCondition.countDown(); + + // Try to accept a connection in 30 seconds. + SSLSocket sslSocket; + try { + sslServerSocket.setSoTimeout(30000); + sslSocket = (SSLSocket)sslServerSocket.accept(); + } catch (SocketTimeoutException ste) { + // Ignore the test case if no connection within 30 seconds. + System.out.println( + "No incoming client connection in 30 seconds. " + + "Ignore in server side."); + return; + } finally { + sslServerSocket.close(); + } + + // handle the connection + try { + // Is it the expected client connection? + // + // Naughty test cases or third party routines may try to + // connection to this server port unintentionally. In + // order to mitigate the impact of unexpected client + // connections and avoid intermittent failure, it should + // be checked that the accepted connection is really linked + // to the expected client. + boolean clientIsReady = + clientCondition.await(30L, TimeUnit.SECONDS); + + if (clientIsReady) { + // Run the application in server side. + runServerApplication(sslSocket); + } else { // Otherwise, ignore + // We don't actually care about plain socket connections + // for TLS communication testing generally. Just ignore + // the test if the accepted connection is not linked to + // the expected client or the client connection timeout + // in 30 seconds. + System.out.println( + "The client is not the expected one or timeout. " + + "Ignore in server side."); + } + } finally { + sslSocket.close(); + } + } + + // Define the server side application of the test for the specified socket. + protected void runServerApplication(SSLSocket socket) throws Exception { + // here comes the test logic + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + } + + protected void doClientSide() throws Exception { + // Wait for server to get started. + // + // The server side takes care of the issue if the server cannot + // get started in 90 seconds. The client side would just ignore + // the test case if the serer is not ready. + boolean serverIsReady = + serverCondition.await(90L, TimeUnit.SECONDS); + if (!serverIsReady) { + System.out.println( + "The server is not ready yet in 90 seconds. " + + "Ignore in client side."); + return; + } + + SSLContext context = SSLExampleCert.createClientSSLContext(); + SSLSocketFactory sslsf = context.getSocketFactory(); + + try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket( + "www.example.com.", serverPort)) { + // OK, here the client and server get connected. + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslSocket.setSSLParameters(sslParameters); + + // Signal the server, the client is ready to communicate. + clientCondition.countDown(); + + // There is still a chance in theory that the server thread may + // wait client-ready timeout and then quit. The chance should + // be really rare so we don't consider it until it becomes a + // real problem. + + // Run the application in client side. + runClientApplication(sslSocket); + } + } + + // Define the client side application of the test for the specified socket. + protected void runClientApplication(SSLSocket socket) throws Exception { + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + } +} + diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java --- openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -26,7 +26,7 @@ /* * @test - * @bug 8211806 + * @bug 8211806 8277881 * @summary TLS 1.3 handshake server name indication is missing on a session resume * @run main/othervm ResumeTLS13withSNI */ @@ -338,6 +338,9 @@ // Get the legacy session length and skip that many bytes int sessIdLen = Byte.toUnsignedInt(resCliHello.get()); + if (sessIdLen == 0) { + throw new Exception("SessionID field empty"); + } resCliHello.position(resCliHello.position() + sessIdLen); // Skip over all the cipher suites diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/templates/SSLExampleCert.java openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/templates/SSLExampleCert.java --- openjdk-17-17.0.5+8/test/jdk/javax/net/ssl/templates/SSLExampleCert.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/net/ssl/templates/SSLExampleCert.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. 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.net.ssl.*; +import java.io.*; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.PKIXBuilderParameters; +import java.security.spec.PKCS8EncodedKeySpec; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Base64; +import java.util.Date; + +/** + * A template to use "www.example.com" as the server name. The caller should + * set a virtual hosts file with System Property, "jdk.net.hosts.file". This + * class will map the loopback address to "www.example.com", and write to + * the specified hosts file. + * + * Commands used: + * # Root CA + * > openssl req -new -config openssl.cnf -out root-ca.csr \ + * -keyout private/root-ca.key -days 7300 -newkey rsa:2048 + * > openssl ca -selfsign -config openssl.cnf -in root-ca.csr \ + * -out certs/root-ca.crt -extensions v3_ca + * -keyfile private/root-ca.key -days 7300 + * + * # www.example.com + * > openssl req -new -keyout private/example.key \ + * -out example.csr -days 7299 -newkey rsa:2048 + * > openssl ca -config openssl.cnf -in example.csr \ + * -out certs/example.crt -extensions usr_cert + * -keyfile private/root-ca.key -days 7299 + * + * # Client + * > openssl req -new -keyout private/client.key \ + * -out client.csr -days 7299 -newkey rsa:2048 + * > openssl ca -config openssl.cnf -in client.csr \ + * -out certs/client.crt -extensions usr_cert + * -keyfile private/root-ca.key -days 7299 + * + * The key files should be in PKCS8 format: + * > openssl pkcs8 -topk8 -inform PEM -outform pem \ + * -in private/example.key -out private/example-pkcs.key -nocrypt + */ +public enum SSLExampleCert { + // Version: 3 (0x2) + // Serial Number: 4097 (0x1001) + // Signature Algorithm: sha256WithRSAEncryption + // Issuer: C = US, ST = California, O = Example, OU = Test + // Validity + // Not Before: Feb 25 20:12:04 2022 GMT + // Not After : Feb 20 20:12:04 2042 GMT + // Subject: C = US, ST = California, O = Example, OU = Test + // Subject Public Key Info: + // Public Key Algorithm: rsaEncryption + // RSA Public-Key: (2048 bit) + CA_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDtDCCApygAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCVVMx + EzARBgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAoTB0V4YW1wbGUxDTALBgNVBAsT + BFRlc3QwHhcNMjIwMjI1MjAxMjA0WhcNNDIwMjIwMjAxMjA0WjBDMQswCQYDVQQG + EwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEQMA4GA1UEChMHRXhhbXBsZTENMAsG + A1UECxMEVGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKOGhEDj + lZ5R6o20kJdgrIRcY1he4qKLWQ4vU0thqAg4mEcKCZZn4/NL05UgJCFLwYaxMZZe + etb/WaTRvQpDDFh7AhsMR24m6zKKJVk9E/e/8ur7sGDIVq8hZOBTq85ZdxPj/zKW + wB1BR/RcY4DsGno1USlkV7TVeZc1qpJHTPImesevzH7zX8nhnFlf4TTQbpQt6RxU + cr+udWpMOyP9xMerIyp7jpPy79tIaGP2x7ryt2BB9FU4RwPk4DcdfOkmdS86md1c + GI9H5qM5rUzyqey0J8wMRLj+E0Vx0F1XELZeTtyulbIbhrBhu/KOXZG2zNIeK+2F + XxDlx9tD+bbcJfUCAwEAAaOBsTCBrjAdBgNVHQ4EFgQULjM9fwJnC3Tp1QYM8HNL + y60btl0wbAYDVR0jBGUwY4AULjM9fwJnC3Tp1QYM8HNLy60btl2hR6RFMEMxCzAJ + BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRAwDgYDVQQKEwdFeGFtcGxl + MQ0wCwYDVQQLEwRUZXN0ggIQATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE + AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAR0Mk+2X/rr4kYYfHsQUIsROwDZSQhQr3 + QOeLc7fyTjkM96OHXN2dKVoOcpzgKi1goHW7lh8vVmKRQk2wfFqRZV9/kQBFK/gz + QtN5gp+pA8Wk912Uj5gD0loiPcRf5bDElvLnr2iwt4VdKkvGIYa9Eu9CYbkf1x3t + ahVLmrZLBkqvKxo4MG4KGYXkqtII3M6clM4ScFa/0rR1nGZOgZyqG7AMMHc01csA + oLlEZx2hUcpJbz+sfCGUWYaF2uKJvuWMNFbGSDhfs8pOMGgelMOHaKVtgOEfEASN + TSqzqn0vzjJ78Mi6mN7/6L/onDKzROxClw0hc6L+PIhIHftD1ckvVQ== + -----END CERTIFICATE-----""", + + """ + MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIn/uWtEzLDK8CAggA + MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECIk7+JC4ErMDBIIEyA3yvNhMm/Oj + ZdkN0HSzPyLv9bOfUyyx4NA121kizZIq/FkUjn8pGxzU63rzMk2vU1hmp2/O3ymr + vmV7gzXRp4ULZCjFwn4cLxi9ieKgBOr9MmgTlRc1oZ9P/Y8eWhmjGxA2CU3fy7Kv + DyzftqAetV8YzTelk8xqxLrGevB16O3zDbFj4dcmG7a0i75kqlI8QyQklJ9uyE10 + SELWFlV6w+3GD82YrbR/8v4fE5KP/nAPbtN4h4C7MY3kJQL+apHr5B3Jst+6N62t + JzmxGS5z3ZVT3Bn3mxi8awo8/XS8s+ZOSnH6nHvz83NBUQwSkVbtujlg+yMD2jg4 + Nt3LWfLnF8Q6n4oAQ1ZP9KJyVIh8+PN12txIRoWq1pF74hJmbfVfiCSR/tMrw6lr + XqlkG1Mi7RmpTCz9ScTUBWY/dyScYFITenv/WE+UnfQ+DXBC+78lkmL36M0Rx/ip + S4O1Tgy/z/MIv1s+ZpAFsRRczlpo9lbVEMuSGEWWTIQJCRPFV8Y1NKHmWUgeZpl3 + 2YUjpHNyQt/a1s1h1g5w9+UNuABt/3cUUnlA7psueb6l4x6M92QFBOpe1xUDL51D + RpaipVl1luFWvE84hqgCIv8Kh9EbkAlclmK8CIOkMQAabk0GmhCfEdm+PCW61Cao + rfCMwZ9Bx6zAcXGRrvl0sK35z8C3r8wLftaS/5xF6RTJBy6XY2iiFW6D44qZDFbh + 0rWV8zDtCf2+OZtEvPkeUn3sjevDW78TM6F7HBjXAeIFrNyJGVe2CTlEJLoZi5pX + W1blhMJ93N1mLiDYisILANmJRBfGMt0tYE/pGcJRlkuqG0qylnqRojjL83CTQvFy + 46q/obR36enRDvCZPvQrX2dB7Vkgpkz/drZ6+avmKdQcTjY/ycCd3DclwexhgUoX + QDntZuJQLp7C4tFfHRy2uh4DOEjzMP6a/NQ3q7p6vc6BTNTFZRUAdyNwcEDIzSLM + nZSPFBiz+gukhtNSCO28kLc8OX1hYsSAMgzbImcMtAiQHG3bFAJ0cs0jF4U9VrJt + 4/97kiDBuCgGb2b5t0+uDqipE6G4B6494IGm5KoIPAPbXMJQstmuzjTJt95UTF+p + e60AnWIXcvEOouIIMzC7gH2g23St5Bo6NixfxcmVfkFa92TDlCTxEz5Z5mnma06k + Pao4Km1eJkYS/QaCDnCZs/yCAMhINUTTDd0/7Y9YE3Dmd5B1s2wOa+ovESSL3Mdv + dZoxh91QR+6hQuz3iYztC/BszMtATH8MznAoco0QFAhKi56Wppe+p1ATLWFMqk4W + elX9vtw5XLucKy5cMkQYh144SnrerlPJTAOGy0XXKunj8ceZfEN6zcS9Us9IN5aF + iENMFHjPsscrrKFhKypaMIn67PuIhVhw4PnGrWejr6TM1gUx+zOcRCwT+5ka2L7U + aqmgS8cDg5ZfAHcbig7No9kku/OSk+5QzkVKca2TZQHm++60oQTzRl3/NWiELO+e + Sl6r8i7dS0Kv3bB/AbLfIHtDgebxUh78qXMel/OUWd58ezxBS74rZ4AQTpYcdTbR + jKHploWi8h5yXYn/YdEZG1vW/zYseFNb7QKT5Cznucl8O/+lNZIOVw63Pq368dTD + tG1GZkIlwM+jlJjRew05YQ== + """), + + // Version: 3 (0x2) + // Serial Number: 4098 (0x1002) + // Signature Algorithm: sha256WithRSAEncryption + // Issuer: C = US, ST = California, O = Example, OU = Test + // Validity + // Not Before: Feb 25 20:31:29 2022 GMT + // Not After : Feb 19 20:31:29 2042 GMT + // Subject: C = US, ST = California, O = Example, OU = Test, CN = www.example.com + // Subject Public Key Info: + // Public Key Algorithm: rsaEncryption + // RSA Public-Key: (2048 bit) + SERVER_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDaTCCAlGgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCVVMx + EzARBgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAoTB0V4YW1wbGUxDTALBgNVBAsT + BFRlc3QwHhcNMjIwMjI1MjAzMTI5WhcNNDIwMjE5MjAzMTI5WjBdMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEQMA4GA1UECgwHRXhhbXBsZTENMAsG + A1UECwwEVGVzdDEYMBYGA1UEAwwPd3d3LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG + 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3crcRzecIV08Muh6kA0CuVKnPkU2bLC+6bpV + 7/iBZ4D3qMwO8Q02+gP71pPNoAQ1nsifxR4k9mBVYOjar35RVpuFmLRRVMargrxg + 4WWDfVgLMhOeCy8+Tl4Mp/yRL3nkr0MJd57RCOPcPE84J/1Crq1Luy2+hsXSj25L + VJKx2o6LE0tfwPWnufdNUHzHRuNoBR83OpqIT0uXH15THZS+0ZcQwrJMcKYe4JWl + 6oXWcsWbtTG+r7QLIRKck2IG7jjHFpE83Q6Iv2HkhctgGZofwSTZyMmJ8eClovva + WFLDaLL2WuI3NwZM//knjMyfsEWtWsILXayCn5NTT74ClQjWQQIDAQABo00wSzAJ + BgNVHRMEAjAAMB0GA1UdDgQWBBQ9nPjenO4PMLtMTBddNiIDsPywjzAfBgNVHSME + GDAWgBQuMz1/AmcLdOnVBgzwc0vLrRu2XTANBgkqhkiG9w0BAQsFAAOCAQEAVOvM + fMDOxOCkWB244cx7J+f2qZU6/1qGlJUiL0WRLRj1XEmB8AYSZEb6Os1suF8sotka + nA9Aw1SFA/wNyrSKazXNlOKo0In1mu/OjHU7n6XYVAyDmFGziYY8zTqG1h8ZPrI7 + oAkNgnNDwmwy7uCAvMj+Q4QQ0Q4YxTHV/i3X1HuEwThRgz9cJGdDRIAsimRHDSDO + 5hsIJo6VASz0ISrYMxNZQ1og+XktdNssPK616bPf+APwXXnsWSuGkIdGDU059DII + cTSsLTbWkTWDXAAQo+sfDZUrvqopCK000eoywEmPQrTf7O8oAQdRvTsyxwMvOONd + EWQ9pDW9+RC8l5DtRA== + -----END CERTIFICATE-----""", + + """ + MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDdytxHN5whXTwy + 6HqQDQK5Uqc+RTZssL7pulXv+IFngPeozA7xDTb6A/vWk82gBDWeyJ/FHiT2YFVg + 6NqvflFWm4WYtFFUxquCvGDhZYN9WAsyE54LLz5OXgyn/JEveeSvQwl3ntEI49w8 + Tzgn/UKurUu7Lb6GxdKPbktUkrHajosTS1/A9ae5901QfMdG42gFHzc6mohPS5cf + XlMdlL7RlxDCskxwph7glaXqhdZyxZu1Mb6vtAshEpyTYgbuOMcWkTzdDoi/YeSF + y2AZmh/BJNnIyYnx4KWi+9pYUsNosvZa4jc3Bkz/+SeMzJ+wRa1awgtdrIKfk1NP + vgKVCNZBAgMBAAECggEBAMUMAtJe7J6Tx/TuqF0swfvGHAHt2eGM0cCzpMATh1xe + rylPSgMNG4faXDcSj4AX3U+ZrKCjHHGruo7jsc5yqm8IsxOtOAjajOwU0vnNh5mn + zCKMXUBQk8lqM1JXyOFmKS8wnsug1NRSJIuMUjbtAf5QxlSg2oHAZUa61cBoqAyk + KXbw9uBYnM4n8WGXdax/LLPuonjnz2Sc35CC1LhRAF/K7oyjg7KvScnphIFRaLiU + X4tFH0nLpcao5de0fP5eUEkbUZ3hE6MEZvOsxn5CFkjH2VdtZ9D5dc3ArV3UMe26 + +3swdenriYZ73HNJDiLAdeIVh9IrGVxhH9UowF9psIUCgYEA/Ldlx4vTTlM7URFn + luqK7D8WH9x4JiCLEGxU80nJxxIgF8eqhOFzsQemytTrf4o1xAkyyPIweHzwApCA + lBdwC4Mc44DjoLFVdTET9hEq7E/UK81znc0mD4v8Hz2JI6h3f2sQrcEAPBvjBwtc + TpS9WlSBKSO3NOb3Hlucq7COVKcCgYEA4KyZ+dOyKVLyGjd0g22v4YW7VC016Hql + uQ7SN1vuI3zQMa2rZfEv5z2L7olJKrDFcmqk8W1tfElrMaSsuohm8khhx0lPtHMw + 4Su/tci/3rEUl+DPrQExdjrrDXCqpUunOAlMP9qElsNBGdkrQ6QlMnSVVi2v8Vf1 + f86Mey2UEtcCgYEAqcOlmqPigfZFnZLcjLPoOQW0HhkjmTE5WgH8GybRZmpVpsPZ + V8R/zEeAkzbvMFEvBw7Kz9RqHTaIoKBjz5fjC8i7ClVWFGesKbqbVyx3MiH6PKaa + aUIbtEvsRSw4SPztsWnB3YcOWlK9csj97Efc36Zu0a0NcHtLPFh8aZWEN3cCgYEA + oQFv8oWPlmeXkcwN1iWjtfT1EtS3XhuOaXjCkuNxW8MVG5S+UHawAoGrpsyBP3Og + e2cLPuxRWpDunYvKMH6Rb60JTRwvXzxxWdvVLbtoLHkwLcrwaKWDQZvlWCNWVtBJ + TDH1j4jUHYpdO93SUE3wTiEX58Mj48tJ5kYpjBhUlc8CgYEA7PG3ORGqZtfCiNmj + CxvPtQiFC+ogf+v8cMQtrKVTgpnI2pxzG+cSXYvL4cnyY2JnwqarWorUic8JU2e2 + EhW53PWUg7VpITlLsqOpATIDiviFAN4qOOxgDt5v0C1PyB3aXe2B5VA3IgczssyR + OLy7p/DhOpu2bqnpKyIkAuzZgFc= + """), + + + // Version: 3 (0x2) + // Serial Number: 4099 (0x1003) + // Signature Algorithm: sha256WithRSAEncryption + // Issuer: C = US, ST = California, O = Example, OU = Test + // Validity + // Not Before: Feb 25 20:33:59 2022 GMT + // Not After : Feb 19 20:33:59 2042 GMT + // Subject: C = US, ST = California, O = Example, OU = Test, CN = Do-Not-Reply + // Subject Public Key Info: + // Public Key Algorithm: rsaEncryption + // RSA Public-Key: (2048 bit) + CLIENT_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDZjCCAk6gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwQzELMAkGA1UEBhMCVVMx + EzARBgNVBAgTCkNhbGlmb3JuaWExEDAOBgNVBAoTB0V4YW1wbGUxDTALBgNVBAsT + BFRlc3QwHhcNMjIwMjI1MjAzMzU5WhcNNDIwMjE5MjAzMzU5WjBaMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEQMA4GA1UECgwHRXhhbXBsZTENMAsG + A1UECwwEVGVzdDEVMBMGA1UEAwwMRG8tTm90LVJlcGx5MIIBIjANBgkqhkiG9w0B + AQEFAAOCAQ8AMIIBCgKCAQEA2yJgm3Lthr+97vdEWTb4zaNuLTa/DkCXdmVNIQk9 + kVn2hjZrPc+JghBCaWpohGVTQ+zxplIJXk+QVZ0ePEimE7ahBClz4MlAgMpt1uxy + mYYUAsSZDCaFUI9Cpx1f0BiSWu330196K/AfRIoT+/SOZucnpbepxyrt+Az5SKrH + TJR/OSqeX4XKGPoRI96pKxDOV8pY5/I9h9yKGuxfufbpOdVODngVLcMKgBAkiD+2 + sguEHM+iGLx970+W6yycu1dFY1CAgWLUF3evUxe8avwePgx7lTFXnNueYt96Ny9v + L1o/WzoBe3z1mTl5Qb//3tYbXn8vdiDYm0dT8wImpDbpvwIDAQABo00wSzAJBgNV + HRMEAjAAMB0GA1UdDgQWBBSXqW/B1BVjNgowSwa3MBiHMkzp6zAfBgNVHSMEGDAW + gBQuMz1/AmcLdOnVBgzwc0vLrRu2XTANBgkqhkiG9w0BAQsFAAOCAQEABIMAjT5T + lZDV/1wmdKCyJQJ7WUjA44N5/yBGtEmpAJ0VM7/COnk8lqiYxrk50wK7lt0tiklX + 4aLqbAgnDc27z9AQGHOqB69dZprGQT9PsTByjK6i7KPGs30ygyND41j0rju/GM2e + 3xprZbusODENRyL196QV4ai0WVe1hEvv0wTMIcnXYmZHMP8ArdVRHWaDQF6zW0Mh + QbFqklt5W0ZIl2ZmC8z7z2Z6jv/BYyDo3U96LfdCWsEKxSKiX/PGHqZu4D3A4VSE + 0+fE7cX61kgRdGvZJgFjtYxtfkXd1HlyJ48Dqilzl+rvgvR5XA68zijjN0khPhml + wZhPIOCIaWMZYw== + -----END CERTIFICATE-----""", + + """ + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDbImCbcu2Gv73u + 90RZNvjNo24tNr8OQJd2ZU0hCT2RWfaGNms9z4mCEEJpamiEZVND7PGmUgleT5BV + nR48SKYTtqEEKXPgyUCAym3W7HKZhhQCxJkMJoVQj0KnHV/QGJJa7ffTX3or8B9E + ihP79I5m5yelt6nHKu34DPlIqsdMlH85Kp5fhcoY+hEj3qkrEM5Xyljn8j2H3Ioa + 7F+59uk51U4OeBUtwwqAECSIP7ayC4Qcz6IYvH3vT5brLJy7V0VjUICBYtQXd69T + F7xq/B4+DHuVMVec255i33o3L28vWj9bOgF7fPWZOXlBv//e1htefy92INibR1Pz + AiakNum/AgMBAAECggEAW0WxWW4AMyzwDnWdWU+FSBm3TUvNPkF3FNBS1NzFcSI4 + hWRrPJ6R1sOw9blleSe/C77IVA89abPYGWDM9C0KR5G89T/SzSDmJf6qy2dGwF1R + PmnmmWH+CzTwfSzF+KYTZ55QqBDPkTd9vo2Ij1woaAIFyId8RsHBxpyYxESlqGY4 + C6IzEqxFQ0obHXasNR+dP4iOWS4ONhxeUHixcrDHxbmoqmHt0WuJwXhlOjxHgr+i + lUPTe5y+Y2B1gVNYrN4KlDTJqJ6lu4n6MFQ46jhfddzTk3uiEOTVWK6nE8Cf0NM7 + djTzTcR8xAVpoY5XDlk0aBfEd8Np7TLSjV4vU3J04QKBgQD6scazH/H9Yu9ZbR7w + EeN/k7uDDlgahWg8/93syzdFtSNIRGvdalNMhTfM/zXaM/Cl63gvZilWxC+56Uvg + 6QC+rBUwzZrm7ryb6hT6Zyoo4w72bw3jGOJ3e2/bclSLrAcJnL/1Gq87J3CS16wl + NIHrlOlY8orToEdki+6HaagyEQKBgQDfxZz4Uqsa+jDO/rEm959+nz2RkaXYu1Ld + DhYONxmlw69/BbwzOvzr88qKNbd+b+oIK8kpm7Lvpc2/cuqItTFdehmw+tGhMWYo + XizKCeKeCByFTjXI2/PEPUHMy0D8M68Tx/Hq0NbIYqCyzkaamHhXpuJGftxGfd3/ + U0NB4WGOzwKBgQDgnyN7YfcwY1I0XUqoLk8aA2Oy5MpaUQh6B4RwZBENO2T2np/L + TzZ9zKuX2WAGOB26fMY+KhqGLNjaike7qOpK7eM6zC6sFmMWjGHpj0A+TFwewJi/ + z48zIX2zMbjBQQ05NqLkWdmCdi8u02HiIC78x3thgEiVn/n4BE1gNXJIEQKBgEdr + dfcXw36/vZZDWd07CU/LmUX9u3YaC498MHPnCCuM8lVTSkb7m7/fNpS4IlGbfJGR + EApUpF6yh6GEFvD9C71u/AYtd3zAHH/j1t3BG/AeXKP7W1U5RmsqtfacJKiaAlYI + 6eBtOTAJsop/Ja+v3DD1laC0Wq+w+orEU2ISgiWnAoGBAK9/9m3RCYPNYzS/PQ2B + AgE2FQRuY8FXxHegZo2tBBwIojPeVHO1OoThYVNgiQfW9k27dFkRwXVAtt6Jqgax + fvOby8rWRStXH2qHVyvHicceL7iXs6v2bX20Szsy44eMkoFfAImea6ZdErLdVWvI + fxlYpTIVpBt3Nu2BRJn28ili + """); + + final String keyAlgo; + final String certStr; + final String privateKeyStr; + + // Trusted certificate + private final static SSLExampleCert[] TRUSTED_CERTS = { + SSLExampleCert.CA_RSA + }; + + // Server certificate. + private final static SSLExampleCert[] SERVER_CERTS = { + SSLExampleCert.SERVER_EXAMPLE_RSA + }; + + // Client certificate. + private final static SSLExampleCert[] CLIENT_CERTS = { + SSLExampleCert.CLIENT_EXAMPLE_RSA + }; + + // Set "www.example.com" to loopback address. + static { + String hostsFileName = System.getProperty("jdk.net.hosts.file"); + String loopbackHostname = + InetAddress.getLoopbackAddress().getHostAddress() + + " " + "www.example.com www.example.com.\n"; + try (FileWriter writer= new FileWriter(hostsFileName, false)) { + writer.write(loopbackHostname); + } catch (IOException ioe) { + // ignore + } + } + + SSLExampleCert(String keyAlgo, String certStr, String privateKeyStr) { + this.keyAlgo = keyAlgo; + this.certStr = certStr; + this.privateKeyStr = privateKeyStr; + } + + public static SSLContext createClientSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, CLIENT_CERTS); + } + + public static SSLContext createServerSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, SERVER_CERTS); + } + + private static SSLContext createSSLContext( + SSLExampleCert[] trustedCerts, + SSLExampleCert[] endEntityCerts) throws Exception { + char[] passphrase = "passphrase".toCharArray(); + + // Generate certificate from cert string. + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // Import the trusted certs. + KeyStore ts = null; // trust store + if (trustedCerts != null && trustedCerts.length != 0) { + ts = KeyStore.getInstance("PKCS12"); + ts.load(null, null); + + Certificate[] trustedCert = new Certificate[trustedCerts.length]; + for (int i = 0; i < trustedCerts.length; i++) { + try (ByteArrayInputStream is = new ByteArrayInputStream( + trustedCerts[i].certStr.getBytes())) { + trustedCert[i] = cf.generateCertificate(is); + } + + ts.setCertificateEntry("trusted-cert-" + + trustedCerts[i].name(), trustedCert[i]); + } + } + + // Import the key materials. + KeyStore ks = null; // trust store + if (endEntityCerts != null && endEntityCerts.length != 0) { + ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + + for (SSLExampleCert endEntityCert : endEntityCerts) { + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder() + .decode(endEntityCert.privateKeyStr)); + KeyFactory kf = + KeyFactory.getInstance( + endEntityCert.keyAlgo); + PrivateKey priKey = kf.generatePrivate(priKeySpec); + + // generate certificate chain + Certificate keyCert; + try (ByteArrayInputStream is = new ByteArrayInputStream( + endEntityCert.certStr.getBytes())) { + keyCert = cf.generateCertificate(is); + } + + Certificate[] chain = new Certificate[]{keyCert}; + + // import the key entry. + ks.setKeyEntry("end-entity-cert-" + + endEntityCert.name(), + priKey, passphrase, chain); + } + } + + // Set the date for the verifying of certificates. + DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); + Date verifyingDate = df.parse("02/02/2023"); + + // Create an SSLContext object. + TrustManagerFactory tmf = + TrustManagerFactory.getInstance("PKIX"); + if (ts != null) { + PKIXBuilderParameters pkixParams = + new PKIXBuilderParameters(ts, null); + pkixParams.setDate(verifyingDate); + pkixParams.setRevocationEnabled(false); + ManagerFactoryParameters managerFactoryParameters = + new CertPathTrustManagerParameters(pkixParams); + tmf.init(managerFactoryParameters); + } else { + tmf.init((KeyStore)null); + } + + SSLContext context = SSLContext.getInstance("TLS"); + if (endEntityCerts != null && endEntityCerts.length != 0) { + KeyManagerFactory kmf = + KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + KeyManager[] kms = kmf.getKeyManagers(); + if (kms != null && kms.length != 0) { + KeyManager km = kms[0]; + Field verificationDateField = + km.getClass().getDeclaredField("verificationDate"); + verificationDateField.setAccessible(true); + verificationDateField.set(km, verifyingDate); + } + + context.init(kms, tmf.getTrustManagers(), null); + } else { + context.init(null, tmf.getTrustManagers(), null); + } + + return context; + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/security/auth/login/modules/SafeLogout.java openjdk-17-17.0.6+10/test/jdk/javax/security/auth/login/modules/SafeLogout.java --- openjdk-17-17.0.5+8/test/jdk/javax/security/auth/login/modules/SafeLogout.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/security/auth/login/modules/SafeLogout.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022, 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.security.auth.Subject; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.Configuration; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; +import java.util.*; + +import static javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag.*; + +/* + * @test + * @bug 8282730 + * @key randomness + * @summary Check that all LoginModule implementations don't throw NPE + * from logout method after login failure + * @modules jdk.security.auth + * java.management + */ +public class SafeLogout { + + static Random r = new Random(); + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 100; i++) { + test(i); + } + } + + static void test(int pos) throws Exception { + // The content of the principals and credentials sets depends on + // combinations of (possibly multiple) login modules configurations, + // and it is difficult to find only a "typical" subset to test on, + // Therefore we use a random number to choose login module names, + // flag for each, and whether to perform a login at the beginning. + // Each config is printed out so that any failure can be reproduced. + boolean login = r.nextBoolean(); + Map empty = Collections.emptyMap(); + AppConfigurationEntry[] result = new AppConfigurationEntry[r.nextInt(4) + 1]; + for (int i = 0; i < result.length; i++) { + result[i] = new AppConfigurationEntry(randomModule(), randomControl(), empty); + } + + System.out.println(pos + " " + login); + Arrays.stream(result) + .forEach(a -> System.out.println(a.getLoginModuleName() + ":" + a.getControlFlag())); + + LoginContext lc = new LoginContext("a", new Subject(), null, new Configuration() { + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) { + return result; + } + }); + + try { + if (login) { + lc.login(); + } + } catch (LoginException e) { + // Don't care + } finally { + try { + lc.logout(); + } catch (LoginException le) { + if (!le.getMessage().contains("all modules ignored")) { + throw le; + } + } + } + } + + static AppConfigurationEntry.LoginModuleControlFlag[] allControls = { + REQUIRED, + REQUISITE, + SUFFICIENT, + OPTIONAL + }; + + static AppConfigurationEntry.LoginModuleControlFlag randomControl() { + return allControls[r.nextInt(allControls.length)]; + } + + static String[] allModules = { + "com.sun.security.auth.module.Krb5LoginModule", + "com.sun.security.auth.module.UnixLoginModule", + "com.sun.security.auth.module.JndiLoginModule", + "com.sun.security.auth.module.KeyStoreLoginModule", + "com.sun.security.auth.module.NTLoginModule", + "com.sun.security.auth.module.LdapLoginModule", + "com.sun.jmx.remote.security.FileLoginModule" + }; + + static String randomModule() { + return allModules[r.nextInt(allModules.length)]; + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/ClosedReceiver.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/ClosedReceiver.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/ClosedReceiver.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/ClosedReceiver.java 2023-01-10 13:21:55.000000000 +0000 @@ -32,6 +32,7 @@ /** * @test + * @key sound * @bug 4616517 * @summary Receiver.send() does not work properly */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/InitializationHang.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/InitializationHang.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/InitializationHang.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/InitializationHang.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 8068412 */ public final class InitializationHang { diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiDeviceGetReceivers.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiDeviceGetReceivers.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiDeviceGetReceivers.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiDeviceGetReceivers.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 4931387 * @summary Add methods to MidiDevice to get list of Transmitters and Receivers */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiIO.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiIO.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiIO.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiIO.java 2023-01-10 13:21:55.000000000 +0000 @@ -27,6 +27,7 @@ /** * @test + * @key sound * @bug 4356787 * @summary MIDI device I/O is not working */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/MidiOutGetMicrosecondPositionBug.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 4903786 * @summary MIDI OUT does not implement getMicrosecondPosition() consistently */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/OpenClose.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/OpenClose.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/OpenClose.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/OpenClose.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 4616517 * @summary Receiver.send() does not work properly. Tests open/close behaviour * of MidiDevices. For this test, it is essential that the MidiDevice diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/ReceiverTransmitterAvailable.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 4616517 * @summary Receiver.send() does not work properly */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/Reopen.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/Reopen.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Devices/Reopen.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Devices/Reopen.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 4914667 * @summary Closing and reopening MIDI IN device on Linux throws * MidiUnavailableException diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/MidiSystem/DefaultDevices.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/MidiSystem/DefaultDevices.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/MidiSystem/DefaultDevices.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/MidiSystem/DefaultDevices.java 2023-01-10 13:21:55.000000000 +0000 @@ -39,6 +39,7 @@ * @bug 4776511 * @bug 4934509 * @bug 4938236 + * @key sound * @modules java.desktop/com.sun.media.sound * @run main/timeout=600 DefaultDevices * @summary RFE: Setting the default MixerProvider diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/MidiSystem/GetSequencer.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/MidiSystem/GetSequencer.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/MidiSystem/GetSequencer.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/MidiSystem/GetSequencer.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4931400 * @summary Clarify default connections in default sequencer */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequence/GetMicrosecondLength.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequence/GetMicrosecondLength.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequence/GetMicrosecondLength.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequence/GetMicrosecondLength.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4929955 * @summary Sequence.getMicrosecondLength() returns wrong value */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/LoopIAE.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/LoopIAE.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/LoopIAE.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/LoopIAE.java 2023-01-10 13:21:55.000000000 +0000 @@ -32,6 +32,7 @@ /** * @test + * @key sound * @bug 5025549 * @summary Verify that setLoopEndPoint throws IAE */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/MetaCallback.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/MetaCallback.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/MetaCallback.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/MetaCallback.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -31,13 +31,16 @@ import javax.sound.midi.Sequencer; import javax.sound.midi.ShortMessage; import javax.sound.midi.Track; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * @test * @bug 4347135 * @summary MIDI MetaMessage callback inconsistent - * @key intermittent - * @run main/othervm MetaCallback + * @key intermittent sound + * @run main/othervm/timeout=120 MetaCallback */ public class MetaCallback implements MetaEventListener { @@ -59,11 +62,15 @@ public static int TOTAL_COUNT = 100; - int metaCount = 0; - boolean finished = false; + volatile int metaCount = 0; + volatile boolean finished = false; + // On M1 Mac sometimes system notifies listener about the same message twice + static List received = Collections.synchronizedList(new ArrayList<>()); + long startTimeMs; MetaCallback() throws Exception { + startTimeMs = System.currentTimeMillis(); sequencer=MidiSystem.getSequencer(); sequence=new Sequence(Sequence.PPQ,240); track=sequence.createTrack(); @@ -101,13 +108,28 @@ } } void start() {sequencer.start();} - void stop() {sequencer.stop();} + void stop() { + sequencer.stop(); + sequencer.close(); + } public void meta(MetaMessage msg) { System.out.println(""+metaCount+": got "+msg); if (msg.getType() == 0x2F) { finished = true; } else if (msg.getData().length > 0 && msg.getType() == 1) { + if (!received.contains(msg)) { + received.add(msg); + } else { + // Add some additional debug output for the case of duplicate meta message + // The test will fail anyway at the end + System.out.println("Duplicate message received after getting " + + received.size() + " messages."); + System.out.println("Sequencer in use: " + sequencer); + System.out.println("Time from test start: " + + (System.currentTimeMillis() - startTimeMs) + "ms"); + Thread.dumpStack(); + } metaCount++; } } diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/Recording.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/Recording.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/Recording.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/Recording.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,7 +34,7 @@ /** * @test * @bug 4932841 - * @key intermittent + * @key intermittent sound * @summary Sequencer's recording feature does not work */ public class Recording { diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqRecordDoesNotCopy.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 5048381 * @summary Sequencer doesn't create distinct messages when recording events. */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqRecordsRealTimeEvents.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 5048381 * @summary Sequencer records real time messages into the sequence */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqStartRecording.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqStartRecording.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SeqStartRecording.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SeqStartRecording.java 2023-01-10 13:21:55.000000000 +0000 @@ -27,6 +27,7 @@ /** * @test + * @key sound * @bug 5001943 * @summary Sequencer.startRecording throws unexpected NPE */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerCacheValues.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerCacheValues.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerCacheValues.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerCacheValues.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 4716740 * @summary default sequencer does not set the tempo factor */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerImplicitSynthOpen.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,6 +23,7 @@ /** * @test + * @key sound * @bug 6660470 * @summary Tests that sequencer correctly opens/closes (implicitly) devices * @author Alex Menkov diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerSetMuteSolo.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4713900 * @summary default Sequencer allows to set Mute for invalid track */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerState.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerState.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SequencerState.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SequencerState.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ /** * @test + * @key sound * @bug 4913027 * @summary several Sequencer methods should specify behaviour on closed Sequencer */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SetTickPosition.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SetTickPosition.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/SetTickPosition.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/SetTickPosition.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,8 +30,9 @@ /** * @test + * @key sound * @bug 4493775 - * @summary Sequncer method, setTickPosition(long) doesnot set the Tick position + * @summary Sequencer method, setTickPosition(long) does not set the Tick position */ public class SetTickPosition { private static boolean testPassed = true; diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/TickLength.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/TickLength.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Sequencer/TickLength.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Sequencer/TickLength.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4427890 * @run main/othervm TickLength * @summary Sequencer.getTickLength() and Sequence.getTickLength() report the diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Soundbanks/ExtraCharInSoundbank.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4429762 * @summary Some instrument names in some soundbanks include bad extra characters */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Synthesizer/Receiver/bug6186488.java openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Synthesizer/Receiver/bug6186488.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/midi/Synthesizer/Receiver/bug6186488.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/midi/Synthesizer/Receiver/bug6186488.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -21,52 +21,183 @@ * questions. */ +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiMessage; import javax.sound.midi.MidiSystem; +import javax.sound.midi.MidiUnavailableException; +import javax.swing.JDialog; +import javax.swing.SwingUtilities; +import javax.swing.JTextArea; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.Timer; +import javax.swing.JPanel; +import javax.swing.WindowConstants; -/** +/* * @test * @bug 6186488 * @summary Tests that software Java Syntesizer processed * non-ShortMessage-derived messages - * @run main/manual=yesno bug6186488 + * @run main/manual bug6186488 */ public class bug6186488 { - public static void main(String[] args) throws Exception { - MidiDevice/*Synthesizer*/ synth = null; + private static final CountDownLatch countDownLatch = new CountDownLatch(1); + private static final int testTimeout = 300000; + private static volatile String testFailureMsg; + private static volatile boolean testPassed; + private static volatile boolean testFinished; + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(() -> createAndShowTestDialog()); try { - synth = MidiSystem.getSynthesizer(); - //synth = MidiSystem.getMidiDevice(infos[0]); + if (!countDownLatch.await(testTimeout, TimeUnit.MILLISECONDS)) { + throw new RuntimeException(String.format("Test timeout '%d ms' elapsed.", testTimeout)); + } + if (!testPassed) { + String failureMsg = testFailureMsg; + if ((failureMsg != null) && (!failureMsg.trim().isEmpty())) { + throw new RuntimeException(failureMsg); + } else { + throw new RuntimeException("Test failed."); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException(ie); + } finally { + testFinished = true; + } + } + private static void pass() { + testPassed = true; + countDownLatch.countDown(); + } + + private static void fail(String failureMsg) { + testFailureMsg = failureMsg; + testPassed = false; + countDownLatch.countDown(); + } + + private static String convertMillisToTimeStr(int millis) { + if (millis < 0) { + return "00:00:00"; + } + int hours = millis / 3600000; + int minutes = (millis - hours * 3600000) / 60000; + int seconds = (millis - hours * 3600000 - minutes * 60000) / 1000; + return String.format("%02d:%02d:%02d", hours, minutes, seconds); + } + + private static void createAndShowTestDialog() { + String testInstruction = "This test verify that software Java Syntesizer processed non-ShortMessage-derived messages.\n" + + "Close all other programs that may use the sound card.\n" + + "Make sure that the speakers are connected and the volume is up.\n" + + "Click on 'Start Test' button. If you listen a sound then test pass else test fail."; + + final JDialog dialog = new JDialog(); + dialog.setTitle("Test Sound"); + dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + dialog.dispose(); + fail("Main dialog was closed."); + } + }); + + final JLabel testTimeoutLabel = new JLabel(String.format("Test timeout: %s", convertMillisToTimeStr(testTimeout))); + final long startTime = System.currentTimeMillis(); + final Timer timer = new Timer(0, null); + timer.setDelay(1000); + timer.addActionListener((e) -> { + int leftTime = testTimeout - (int) (System.currentTimeMillis() - startTime); + if ((leftTime < 0) || testFinished) { + timer.stop(); + dialog.dispose(); + } + testTimeoutLabel.setText(String.format("Test timeout: %s", convertMillisToTimeStr(leftTime))); + }); + timer.start(); + + JTextArea textArea = new JTextArea(testInstruction); + textArea.setEditable(false); + + final JButton startTestButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + final JButton failButton = new JButton("FAIL"); + startTestButton.addActionListener((e) -> { + new Thread(() -> { + try { + doTest(); + + SwingUtilities.invokeLater(() -> { + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + } catch (Throwable t) { + t.printStackTrace(); + dialog.dispose(); + fail("Exception occurred in a thread executing the test."); + } + }).start(); + }); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail("Expected that sound will be heard but did not hear sound"); + }); + + JPanel mainPanel = new JPanel(new BorderLayout()); + JPanel labelPanel = new JPanel(new FlowLayout()); + labelPanel.add(testTimeoutLabel); + mainPanel.add(labelPanel, BorderLayout.NORTH); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(startTestButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + } + + public static void waitForSynToOpen(MidiDevice synth) throws InterruptedException { + int count = 0; + do { + if (synth.isOpen()) { + System.out.println("synth is opened"); + return; + } + TimeUnit.SECONDS.sleep(1); + } while( ++count >= 5); + throw new RuntimeException(synth + " did not open even after 5 seconds"); + } + + private static void doTest() throws MidiUnavailableException, InterruptedException { + try (MidiDevice synth = MidiSystem.getSynthesizer()) { System.out.println("Synthesizer: " + synth.getDeviceInfo()); synth.open(); + waitForSynToOpen(synth); MidiMessage msg = new GenericMidiMessage(0x90, 0x3C, 0x40); - //ShortMessage msg = new ShortMessage(); - //msg.setMessage(0x90, 0x3C, 0x40); - synth.getReceiver().send(msg, 0); Thread.sleep(2000); - - } catch (Exception ex) { - ex.printStackTrace(); - throw ex; - } finally { - if (synth != null && synth.isOpen()) - synth.close(); - } - System.out.print("Did you heard a note? (enter 'y' or 'n') "); - int result = System.in.read(); - System.in.skip(1000); - if (result == 'y' || result == 'Y') - { - System.out.println("Test passed sucessfully."); - } - else - { - System.out.println("Test FAILED."); - throw new RuntimeException("Test failed."); } } diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/AudioSystem/DefaultMixers.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/AudioSystem/DefaultMixers.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/AudioSystem/DefaultMixers.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/AudioSystem/DefaultMixers.java 2023-01-10 13:21:55.000000000 +0000 @@ -38,6 +38,7 @@ /** * @test + * @key sound * @bug 4776511 * @summary RFE: Setting the default MixerProvider. Test the retrieving of lines * with defaut mixer properties. diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/ClipCloseLoss.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/ClipCloseLoss.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/ClipCloseLoss.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/ClipCloseLoss.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4946913 8178403 * @summary DirectClip doesn't kill the thread correctly, sometimes * @run main/othervm ClipCloseLoss diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/ClipFlushCrash.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/ClipFlushCrash.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/ClipFlushCrash.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/ClipFlushCrash.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4946945 * @summary Crash in javasound while running TicTacToe demo applet tiger b26 */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Drain/ClipDrain.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Drain/ClipDrain.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Drain/ClipDrain.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Drain/ClipDrain.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 4732218 * @summary Clip.drain does not actually block until all I/O is complete as * documented. diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Duration/ClipDuration.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Duration/ClipDuration.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Duration/ClipDuration.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Duration/ClipDuration.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4237703 * @summary Check that Clip.getMicrosecondLength() returns correct value. */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Clip/Endpoint/ClipSetEndPoint.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4385928 * @summary Verify that an endpoint -1 in Clip does not throw an exception */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Controls/FloatControl/FloatControlBug.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ /** * @test + * @key sound * @bug 4385654 * @summary Check that the MASTER_GAIN control has a valid precision */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/DataLine_ArrayIndexOutOfBounds.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/DataLine_ArrayIndexOutOfBounds.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/DataLine_ArrayIndexOutOfBounds.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/DataLine_ArrayIndexOutOfBounds.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,6 +23,7 @@ /** * @test + * @key sound * @bug 7088367 * @summary SourceDataLine.write and TargetDataLine.read don't throw ArrayIndexOutOfBoundsException * @author Alex Menkov diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/DataLineInfoNegBufferSize.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 5021234 * @summary Using -2 for buffer size will fail retrieval of lines */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/LineDefFormat.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/LineDefFormat.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/DataLine/LineDefFormat.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/DataLine/LineDefFormat.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 5053380 * @summary Verify that getting a line initializes it with the format in * DataLine.Info diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/16and32KHz/Has16and32KHz.java 2023-01-10 13:21:55.000000000 +0000 @@ -32,6 +32,7 @@ /** * @test + * @key sound * @bug 4479441 * @summary Verify that the lines report 16KHz and 32KHz capability */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/BufferSizeCheck.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/BufferSizeCheck.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/BufferSizeCheck.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/BufferSizeCheck.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4661602 * @summary Buffersize is checked when re-opening line */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ChangingBuffer.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ChangingBuffer.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ChangingBuffer.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ChangingBuffer.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4515126 * @summary Verify that the buffer passed to SourceDataLine.write() and * Clip.open() will not be changed diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ClickInPlay/Test4218609.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 4218609 * @summary A soft audio click is heard when playing some audio file * @build ClickInPlay diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ClipOpenException.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ClipOpenException.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/ClipOpenException.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/ClipOpenException.java 2023-01-10 13:21:55.000000000 +0000 @@ -33,6 +33,7 @@ /** * @test + * @key sound * @bug 4679187 * @summary Clip.open() throws unexpected Exceptions. verifies that clip, * sourcedataline and targetdataline throw IllegalArgumentExcepotion if diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/FrameSize/FrameSizeTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 4469409 * @summary Check that the frame size in the formats returned by lines is * correct diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/SDLwrite.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/SDLwrite.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/SDLwrite.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/SDLwrite.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4680710 * @summary SourceDataLine.write() behavior is not correct for not open or not * started lines diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/SourceDataLineDefaultBufferSizeCrash.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4681384 * @summary SourceDataLine.write() causes Unexpected Signal 11 in native code * outside the VM diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/StopStart.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/StopStart.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Lines/StopStart.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Lines/StopStart.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ /** * @test + * @key sound * @bug 4828556 * @summary stopping and starting sampled audio plays small chunk in infinite * loop diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxBlock/PlaySine.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxBlock/PlaySine.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxBlock/PlaySine.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxBlock/PlaySine.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ /** * @test + * @key sound * @bug 4834461 * @summary Applet hang when you load it during sound card is in use * @run main/manual PlaySine diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash2.java 2023-01-10 13:21:55.000000000 +0000 @@ -36,6 +36,7 @@ /** * @test + * @key sound * @bug 4498848 * @summary Sound causes crashes on Linux (part 3) */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/ClipLinuxCrash.java 2023-01-10 13:21:55.000000000 +0000 @@ -34,6 +34,7 @@ /** * @test + * @key sound * @bug 4498848 * @summary Sound causes crashes on Linux (part 1) */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/LinuxCrash/SDLLinuxCrash.java 2023-01-10 13:21:55.000000000 +0000 @@ -32,6 +32,7 @@ /** * @test + * @key sound * @bug 4498848 * @summary Sound causes crashes on Linux (part 2) */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/BogusMixers.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/BogusMixers.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/BogusMixers.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/BogusMixers.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 4667064 * @summary Java Sound provides bogus SourceDataLine and TargetDataLine */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/BothEndiansAndSigns.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/BothEndiansAndSigns.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/BothEndiansAndSigns.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/BothEndiansAndSigns.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 4936397 * @summary Verify that there'll for a given endianness, there's also the little * endian version diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/DirectSoundRepeatingBuffer/Test4997635.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 4997635 * @summary Win: SourceDataLine playback loops endlessly unless you manually * stop() diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/DirectSoundUnderrunSilence/Test5032020.java 2023-01-10 13:21:55.000000000 +0000 @@ -31,6 +31,7 @@ /** * @test + * @key sound * @bug 5032020 * @summary Win: Direct Audio is silent after underrun * @build DirectSoundUnderrunSilence diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/NoSimpleInputDevice.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/NoSimpleInputDevice.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/NoSimpleInputDevice.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/NoSimpleInputDevice.java 2023-01-10 13:21:55.000000000 +0000 @@ -26,6 +26,7 @@ /** * @test + * @key sound * @bug 4936397 * @summary Verify that there'll be either SimpleInputDevice OR DirectAudioDevice */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/PhantomMixers.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/PhantomMixers.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/PhantomMixers.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/PhantomMixers.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4794104 * @summary mixers are always present, independent of available soundcards * @run main/manual PhantomMixers diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/PlugHwMonoAnd8bitAvailable.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 5013897 * @summary Verify that plughw: provides mono and 8-bit lines */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/UnexpectedIAE.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/UnexpectedIAE.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Mixers/UnexpectedIAE.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Mixers/UnexpectedIAE.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,6 +28,7 @@ /** * @test + * @key sound * @bug 4964288 * @summary Unexpected IAE raised while getting TargetDataLine */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Recording/TargetDataLineFlush.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Recording/TargetDataLineFlush.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/Recording/TargetDataLineFlush.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/Recording/TargetDataLineFlush.java 2023-01-10 13:21:55.000000000 +0000 @@ -30,6 +30,7 @@ /** * @test + * @key sound * @bug 4836433 * @summary Windows: TargetDataLine.flush() does not work. Since this test has * some real-time variance, I disabled it by making it a manual test. diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/spi/MixerProvider/ExpectedNPEOnNull.java openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/spi/MixerProvider/ExpectedNPEOnNull.java --- openjdk-17-17.0.5+8/test/jdk/javax/sound/sampled/spi/MixerProvider/ExpectedNPEOnNull.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/sound/sampled/spi/MixerProvider/ExpectedNPEOnNull.java 2023-01-10 13:21:55.000000000 +0000 @@ -29,6 +29,7 @@ /** * @test + * @key sound * @bug 8135100 * @author Sergey Bylokhov */ diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2022, 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.event.KeyEvent; +import java.awt.Robot; +import java.util.Arrays; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import static java.util.stream.Collectors.toList; + +/* + * @test + * @key headful + * @requires (os.family == "windows") + * @bug 4659800 + * @summary Check whether pressing key generates + * ActionEvent on focused Button or not. This is applicable only for + * WindowsLookAndFeel and WindowsClassicLookAndFeel. + * @run main EnterKeyActivatesButton + */ +public class EnterKeyActivatesButton { + private static volatile boolean buttonPressed; + private static JFrame frame; + + public static void main(String[] s) throws Exception { + runTest(); + } + + private static void setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported L&F: " + lafName); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private static void createUI() { + frame = new JFrame(); + JPanel panel = new JPanel(); + JButton focusedButton = new JButton("Button1"); + focusedButton.addActionListener(e -> buttonPressed = true); + panel.add(focusedButton); + panel.add(new JButton("Button2")); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + focusedButton.requestFocusInWindow(); + } + + public static void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + // Consider only Windows and Windows Classic LnFs. + List winlafs = Arrays.stream(UIManager.getInstalledLookAndFeels()) + .filter(laf -> laf.getName().startsWith("Windows")) + .map(laf -> laf.getClassName()) + .collect(toList()); + + for (String laf : winlafs) { + try { + buttonPressed = false; + System.out.println("Testing L&F: " + laf); + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createUI(); + }); + + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + + if (buttonPressed) { + System.out.println("Test Passed for L&F: " + laf); + } else { + throw new RuntimeException("Test Failed, button not pressed for L&F: " + laf); + } + + } finally { + SwingUtilities.invokeAndWait(EnterKeyActivatesButton::disposeFrame); + } + } + + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JEditorPane/4666101/JEditorPaneNavigationTest.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JEditorPane/4666101/JEditorPaneNavigationTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JEditorPane/4666101/JEditorPaneNavigationTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JEditorPane/4666101/JEditorPaneNavigationTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2002, 2022, 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.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import javax.imageio.ImageIO; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.UnsupportedLookAndFeelException; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/* + * @test + * @key headful + * @bug 4666101 + * @summary Verifies that in a JEditorPane, the down arrow is honoured after you + add text on a line preceding a blank line. + * @run main JEditorPaneNavigationTest + */ +public class JEditorPaneNavigationTest { + + private static volatile int caretPos; + private static JEditorPane jep; + private static JFrame frame; + private static Robot robot; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + List lafs = Arrays.stream(getInstalledLookAndFeels()) + .map(LookAndFeelInfo::getClassName) + .collect(Collectors.toList()); + for (final String laf : lafs) { + try { + AtomicBoolean lafSetSuccess = new AtomicBoolean(false); + SwingUtilities.invokeAndWait(() -> { + lafSetSuccess.set(setLookAndFeel(laf)); + if (lafSetSuccess.get()) { + createUI(); + } + }); + if (!lafSetSuccess.get()) { + continue; + } + robot.waitForIdle(); + + AtomicReference pt = new AtomicReference<>(); + SwingUtilities.invokeAndWait(() -> pt.set(jep.getLocationOnScreen())); + caretPos = 0; + final Point jEditorLoc = pt.get(); + + // Click on JEditorPane + robot.mouseMove(jEditorLoc.x + 50, jEditorLoc.y + 50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + keyType(KeyEvent.VK_ENTER); + keyType(KeyEvent.VK_ENTER); + + typeSomeText(); + + keyType(KeyEvent.VK_UP); + keyType(KeyEvent.VK_UP); + + typeSomeText(); + + keyType(KeyEvent.VK_DOWN); + + System.out.println(" test1 caret pos = " + caretPos); + + // Check whether the caret position is at the expected value 5 + if (caretPos != 5) { + captureScreen(); + throw new RuntimeException("Test Failed in " + laf + + " expected initial caret position is 5, but actual is " + caretPos); + } + + keyType(KeyEvent.VK_DOWN); + + System.out.println(" test2 caret pos = " + caretPos); + + // Check whether the caret position is at the expected value 10 + if (caretPos != 10) { + captureScreen(); + throw new RuntimeException("Test Failed in " + laf + + " expected final caret position is 10, but actual is " + caretPos); + } + + System.out.println("Test Passed in " + laf); + + } finally { + SwingUtilities.invokeAndWait(JEditorPaneNavigationTest::disposeFrame); + } + } + } + + private static void captureScreen() { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + try { + ImageIO.write( + robot.createScreenCapture(new Rectangle(0, 0, screenSize.width, screenSize.height)), + "png", + new File("JEditorPaneNavigationTest.png") + ); + } catch (IOException ignore) { + } + } + + private static void typeSomeText() { + keyType(KeyEvent.VK_T); + keyType(KeyEvent.VK_E); + keyType(KeyEvent.VK_X); + keyType(KeyEvent.VK_T); + } + + private static void keyType(int keyCode) { + robot.keyPress(keyCode); + robot.keyRelease(keyCode); + } + + + private static void createUI() { + frame = new JFrame(); + jep = new JEditorPane(); + jep.setPreferredSize(new Dimension(100, 100)); + jep.addCaretListener(e -> caretPos = jep.getCaretPosition()); + jep.setEditable(true); + JPanel panel = new JPanel(); + panel.add(jep); + frame.add(panel); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + + private static boolean setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported laf : " + lafName); + return false; + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + return true; + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JMenu/4515762/bug4515762.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JMenu/4515762/bug4515762.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JMenu/4515762/bug4515762.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JMenu/4515762/bug4515762.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, 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 @@ -21,9 +21,15 @@ * questions. */ -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; /** * @test @@ -37,8 +43,8 @@ */ public class bug4515762 { - private static volatile boolean actionExpected = false; - private static volatile boolean actionRecieved = false; + private static volatile boolean actionExpected; + private static volatile boolean actionRecieved; private static JFrame frame; /** @@ -99,18 +105,18 @@ return menuItem; } - public static void checkAction() { + public static void checkAction(String str) { if (actionRecieved == true) { actionRecieved = false; } else { - throw new RuntimeException("Action has not been received"); + throw new RuntimeException("Action has not been received: " + str); } } public static void main(String[] args) throws Throwable { try { Robot robot = new Robot(); - robot.setAutoDelay(250); + robot.setAutoDelay(100); SwingUtilities.invokeAndWait(new Runnable() { @@ -119,6 +125,7 @@ frame = new JFrame("Test"); frame.setJMenuBar(createMenuBar()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocationRelativeTo(null); frame.pack(); frame.setVisible(true); frame.toFront(); @@ -126,6 +133,7 @@ }); robot.waitForIdle(); + robot.delay(1000); Util.hitMnemonics(robot, KeyEvent.VK_D); robot.waitForIdle(); @@ -133,7 +141,9 @@ // Press the S key many times (should not cause an action peformed) int TIMES = 5; for (int i = 0; i < TIMES; i++) { - Util.hitKeys(robot, KeyEvent.VK_S); + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + robot.waitForIdle(); } robot.waitForIdle(); @@ -146,7 +156,7 @@ robot.keyRelease(KeyEvent.VK_S); robot.waitForIdle(); - checkAction(); + checkAction("pressing VK_S"); Util.hitMnemonics(robot, KeyEvent.VK_U); robot.waitForIdle(); @@ -155,28 +165,31 @@ robot.keyRelease(KeyEvent.VK_M); robot.waitForIdle(); - checkAction(); + checkAction("pressing VK_M"); Util.hitMnemonics(robot, KeyEvent.VK_U); robot.waitForIdle(); - Util.hitKeys(robot, KeyEvent.VK_T); + robot.keyPress(KeyEvent.VK_T); + robot.keyRelease(KeyEvent.VK_T); robot.waitForIdle(); - checkAction(); + checkAction("pressing VK_T"); Util.hitMnemonics(robot, KeyEvent.VK_U); robot.waitForIdle(); - Util.hitKeys(robot, KeyEvent.VK_W); + robot.keyPress(KeyEvent.VK_W); + robot.keyRelease(KeyEvent.VK_W); robot.waitForIdle(); - checkAction(); + checkAction("pressing VK_W"); Util.hitMnemonics(robot, KeyEvent.VK_U); robot.waitForIdle(); - Util.hitKeys(robot, KeyEvent.VK_U); + robot.keyPress(KeyEvent.VK_U); + robot.keyRelease(KeyEvent.VK_U); robot.waitForIdle(); - checkAction(); + checkAction("pressing VK_U"); } finally { if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose()); } diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JPopupMenu/JPopupMenuFocusStealTest.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JPopupMenu/JPopupMenuFocusStealTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JPopupMenu/JPopupMenuFocusStealTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JPopupMenu/JPopupMenuFocusStealTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2002, 2022, 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.BorderLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.UnsupportedLookAndFeelException; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/* + * @test + * @key headful + * @bug 4632782 + * @summary This test checks CCC #4632782, which verifies that showing a + * JPopupMenu shouldn't steal the focus out of current focused component. + * @run main JPopupMenuFocusStealTest + */ +public class JPopupMenuFocusStealTest { + private static JPopupMenu popupMenu; + private static JComboBox comboBox; + private static JFrame frame; + private static Robot robot; + private static JLabel label; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(200); + robot.setAutoWaitForIdle(true); + + List lafs = Arrays.stream(getInstalledLookAndFeels()) + .map(LookAndFeelInfo::getClassName) + .collect(Collectors.toList()); + for (final String laf : lafs) { + AtomicBoolean lafSetSuccess = new AtomicBoolean(false); + SwingUtilities.invokeAndWait(() -> { + lafSetSuccess.set(setLookAndFeel(laf)); + if (lafSetSuccess.get()) { + createUI(); + } + }); + if (!lafSetSuccess.get()) { + continue; + } + robot.waitForIdle(); + + // Bring the mouse pointer to label + mouseClick(label); + // Get the Popup menu by Mouse Button 3 click + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + hitKeys(KeyEvent.VK_DOWN, KeyEvent.VK_DOWN, KeyEvent.VK_ENTER); + final AtomicBoolean isFocusOwner = new AtomicBoolean(false); + SwingUtilities.invokeAndWait( + () -> isFocusOwner.set(comboBox.isFocusOwner())); + SwingUtilities + .invokeAndWait(JPopupMenuFocusStealTest::disposeFrame); + if (isFocusOwner.get()) { + System.out.println("Test Passed for " + laf); + } else { + throw new RuntimeException("Test Failed for " + laf); + } + } + } + + private static void createUI() { + frame = new JFrame(); + frame.setTitle("Popup Menu Application"); + JPanel topPanel = new JPanel(new BorderLayout()); + Object[] array = {"Item1", "Item2", "Item3"}; + comboBox = new JComboBox(array); + label = new JLabel("Check focus transfer from Combo to Popupmenu"); + topPanel.add(comboBox, BorderLayout.NORTH); + topPanel.add(label, BorderLayout.CENTER); + frame.getContentPane().add(topPanel); + + // Create some menu items for the popup + popupMenu = new JPopupMenu("Menu"); + popupMenu.add(new JMenuItem("New")); + popupMenu.add(new JMenuItem("Open...")); + popupMenu.add(new JMenuItem("Save")); + popupMenu.add(new JMenuItem("Save As...")); + popupMenu.add(new JMenuItem("Exit")); + + topPanel.addMouseListener(new PopupMenuEventListener()); + popupMenu.setFocusable(false); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + } + + private static void mouseClick(JComponent jComponent) throws Exception { + final AtomicReference loc = new AtomicReference<>(); + SwingUtilities + .invokeAndWait(() -> loc.set(jComponent.getLocationOnScreen())); + final Point location = loc.get(); + robot.mouseMove(location.x + 15, location.y + 5); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + private static void hitKeys(int... keys) { + for (int key : keys) { + robot.keyPress(key); + } + for (int i = keys.length - 1; i >= 0; i--) { + robot.keyRelease(keys[i]); + } + } + + private static boolean setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported L&F: " + lafName); + return false; + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + return true; + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private static class PopupMenuEventListener extends MouseAdapter { + public void mousePressed(MouseEvent me) { + if (me.isPopupTrigger()) { + popupMenu.show(me.getComponent(), me.getX(), me.getY()); + } + } + + } + +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2022, 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.ComponentOrientation; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerDateModel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/* + * @test + * @key headful + * @bug 4515999 + * @summary Check whether incrementing dates via the keyboard (up/down) gives + * the same results as using mouse press on the arrow buttons in a JSpinner. + * @run main JSpinnerMouseAndKeyPressTest + */ +public class JSpinnerMouseAndKeyPressTest { + // 2 days in milliseconds + private static final int EXPECTED_VALUE_2_DAYS = 2 * 24 * 60 * 60 * 1000; + + private static JFrame frame; + private static JSpinner spinner; + private static volatile Point spinnerUpButtonCenter; + private static volatile Point spinnerDownButtonCenter; + private static volatile Date spinnerValue; + + public static void main(String[] s) throws Exception { + runTest(); + } + + private static void setLookAndFeel(final String laf) { + try { + UIManager.setLookAndFeel(laf); + System.out.println("LookAndFeel: " + laf); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void createUI() { + frame = new JFrame(); + JPanel panel = new JPanel(); + spinner = new JSpinner(); + spinner.setModel(new DateModel()); + JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "dd/MM/yy"); + spinner.setEditor(editor); + spinner.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + panel.add(spinner); + frame.add(panel); + frame.setUndecorated(true); + frame.pack(); + frame.setAlwaysOnTop(true); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + + public static void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + List lafs = Arrays.stream(getInstalledLookAndFeels()) + .map(UIManager.LookAndFeelInfo::getClassName) + .collect(Collectors.toList()); + for (final String laf : lafs) { + try { + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createUI(); + }); + + SwingUtilities.invokeAndWait(() -> { + Point loc = spinner.getLocationOnScreen(); + int editorWidth = spinner.getEditor().getWidth(); + int buttonWidth = spinner.getWidth() - editorWidth; + int quarterHeight = spinner.getHeight() / 4; + + spinnerUpButtonCenter = new Point(loc.x + editorWidth + + (buttonWidth / 2), + loc.y + quarterHeight); + spinnerDownButtonCenter = new Point(spinnerUpButtonCenter.x, + loc.y + (3 * quarterHeight)); + }); + + // Mouse press use-case + // Move Mouse pointer to UP button center and click it + robot.mouseMove(spinnerUpButtonCenter.x, spinnerUpButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + updateSpinnerValue(); + long upValue = spinnerValue.getTime(); + + // Move Mouse pointer to DOWN button center and click it + robot.mouseMove(spinnerDownButtonCenter.x, spinnerDownButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + updateSpinnerValue(); + long downValue = spinnerValue.getTime(); + + long mouseIncrement = upValue - downValue; + + // Key press use-case + // Up Key press + robot.keyPress(KeyEvent.VK_UP); + robot.keyRelease(KeyEvent.VK_UP); + + updateSpinnerValue(); + upValue = spinnerValue.getTime(); + + // Down Key press + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + + updateSpinnerValue(); + downValue = spinnerValue.getTime(); + + long keyIncrement = upValue - downValue; + + if ((keyIncrement == EXPECTED_VALUE_2_DAYS) && + (mouseIncrement == EXPECTED_VALUE_2_DAYS)) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("Test failed because keyIncrement: " + + keyIncrement + " and mouseIncrement: " + + mouseIncrement + " should match with the expected value " + + EXPECTED_VALUE_2_DAYS + " for LnF " + laf); + } + + } finally { + SwingUtilities.invokeAndWait(JSpinnerMouseAndKeyPressTest::disposeFrame); + } + } + } + + private static void updateSpinnerValue() throws Exception { + SwingUtilities.invokeAndWait(() -> spinnerValue = (Date) spinner.getValue()); + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private static class DateModel extends SpinnerDateModel { + + private final Calendar cal = Calendar.getInstance(); + + @Override + public Object getNextValue() { + cal.setTime(getDate()); + cal.add(Calendar.DAY_OF_MONTH, 2); // Increment two days + return cal.getTime(); + } + + @Override + public Object getPreviousValue() { + cal.setTime(getDate()); + cal.add(Calendar.DAY_OF_MONTH, -2); // Decrement two days + return cal.getTime(); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2002, 2022, 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 + * @key headful + * @bug 4516019 + * @summary Verify that clicking on the increment/decrement buttons + * of the spinner gives focus to the spinner. + * @run main JSpinnerFocusTest + */ + +import java.awt.BorderLayout; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.JSpinner.DefaultEditor; +import javax.swing.SwingUtilities; + +public class JSpinnerFocusTest { + + JFrame jFrame; + JButton jButton; + JSpinner jSpinner; + Robot robot; + + volatile Rectangle bounds; + volatile boolean jTextFieldFocusStatus = false; + + private void createGUI() { + jFrame = new JFrame(); + jButton = new JButton(); + jSpinner = new JSpinner(); + + jFrame.setLayout(new BorderLayout()); + jFrame.add(jButton, BorderLayout.NORTH); + jFrame.add(jSpinner, BorderLayout.CENTER); + jFrame.setLocationRelativeTo(null); + jFrame.setSize(300, 300); + jFrame.setVisible(true); + } + + public void doTest() throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(400); + + SwingUtilities.invokeAndWait(() -> createGUI()); + + robot.waitForIdle(); + runTest(); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTextFieldFocusStatus = ((DefaultEditor) jSpinner.getEditor()) + .getTextField().isFocusOwner(); + }); + if (!jTextFieldFocusStatus) { + throw new RuntimeException( + "Clicking on JSpinner buttons did not" + + " shift focus to the JSpinner"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jFrame != null) { + jFrame.dispose(); + } + }); + } + } + + private void runTest() throws Exception { + SwingUtilities.invokeAndWait(() -> { + bounds = new Rectangle(jSpinner.getLocationOnScreen(), + jSpinner.getSize()); + }); + + // Move cursor to place it in the spinner editor + robot.mouseMove(bounds.x + bounds.width / 2, + bounds.y + bounds.height / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + // Move cursor to click spinner up arrow button + robot.mouseMove(bounds.x + bounds.width - 2, + bounds.y + bounds.height / 4); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public static void main(String[] args) throws Exception { + new JSpinnerFocusTest().doTest(); + System.out.println("Test Passed"); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JTabbedPane/TestBackgroundScrollPolicy.java 2023-01-10 13:21:55.000000000 +0000 @@ -36,7 +36,7 @@ * @key headful * @bug 8172269 8244557 * @summary Tests JTabbedPane background for SCROLL_TAB_LAYOUT - * @run main TestBackgroundScrollPolicy + * @run main/othervm -Dsun.java2d.uiScale=1 TestBackgroundScrollPolicy */ public class TestBackgroundScrollPolicy { diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/JTree/6263446/bug6263446.java openjdk-17-17.0.6+10/test/jdk/javax/swing/JTree/6263446/bug6263446.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/JTree/6263446/bug6263446.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/JTree/6263446/bug6263446.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2022, 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 @@ -38,7 +38,7 @@ public class bug6263446 { - private static final String FIRST = "AAAAAAAAAAA"; + private static final String FIRST = "AAAAA"; private static final String SECOND = "BB"; private static final String ALL = FIRST + " " + SECOND; private static JTree tree; @@ -62,46 +62,59 @@ try { Point point = getClickPoint(); robot.mouseMove(point.x, point.y); + robot.waitForIdle(); // click count 3 click(1); + robot.waitForIdle(); assertNotEditing(); click(2); + robot.waitForIdle(); assertNotEditing(); click(3); + robot.waitForIdle(); assertEditing(); cancelCellEditing(); assertNotEditing(); click(4); + robot.waitForIdle(); checkSelectedText(FIRST); click(5); + robot.waitForIdle(); checkSelectedText(ALL); // click count 4 setClickCountToStart(4); + robot.waitForIdle(); click(1); + robot.waitForIdle(); assertNotEditing(); click(2); + robot.waitForIdle(); assertNotEditing(); click(3); + robot.waitForIdle(); assertNotEditing(); click(4); + robot.waitForIdle(); assertEditing(); cancelCellEditing(); assertNotEditing(); click(5); + robot.waitForIdle(); checkSelectedText(FIRST); click(6); + robot.waitForIdle(); checkSelectedText(ALL); // start path editing @@ -109,12 +122,15 @@ assertEditing(); click(1); + robot.waitForIdle(); checkSelection(null); click(2); + robot.waitForIdle(); checkSelection(FIRST); click(3); + robot.waitForIdle(); checkSelection(ALL); } finally { if (frame != null) { @@ -128,7 +144,6 @@ for (int i = 0; i < times; i++) { robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(); } } @@ -141,7 +156,7 @@ public void run() { Rectangle rect = tree.getRowBounds(0); // UPDATE !!! - Point p = new Point(rect.x + rect.width / 2, rect.y + 2); + Point p = new Point(rect.x + rect.width/2, rect.y + rect.height/2); SwingUtilities.convertPointToScreen(p, tree); result[0] = p; @@ -166,9 +181,11 @@ frame.getContentPane().add(tree); + frame.setAlwaysOnTop(true); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); + frame.toFront(); } private static void setClickCountToStart(final int clicks) throws Exception { @@ -183,6 +200,7 @@ field.setAccessible(true); DefaultCellEditor ce = (DefaultCellEditor) field.get(editor); ce.setClickCountToStart(clicks); + } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (NoSuchFieldException e) { @@ -248,7 +266,9 @@ private static void checkSelectedText(String sel) throws Exception { assertEditing(); checkSelection(sel); + robot.waitForIdle(); cancelCellEditing(); + robot.waitForIdle(); assertNotEditing(); } diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/plaf/nimbus/NimbusJTreeSelTextColor.java openjdk-17-17.0.6+10/test/jdk/javax/swing/plaf/nimbus/NimbusJTreeSelTextColor.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/plaf/nimbus/NimbusJTreeSelTextColor.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/plaf/nimbus/NimbusJTreeSelTextColor.java 2023-01-10 13:21:55.000000000 +0000 @@ -22,140 +22,130 @@ */ /* * @test - * @bug 8266510 8271315 - * @summary Verifies Nimbus JTree default tree cell renderer use selected text color - * @run main/manual NimbusJTreeSelTextColor + * @bug 8266510 8271315 8273043 + * @summary Verifies Nimbus JTree default tree cell renderer uses selected text color + * @requires os.family != "mac" + * @run main/othervm -Dawt.useSystemAAFontSettings=off NimbusJTreeSelTextColor */ -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; + import java.awt.Color; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.GridBagConstraints; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import javax.swing.JButton; -import javax.swing.JComponent; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.SwingUtilities; -import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.UIManager; +import javax.swing.tree.DefaultTreeCellRenderer; + +import static java.awt.image.BufferedImage.TYPE_INT_RGB; public class NimbusJTreeSelTextColor { - private static JFrame frame; - private static JTree tree; - private static DefaultTreeCellRenderer treeCellRenderer; - private static volatile CountDownLatch countDownLatch; - private static volatile boolean testResult; - - private static final String INSTRUCTIONS = "INSTRUCTIONS:\n\n" - + "Verify selected text color is same as selected tree leaf icon color.\n " - + "If the color is same ie, white\n" - + "then press Pass otherwise press Fail."; + private static int iconOffset; + private static Color foregroundColor; + private static Color backgroundColor; + + private static volatile Exception testFailed; + + private static final String FILENAME = "image.png"; - public static void main(String args[]) throws Exception{ - countDownLatch = new CountDownLatch(1); + public static void main(String[] args) throws Exception { + final boolean showFrame = args.length >= 1 && args[0].equals("-show"); - SwingUtilities.invokeAndWait(NimbusJTreeSelTextColor::createUI); - countDownLatch.await(5, TimeUnit.MINUTES); + // Disable text antialiasing + System.setProperty("awt.useSystemAAFontSettings", "off"); - if (!testResult) { - throw new RuntimeException("Selected text color not same as selected tree leaf icon color!"); + SwingUtilities.invokeAndWait(() -> runTest(showFrame)); + + if (testFailed != null) { + throw testFailed; } } - private static void createUI() { + private static void runTest(final boolean showFrame) { try { UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception e) { throw new RuntimeException(e); } - JFrame mainFrame = new JFrame(); - GridBagLayout layout = new GridBagLayout(); - JPanel mainControlPanel = new JPanel(layout); - JPanel resultButtonPanel = new JPanel(layout); - - GridBagConstraints gbc = new GridBagConstraints(); - - gbc.gridx = 0; - gbc.gridy = 0; - gbc.insets = new Insets(5, 15, 5, 15); - gbc.fill = GridBagConstraints.HORIZONTAL; - mainControlPanel.add(createComponent(), gbc); - - JTextArea instructionTextArea = new JTextArea(); - instructionTextArea.setText(INSTRUCTIONS); - instructionTextArea.setEditable(false); - instructionTextArea.setBackground(Color.white); - - gbc.gridx = 0; - gbc.gridy = 1; - gbc.fill = GridBagConstraints.HORIZONTAL; - mainControlPanel.add(instructionTextArea, gbc); - - JButton passButton = new JButton("Pass"); - passButton.setActionCommand("Pass"); - passButton.addActionListener((ActionEvent e) -> { - testResult = true; - mainFrame.dispose(); - countDownLatch.countDown(); - - }); - - JButton failButton = new JButton("Fail"); - failButton.setActionCommand("Fail"); - failButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - mainFrame.dispose(); - countDownLatch.countDown(); - } - }); - - gbc.gridx = 0; - gbc.gridy = 0; + final JTree tree = createTree(); + Dimension size = tree.getPreferredSize(); + tree.setSize(size); + + BufferedImage im = new BufferedImage(size.width, size.height, + TYPE_INT_RGB); + Graphics g = im.getGraphics(); + tree.paint(g); + g.dispose(); - resultButtonPanel.add(passButton, gbc); - gbc.gridx = 1; - gbc.gridy = 0; - resultButtonPanel.add(failButton, gbc); - - gbc.gridx = 0; - gbc.gridy = 2; - mainControlPanel.add(resultButtonPanel, gbc); + if (showFrame) { + showFrame(tree); + } - mainFrame.add(mainControlPanel); - mainFrame.pack(); + size.height /= 4; // height of one row + size.width -= iconOffset; + size.width -= 2; // crop selection border on the right + checkColors(im, iconOffset, size.height / 2, size.width); + } - mainFrame.addWindowListener(new WindowAdapter() { + private static void showFrame(final JTree tree) { + JFrame frame = new JFrame("Nimbus Tree selected color"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + frame.getContentPane().add(tree); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } - @Override - public void windowClosing(WindowEvent e) { - mainFrame.dispose(); - countDownLatch.countDown(); + private static void checkColors(final BufferedImage image, + final int iconOffset, + final int y, + final int width) { + final int foreground = foregroundColor.getRGB(); + final int background = backgroundColor.getRGB(); + + for (int x = iconOffset; x < width; x++) { + int rgb = image.getRGB(x, y); + if (rgb != foreground && rgb != background) { + testFailed = new RuntimeException( + "Unexpected color found: " + Integer.toHexString(rgb) + + " at (" + x + ", " + y + ");" + + " foreground: " + Integer.toHexString(foreground) + ";" + + " background: " + Integer.toHexString(background) + + " - check " + FILENAME); + save(image); } - }); - mainFrame.setLocationRelativeTo(null); - mainFrame.setVisible(true); + } } - private static JComponent createComponent() { - tree = new JTree(); + private static JTree createTree() { + DefaultTreeCellRenderer cellRenderer = new DefaultTreeCellRenderer(); + iconOffset = cellRenderer.getOpenIcon().getIconWidth() + + cellRenderer.getIconTextGap(); + foregroundColor = (Color) UIManager.get("Tree.selectionForeground"); + backgroundColor = (Color) UIManager.get("Tree.selectionBackground"); - treeCellRenderer = new DefaultTreeCellRenderer(); + JTree tree = new JTree(); tree.setRootVisible(true); - tree.setShowsRootHandles(true); - - tree.setCellRenderer(treeCellRenderer); - tree.setSelectionRow(1); + tree.setShowsRootHandles(false); + tree.setCellRenderer(cellRenderer); + tree.setSelectionRow(0); return tree; } -} + private static void save(final BufferedImage img) { + try { + ImageIO.write(img, "png", new File(FILENAME)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff -Nru openjdk-17-17.0.5+8/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java openjdk-17-17.0.6+10/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java --- openjdk-17-17.0.5+8/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/javax/swing/plaf/synth/SynthButtonUI/6276188/bug6276188.java 2023-01-10 13:21:55.000000000 +0000 @@ -28,7 +28,7 @@ * @build Util * @author Romain Guy * @summary Tests PRESSED and MOUSE_OVER and FOCUSED state for buttons with Synth. - * @run main bug6276188 + * @run main/othervm -Dsun.java2d.uiScale=1 bug6276188 */ import java.awt.*; import java.awt.image.*; diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/cgroup/TestCgroupSubsystemFactory.java openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/cgroup/TestCgroupSubsystemFactory.java --- openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/cgroup/TestCgroupSubsystemFactory.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/cgroup/TestCgroupSubsystemFactory.java 2023-01-10 13:21:55.000000000 +0000 @@ -51,7 +51,7 @@ /* * @test - * @bug 8287107 8287073 + * @bug 8287107 8287073 8293540 * @key cgroups * @requires os.family == "linux" * @modules java.base/jdk.internal.platform @@ -72,8 +72,8 @@ private Path cgroupv1CgInfoNonZeroHierarchy; private Path cgroupv1MntInfoNonZeroHierarchy; private Path cgroupv1MntInfoSystemdOnly; - private Path cgroupv1MntInfoDoubleCpusets; - private Path cgroupv1MntInfoDoubleCpusets2; + private Path cgroupv1MntInfoDoubleControllers; + private Path cgroupv1MntInfoDoubleControllers2; private Path cgroupv1MntInfoColonsHierarchy; private Path cgroupv1SelfCgroup; private Path cgroupv1SelfColons; @@ -194,9 +194,13 @@ private String mntInfoCgroupsV1SystemdOnly = "35 26 0:26 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd\n" + "26 18 0:19 / /sys/fs/cgroup rw,relatime - tmpfs none rw,size=4k,mode=755\n"; - private String mntInfoCgroupv1MoreCpusetLine = "121 32 0:37 / /cpuset rw,relatime shared:69 - cgroup none rw,cpuset\n"; - private String mntInfoCgroupsV1DoubleCpuset = mntInfoHybrid + mntInfoCgroupv1MoreCpusetLine; - private String mntInfoCgroupsV1DoubleCpuset2 = mntInfoCgroupv1MoreCpusetLine + mntInfoHybrid; + private String mntInfoCgroupv1MoreControllers = "121 32 0:37 / /cpuset rw,relatime shared:69 - cgroup none rw,cpuset\n" + + "35 30 0:31 / /cgroup-in/memory rw,nosuid,nodev,noexec,relatime shared:7 - cgroup none rw,seclabel,memory\n" + + "36 30 0:32 / /cgroup-in/pids rw,nosuid,nodev,noexec,relatime shared:8 - cgroup none rw,seclabel,pids\n" + + "40 30 0:36 / /cgroup-in/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:12 - cgroup none rw,seclabel,cpu,cpuacct\n" + + "40 30 0:36 / /cgroup-in/blkio rw,nosuid,nodev,noexec,relatime shared:12 - cgroup none rw,seclabel,blkio\n"; + private String mntInfoCgroupsV1DoubleControllers = mntInfoHybrid + mntInfoCgroupv1MoreControllers; + private String mntInfoCgroupsV1DoubleControllers2 = mntInfoCgroupv1MoreControllers + mntInfoHybrid; private String cgroupv1SelfCgroupContent = "11:memory:/user.slice/user-1000.slice/user@1000.service\n" + "10:hugetlb:/\n" + "9:cpuset:/\n" + @@ -275,11 +279,11 @@ cgroupv1MntInfoSystemdOnly = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv1_systemd_only"); Files.writeString(cgroupv1MntInfoSystemdOnly, mntInfoCgroupsV1SystemdOnly); - cgroupv1MntInfoDoubleCpusets = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv1_double_cpuset"); - Files.writeString(cgroupv1MntInfoDoubleCpusets, mntInfoCgroupsV1DoubleCpuset); + cgroupv1MntInfoDoubleControllers = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv1_double_controllers"); + Files.writeString(cgroupv1MntInfoDoubleControllers, mntInfoCgroupsV1DoubleControllers); - cgroupv1MntInfoDoubleCpusets2 = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv1_double_cpuset2"); - Files.writeString(cgroupv1MntInfoDoubleCpusets2, mntInfoCgroupsV1DoubleCpuset2); + cgroupv1MntInfoDoubleControllers2 = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv1_double_controllers2"); + Files.writeString(cgroupv1MntInfoDoubleControllers2, mntInfoCgroupsV1DoubleControllers2); cgroupv1CgroupsJoinControllers = Paths.get(existingDirectory.toString(), "cgroups_cgv1_join_controllers"); Files.writeString(cgroupv1CgroupsJoinControllers, cgroupsNonZeroJoinControllers); @@ -390,11 +394,11 @@ @Test public void testCgroupv1MultipleCpusetMounts() throws IOException { - doMultipleCpusetMountsTest(cgroupv1MntInfoDoubleCpusets); - doMultipleCpusetMountsTest(cgroupv1MntInfoDoubleCpusets2); + doMultipleMountsTest(cgroupv1MntInfoDoubleControllers); + doMultipleMountsTest(cgroupv1MntInfoDoubleControllers2); } - private void doMultipleCpusetMountsTest(Path info) throws IOException { + private void doMultipleMountsTest(Path info) throws IOException { String cgroups = cgroupv1CgInfoNonZeroHierarchy.toString(); String mountInfo = info.toString(); String selfCgroup = cgroupv1SelfCgroup.toString(); @@ -406,6 +410,13 @@ CgroupInfo cpuSetInfo = res.getInfos().get("cpuset"); assertEquals("/sys/fs/cgroup/cpuset", cpuSetInfo.getMountPoint()); assertEquals("/", cpuSetInfo.getMountRoot()); + // Ensure controllers at /sys/fs/cgroup will be used + String[] ctrlNames = new String[] { "memory", "cpu", "cpuacct", "blkio", "pids" }; + for (int i = 0; i < ctrlNames.length; i++) { + CgroupInfo cinfo = res.getInfos().get(ctrlNames[i]); + assertTrue(cinfo.getMountPoint().startsWith("/sys/fs/cgroup/")); + assertEquals("/", cinfo.getMountRoot()); + } } @Test diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerBasic.java openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerBasic.java --- openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerBasic.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerBasic.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * 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 8293540 + * @summary Verify that -XshowSettings:system works + * @key cgroups + * @requires docker.support + * @library /test/lib + * @run main/timeout=360 TestDockerBasic + */ + +import jdk.test.lib.Utils; +import jdk.test.lib.containers.docker.Common; +import jdk.test.lib.containers.docker.DockerRunOptions; +import jdk.test.lib.containers.docker.DockerTestUtils; + +public class TestDockerBasic { + private static final String imageName = Common.imageName("javaDockerBasic"); + + public static void main(String[] args) throws Exception { + if (!DockerTestUtils.canTestDocker()) { + return; + } + + DockerTestUtils.buildJdkContainerImage(imageName); + + try { + testXshowSettingsSystem(true); + testXshowSettingsSystem(false); + } finally { + DockerTestUtils.removeDockerImage(imageName); + } + } + + private static void testXshowSettingsSystem(boolean addCgroupMounts) throws Exception { + String testMsg = (addCgroupMounts ? " with " : " without ") + " additional cgroup FS mounts in /cgroup-in"; + Common.logNewTestCase("Test TestDockerBasic " + testMsg); + DockerRunOptions opts = + new DockerRunOptions(imageName, "/jdk/bin/java", "-version"); + opts.addJavaOpts("-esa"); + opts.addJavaOpts("-XshowSettings:system"); + opts.addDockerOpts("--memory", "300m"); + if (addCgroupMounts) { + // Extra cgroup mount should be ignored by product code + opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroup-in:ro"); + } + DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0) + .shouldNotContain("AssertionError") + .shouldContain("Memory Limit: 300.00M"); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerCpuMetrics.java openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerCpuMetrics.java --- openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerCpuMetrics.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerCpuMetrics.java 2023-01-10 13:21:55.000000000 +0000 @@ -65,11 +65,13 @@ testCpuSet((((numCpus - 1) / 2) + 1) + "-" + (numCpus - 1)); } testCpuSet(IntStream.range(0, numCpus).mapToObj(a -> Integer.toString(a)).collect(Collectors.joining(","))); + testCpuSet("0", true /* additional cgroup fs mount */); testCpuQuota(50 * 1000, 100 * 1000); testCpuQuota(100 * 1000, 100 * 1000); testCpuQuota(150 * 1000, 100 * 1000); testCpuQuota(400 * 1000, 100 * 1000); + testCpuQuota(200 * 1000, 100 * 1000, true /* additional cgroup fs mount */); testCpuShares(256); testCpuShares(2048); @@ -108,10 +110,18 @@ } private static void testCpuSet(String value) throws Exception { + testCpuSet(value, false); + } + + private static void testCpuSet(String value, boolean addCgroupMount) throws Exception { Common.logNewTestCase("testCpuSet, value = " + value); DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester"); opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/"); + if (addCgroupMount) { + // Extra cgroup mount should be ignored by product code + opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroup-in:ro"); + } opts.addJavaOpts("-cp", "/test-classes/"); opts.addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED"); opts.addClassOptions("cpusets", value); @@ -120,10 +130,18 @@ } private static void testCpuQuota(long quota, long period) throws Exception { + testCpuQuota(quota, period, false); + } + + private static void testCpuQuota(long quota, long period, boolean addCgroupMount) throws Exception { Common.logNewTestCase("testCpuQuota, quota = " + quota + ", period = " + period); DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsCpuTester"); opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/"); + if (addCgroupMount) { + // Extra cgroup mount should be ignored by product code + opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroup-in:ro"); + } opts.addDockerOpts("--cpu-period=" + period).addDockerOpts("--cpu-quota=" + quota); opts.addJavaOpts("-cp", "/test-classes/").addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED"); opts.addClassOptions("cpuquota", quota + "", period + ""); diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java --- openjdk-17-17.0.5+8/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java 2023-01-10 13:21:55.000000000 +0000 @@ -56,6 +56,8 @@ try { testMemoryLimit("200m"); testMemoryLimit("1g"); + // Memory limit test with additional cgroup fs mounted + testMemoryLimit("500m", true /* cgroup fs mount */); testMemoryAndSwapLimit("200m", "1g"); testMemoryAndSwapLimit("100m", "200m"); @@ -89,6 +91,10 @@ } private static void testMemoryLimit(String value) throws Exception { + testMemoryLimit(value, false); + } + + private static void testMemoryLimit(String value, boolean addCgroupMount) throws Exception { Common.logNewTestCase("testMemoryLimit, value = " + value); DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java", "MetricsMemoryTester"); @@ -97,6 +103,10 @@ .addJavaOpts("-cp", "/test-classes/") .addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED") .addClassOptions("memory", value); + if (addCgroupMount) { + // Extra cgroup mount should be ignored by product code + opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroup-in:ro"); + } DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!"); } diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java openjdk-17-17.0.6+10/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java --- openjdk-17-17.0.5+8/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/jfr/api/consumer/streaming/TestLatestEvent.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,8 +23,12 @@ package jdk.jfr.api.consumer.streaming; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Comparator; +import java.util.List; +import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -34,6 +38,7 @@ import jdk.jfr.Name; import jdk.jfr.Recording; import jdk.jfr.consumer.EventStream; +import jdk.jfr.consumer.RecordingFile; import jdk.jfr.consumer.RecordingStream; /** @@ -65,7 +70,8 @@ CountDownLatch beginChunks = new CountDownLatch(1); try (RecordingStream r = new RecordingStream()) { - r.onEvent("MakeChunks", event-> { + r.setMaxSize(1_000_000_000); + r.onEvent("MakeChunks", event -> { System.out.println(event); beginChunks.countDown(); }); @@ -100,13 +106,25 @@ // This latch ensures thatNotLatest has been // flushed and a new valid position has been written // to the chunk header - notLatestEvent.await(80, TimeUnit.SECONDS); + boolean timeout = notLatestEvent.await(80, TimeUnit.SECONDS); if (notLatestEvent.getCount() != 0) { + System.out.println("timeout = " + timeout); + Path repo = Path.of(System.getProperty("jdk.jfr.repository")); + System.out.println("repo = " + repo); + List files = new ArrayList<>(Files.list(repo).toList()); + files.sort(Comparator.comparing(Path::toString)); + for (Path f : files) { + System.out.println("------------"); + System.out.println("File: " + f); + for (var event : RecordingFile.readAllEvents(f)) { + System.out.println(event); + } + } Recording rec = FlightRecorder.getFlightRecorder().takeSnapshot(); Path p = Paths.get("error-not-latest.jfr").toAbsolutePath(); rec.dump(p); System.out.println("Dumping repository as a file for inspection at " + p); - throw new Exception("Timeout 80 s. Expected 6 event, but got " + notLatestEvent.getCount()); + throw new Exception("Timeout 80 s. Expected 6 event, but got " + (6 - notLatestEvent.getCount())); } try (EventStream s = EventStream.openRepository()) { diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java --- openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/compiler/TestCodeCacheFull.java 2023-01-10 13:21:55.000000000 +0000 @@ -79,6 +79,7 @@ Events.assertField(event, "startAddress").notEqual(0L); Events.assertField(event, "commitedTopAddress").notEqual(0L); Events.assertField(event, "reservedTopAddress").notEqual(0L); + Events.assertField(event, "codeCacheMaxCapacity").notEqual(0L); } private static BlobType blobTypeFromName(String codeBlobTypeName) throws Exception { diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/compiler/TestJitRestart.java openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/compiler/TestJitRestart.java --- openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/compiler/TestJitRestart.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/compiler/TestJitRestart.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2013, 2022, 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. + */ + +package jdk.jfr.event.compiler; + +import java.util.List; +import java.util.Comparator; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.whitebox.WhiteBox; +import jdk.test.whitebox.code.BlobType; + +/** + * @test TestJitRestart + * @requires vm.hasJFR + * + * @library /test/lib + * @modules jdk.jfr + * jdk.management.jfr + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:-UseLargePages jdk.jfr.event.compiler.TestJitRestart + */ +public class TestJitRestart { + + public static void main(String[] args) throws Exception { + boolean checkJitRestartCompilation = false; + for (BlobType btype : BlobType.getAvailable()) { + boolean jr = testWithBlobType(btype, calculateAvailableSize(btype)); + if (jr) { + System.out.println("JIT restart event / Compilation event check for BlobType " + btype + " was successful"); + checkJitRestartCompilation = true; + } + } + Asserts.assertTrue(checkJitRestartCompilation, "No JIT restart event found and unexpected compilation seen"); + } + + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + private static boolean testWithBlobType(BlobType btype, long availableSize) throws Exception { + Recording r = new Recording(); + r.enable(EventNames.CodeCacheFull); + r.enable(EventNames.Compilation); + r.enable(EventNames.JITRestart); + r.start(); + long addr = WHITE_BOX.allocateCodeBlob(availableSize, btype.id); + WHITE_BOX.freeCodeBlob(addr); + WHITE_BOX.forceNMethodSweep(); + r.stop(); + + List events = Events.fromRecording(r); + System.out.println("---------------------------------------------"); + System.out.println("# events:" + events.size()); + Events.hasEvents(events); + events.sort(Comparator.comparing(RecordedEvent::getStartTime)); + + boolean compilationCanHappen = true; + for (RecordedEvent evt: events) { + System.out.println(evt); + if (evt.getEventType().getName().equals("jdk.CodeCacheFull")) { + System.out.println("--> jdk.CodeCacheFull found"); + compilationCanHappen = false; + } + if (evt.getEventType().getName().equals("jdk.Compilation") && !compilationCanHappen) { + return false; + } + if (evt.getEventType().getName().equals("jdk.JITRestart")) { + System.out.println("--> jdk.JitRestart found"); + Events.assertField(evt, "codeCacheMaxCapacity").notEqual(0L); + Events.assertField(evt, "freedMemory").notEqual(0L); + System.out.println("JIT restart event found for BlobType " + btype); + return true; + } + } + System.out.println("---------------------------------------------"); + + // in some seldom cases we do not see the JitRestart event; but then + // do not fail (as long as no compilation happened before) + return true; + } + + // Compute the available size for this BlobType by taking into account + // that it may be stored in a different code heap in case it does not fit + // into the current one. + private static long calculateAvailableSize(BlobType btype) { + long availableSize = btype.getSize(); + for (BlobType alternative : BlobType.getAvailable()) { + if (btype.allowTypeWhenOverflow(alternative)) { + availableSize = Math.max(availableSize, alternative.getSize()); + } + } + return availableSize; + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java --- openjdk-17-17.0.5+8/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/jfr/event/oldobject/TestClassLoaderLeak.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -40,10 +40,9 @@ * @test * @key jfr * @requires vm.hasJFR - * @requires vm.gc != "Serial" * @library /test/lib /test/jdk * @modules jdk.jfr/jdk.jfr.internal.test - * @run main/othervm -XX:TLABSize=2k jdk.jfr.event.oldobject.TestClassLoaderLeak + * @run main/othervm -XX:TLABSize=2k -Xmx64m jdk.jfr.event.oldobject.TestClassLoaderLeak */ public class TestClassLoaderLeak { diff -Nru openjdk-17-17.0.5+8/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java openjdk-17-17.0.6+10/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java --- openjdk-17-17.0.5+8/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -35,15 +35,15 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Map; -import java.util.Random; /** * @test * @summary Verify that the outputstream created for zip file entries, through the ZipFileSystem * works fine for varying sizes of the zip file entries - * @bug 8190753 8011146 + * @bug 8190753 8011146 8279536 * @run testng/timeout=300 ZipFSOutputStreamTest */ public class ZipFSOutputStreamTest { @@ -87,7 +87,9 @@ @Test(dataProvider = "zipFSCreationEnv") public void testOutputStream(final Map env) throws Exception { final byte[] chunk = new byte[1024]; - new Random().nextBytes(chunk); + // fill it with some fixed content (the fixed content will later on help ease + // the verification of the content written out) + Arrays.fill(chunk, (byte) 42); try (final FileSystem zipfs = FileSystems.newFileSystem(ZIP_FILE, env)) { // create the zip with varying sized entries for (final Map.Entry entry : ZIP_ENTRIES.entrySet()) { @@ -95,9 +97,12 @@ if (entryPath.getParent() != null) { Files.createDirectories(entryPath.getParent()); } + long start = System.currentTimeMillis(); try (final OutputStream os = Files.newOutputStream(entryPath)) { writeAsChunks(os, chunk, entry.getValue()); } + System.out.println("Wrote entry " + entryPath + " of bytes " + entry.getValue() + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); } } // now verify the written content @@ -108,15 +113,15 @@ final byte[] buf = new byte[chunk.length]; int numRead; long totalRead = 0; + long start = System.currentTimeMillis(); while ((numRead = is.read(buf)) != -1) { totalRead += numRead; // verify the content - for (int i = 0, chunkoffset = (int) ((totalRead - numRead) % chunk.length); - i < numRead; i++, chunkoffset++) { - Assert.assertEquals(buf[i], chunk[chunkoffset % chunk.length], - "Unexpected content in " + entryPath); - } + Assert.assertEquals(Arrays.mismatch(buf, chunk), -1, + "Unexpected content in " + entryPath); } + System.out.println("Read entry " + entryPath + " of bytes " + totalRead + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); Assert.assertEquals(totalRead, (long) entry.getValue(), "Unexpected number of bytes read from zip entry " + entryPath); } diff -Nru openjdk-17-17.0.5+8/test/jdk/ProblemList.txt openjdk-17-17.0.6+10/test/jdk/ProblemList.txt --- openjdk-17-17.0.5+8/test/jdk/ProblemList.txt 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/ProblemList.txt 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ ########################################################################### # -# Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2023, 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 @@ -133,7 +133,6 @@ java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252 macosx-all java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java 8194753 linux-all,macosx-all java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest.java 7152980 macosx-all -java/awt/Focus/SimpleWindowActivationTest/SimpleWindowActivationTest.java 8159599 macosx-all java/awt/Focus/TypeAhead/TestFocusFreeze.java 8198622,6447537 macosx-all,windows-all,linux-all java/awt/Focus/ToFrontFocusTest/ToFrontFocus.java 7156130 linux-all java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.java 8169096 macosx-all @@ -185,12 +184,11 @@ java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all java/awt/datatransfer/SystemFlavorMap/AddFlavorTest.java 8079268 linux-all -java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java 6829250 windows-all java/awt/Toolkit/RealSync/Test.java 6849383 linux-all java/awt/LightweightComponent/LightweightEventTest/LightweightEventTest.java 8159252 windows-all java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java 8203047 macosx-all java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java 8073636 macosx-all -java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055 windows-all,linux-all +java/awt/FullScreen/FullScreenInsets/FullScreenInsets.java 7019055,8266245 windows-all,linux-all,macosx-aarch64 java/awt/Focus/8013611/JDK8013611.java 8175366 windows-all,macosx-all java/awt/Focus/6981400/Test1.java 8029675 windows-all,macosx-all java/awt/Focus/6981400/Test3.java 8173264 generic-all @@ -224,7 +222,6 @@ java/awt/Window/ShapedAndTranslucentWindows/SetShapeAndClick.java 8197936 macosx-all java/awt/Window/ShapedAndTranslucentWindows/SetShapeDynamicallyAndClick.java 8013450 macosx-all java/awt/Window/ShapedAndTranslucentWindows/ShapedTranslucentWindowClick.java 8013450 macosx-all -java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 8222323 windows-all java/awt/Window/ShapedAndTranslucentWindows/FocusAWTTest.java 8222328 windows-all,linux-all,macosx-all java/awt/Window/ShapedAndTranslucentWindows/Shaped.java 8222328 windows-all,linux-all,macosx-all java/awt/Window/ShapedAndTranslucentWindows/ShapedByAPI.java 8222328 windows-all,linux-all,macosx-all @@ -239,14 +236,11 @@ java/awt/FontMetrics/FontCrash.java 8198336 windows-all java/awt/image/BufferedImage/ICMColorDataTest/ICMColorDataTest.java 8233028 generic-all java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 linux-all -java/awt/image/multiresolution/MultiresolutionIconTest.java 8169187,8252812 macosx-all,windows-all,linux-x64 java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all sun/awt/datatransfer/SuplementaryCharactersTransferTest.java 8011371 generic-all sun/awt/shell/ShellFolderMemoryLeak.java 8197794 windows-all -sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 8022403 generic-all sun/java2d/DirectX/OverriddenInsetsTest/OverriddenInsetsTest.java 8196102 generic-all sun/java2d/DirectX/RenderingToCachedGraphicsTest/RenderingToCachedGraphicsTest.java 8196180 windows-all,macosx-all -java/awt/Graphics2D/CopyAreaOOB.java 7001973 windows-all,macosx-all sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java 8144029 macosx-all,linux-all sun/java2d/SunGraphics2D/DrawImageBilinear.java 8191406 generic-all sun/java2d/SunGraphics2D/PolyVertTest.java 6986565 generic-all @@ -261,6 +255,7 @@ java/awt/Component/GetScreenLocTest/GetScreenLocTest.java 4753654 generic-all java/awt/Component/SetEnabledPerformance/SetEnabledPerformance.java 8165863 macosx-all java/awt/Clipboard/HTMLTransferTest/HTMLTransferTest.java 8017454 macosx-all +java/awt/Frame/MiscUndecorated/RepaintTest.java 8266244 macosx-aarch64 java/awt/Robot/ModifierRobotKey/ModifierRobotKeyTest.java 8157173 generic-all java/awt/Modal/FileDialog/FileDialogAppModal1Test.java 7186009 macosx-all java/awt/Modal/FileDialog/FileDialogAppModal2Test.java 7186009 macosx-all @@ -471,12 +466,10 @@ java/awt/image/VolatileImage/GradientPaints.java 8199003 linux-all java/awt/JAWT/JAWT.sh 8197798 windows-all,linux-all java/awt/Debug/DumpOnKey/DumpOnKey.java 8202667 windows-all -java/awt/Robot/RobotWheelTest/RobotWheelTest.java 8129827 generic-all java/awt/Focus/WindowUpdateFocusabilityTest/WindowUpdateFocusabilityTest.java 8202926 linux-all java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java 8202860 linux-all java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java 8202790 macosx-all,linux-all java/awt/FileDialog/FilenameFilterTest/FilenameFilterTest.java 8202882,8255898 linux-all,macosx-all -java/awt/dnd/MissingDragExitEventTest/MissingDragExitEventTest.java 8030121 macosx-all,linux-all java/awt/Choice/ChoicePopupLocation/ChoicePopupLocation.java 8202931 macosx-all,linux-all java/awt/Focus/NonFocusableBlockedOwnerTest/NonFocusableBlockedOwnerTest.java 7124275 macosx-all java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java 6848810 macosx-all,linux-all @@ -496,9 +489,7 @@ java/awt/Frame/DisposeParentGC/DisposeParentGC.java 8079786 macosx-all java/awt/TextArea/AutoScrollOnSelectAndAppend/AutoScrollOnSelectAndAppend.java 8213120 macosx-all -java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223 linux-all,windows-all -java/awt/Window/WindowResizing/DoubleClickTitleBarTest.java 8233557 macosx-all -java/awt/Window/WindowOwnedByEmbeddedFrameTest/WindowOwnedByEmbeddedFrameTest.java 8233558 macosx-all +java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223,8274106 macosx-aarch64,linux-all,windows-all java/awt/keyboard/AllKeyCode/AllKeyCode.java 8242930 macosx-all java/awt/FullScreen/8013581/bug8013581.java 8169471 macosx-all java/awt/event/MouseEvent/RobotLWTest/RobotLWTest.java 8233568 macosx-all @@ -506,7 +497,6 @@ java/awt/event/MouseEvent/ClickDuringKeypress/ClickDuringKeypress.java 8233568 macosx-all java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java 8233568 macosx-all java/awt/event/KeyEvent/DeadKey/deadKeyMacOSX.java 8233568 macosx-all -com/apple/eawt/DefaultMenuBar/DefaultMenuBarTest.java 8233648 macosx-all java/awt/Choice/ChoiceKeyEventReaction/ChoiceKeyEventReaction.java 7185258 macosx-all java/awt/TrayIcon/RightClickWhenBalloonDisplayed/RightClickWhenBalloonDisplayed.java 8238720 windows-all java/awt/PopupMenu/PopupMenuLocation.java 8238720 windows-all @@ -524,6 +514,7 @@ java/awt/KeyboardFocusmanager/TypeAhead/ButtonActionKeyTest/ButtonActionKeyTest.java 8257529 windows-x64 java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787 linux-x64 +java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243 macosx-aarch64 ############################################################################ @@ -680,7 +671,6 @@ sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/ExtDirsChange.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all -sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java 8277970 linux-all,macosx-x64 ############################################################################ @@ -694,7 +684,6 @@ javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all javax/sound/midi/Sequencer/Recording.java 8167580,8265485 linux-all,macosx-aarch64 -javax/sound/midi/Sequencer/MetaCallback.java 8178698 linux-all javax/sound/midi/Sequencer/Looping.java 8136897 generic-all ############################################################################ @@ -737,6 +726,14 @@ javax/swing/Popup/TaskbarPositionTest.java 8065097 macosx-all,linux-all javax/swing/JEditorPane/6917744/bug6917744.java 8213124 macosx-all javax/swing/JRootPane/4670486/bug4670486.java 8042381 macosx-all +javax/swing/JButton/8151303/PressedIconTest.java 8266246 macosx-aarch64 +java/awt/Robot/HiDPIScreenCapture/ScreenCaptureGtkTest.java 8282270 linux-all +java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8282270 windows-all + +# Several tests which fail on some hidpi systems +java/awt/Window/8159168/SetShapeTest.java 8274106 macosx-aarch64 +java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8274106 macosx-aarch64 +javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java 8274106 macosx-aarch64 sanity/client/SwingSet/src/ToolTipDemoTest.java 8225012 windows-all,macosx-all sanity/client/SwingSet/src/ScrollPaneDemoTest.java 8225013 linux-all @@ -818,7 +815,6 @@ jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64 -jdk/jfr/api/consumer/streaming/TestLatestEvent.java 8268297 windows-x64 ############################################################################ diff -Nru openjdk-17-17.0.5+8/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java openjdk-17-17.0.6+10/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java --- openjdk-17-17.0.5+8/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, 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 @@ -24,7 +24,8 @@ /* * @test * @bug 8189131 8207059 - * @summary Interoperability tests with QuoVadis Root CA1, CA2, and CA3 CAs + * @key intermittent + * @summary Interoperability tests with QuoVadis Root CA1, CA2, and CA3 G3 CAs * @build ValidatePathWithParams * @run main/othervm -Djava.security.debug=certpath QuoVadisCA OCSP * @run main/othervm -Djava.security.debug=certpath QuoVadisCA CRL @@ -94,25 +95,26 @@ "73bpxSkjPrYbmKo9mGEAMhW1ZxY=\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-1-g3.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US + // Owner: CN=quovadis-root-ca-1-g3.chain-demos.digicert.com, O="DigiCert, Inc.", + // L=Lehi, ST=Utah, C=US // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 1 G3, O="DigiCert, Inc", C=US - // Serial number: 2b9bf892d8abbde06c26d764263bfa8 - // Valid from: Tue Jan 19 16:00:00 PST 2021 until: Sun Feb 20 15:59:59 PST 2022 + // Serial number: a94cc08600f5fe5d3f0659bfcfec6f0 + // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIGhjCCBW6gAwIBAgIQArm/iS2Ku94Gwm12QmO/qDANBgkqhkiG9w0BAQsFADBZ\n" + + "MIIG/DCCBeSgAwIBAgIQCpTMCGAPX+XT8GWb/P7G8DANBgkqhkiG9w0BAQsFADBZ\n" + "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjEw\n" + - "MTIwMDAwMDAwWhcNMjIwMjIwMjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + + "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjIw\n" + + "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + "CBMEVXRhaDENMAsGA1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x\n" + "NzA1BgNVBAMTLnF1b3ZhZGlzLXJvb3QtY2EtMS1nMy5jaGFpbi1kZW1vcy5kaWdp\n" + - "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUqAk3cOpq\n" + - "E+70B1WMI5R3QEqbrF4TE9jpXFIy2HQV60HSyxrsh2xDpU/zD0BF2mwOGZvQKc1F\n" + - "JcVpwWXJ4vjS/lqDvZBNlzDejr4sQbzZVGFkqP6wu+KrAa+Eu7Lvayke3vi99Ba3\n" + - "MmcauuHQsLwh/A+nLzUZIL56HKREDA6YmvF2Bkz6La+f3y4BhiFcQLWQOSr4LgvD\n" + - "7qqdtd550sT4agIh6G1C3CDgUU2OYX8d70YOokO+msZXppD2le5HJDAUwrEKXB/L\n" + - "3+jxA2wxgxmGzWigkRFl7UlsuLezUZKIHj8YoQu/0LGLZZUcW0OEHj5sspifmQJ7\n" + - "DccQrGWyqU6XAgMBAAGjggMkMIIDIDAfBgNVHSMEGDAWgBSZEX3psK0tYlpw0zyN\n" + - "hyCt2touQTAdBgNVHQ4EFgQUDBReNH49ishzOagWgVaxd7nSyrgwOQYDVR0RBDIw\n" + + "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3HrwaCagg\n" + + "6bxmgEC+neLN/ShfNYuOMQ2Slk5q/zDUhQRpNQnh3nUwoRSWRvwGxDFsRj++LECF\n" + + "TMdfzIu+0rlFzGqd3B5mlRsJrcycy/+ILwGNtIooUSU7pvJAVgLZ5N1SSVZoY+i3\n" + + "bqLiMmv2/JfouT1SQB3U0tGmS+QKyBtVyKPVeuAhnLdyw90UiB7Gu9qXQpCawac8\n" + + "pXPQLFzyEP7VJO0wDXanXvi6YPuIhh4m+j2YVCd9d2zI3y3kOrkuaUY5UCBvMG/b\n" + + "Pc7/5pBsqf+E+7RHF24JAR2aqXzARWt2MzRiwpE/DJDfu097IUtR5aEdCRIKw/b4\n" + + "GcHEbVaE3c8RAgMBAAGjggOaMIIDljAfBgNVHSMEGDAWgBSZEX3psK0tYlpw0zyN\n" + + "hyCt2touQTAdBgNVHQ4EFgQUsG1/1d7ATEocqm82IRByZD/1qQIwOQYDVR0RBDIw\n" + "MIIucXVvdmFkaXMtcm9vdC1jYS0xLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNv\n" + "bTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + "MIGXBgNVHR8EgY8wgYwwRKBCoECGPmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E\n" + @@ -122,62 +124,67 @@ "dHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggr\n" + "BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFo\n" + "dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lD\n" + - "QVFWUm9vdENBMUczLmNydDAMBgNVHRMBAf8EAjAAMIIBBAYKKwYBBAHWeQIEAgSB\n" + - "9QSB8gDwAHUAKXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF3IHgp\n" + - "NQAABAMARjBEAiBNOisRzreFHgpQYJmdzN8pKAGcerQHCWfeWeWyDDD8hQIgP2sh\n" + - "8KGW4sOt/BqEUNhGdD+ZAbv2+xrT57aSRONrG/UAdwAiRUUHWVUkVpY/oS/x922G\n" + - "4CMmY63AS39dxoNcbuIPAgAAAXcgeCmLAAAEAwBIMEYCIQCKVxPY+JbJX4IMcbVc\n" + - "HypoqNyozayPjzuHPZXsr5sZfAIhAIdS8wHmUZz6w5Frqa/CTUSugoNgx9H0K9dN\n" + - "Cl6gsvdcMA0GCSqGSIb3DQEBCwUAA4IBAQB35ONSVAMAhFpTwQl6HEFEmhh++JaF\n" + - "3WLMUODAa79N/GXe0JMvPuTbLsB/H1WXP/27D9ImvWlqLQU3EgqRp0fTdWCnnP4q\n" + - "8FKsKslnKPoiqNyTjpKHWk+gugFAyAAUXEFP4QYSMgye7kBNQZoX9MX4LhPBtqTa\n" + - "cPXLprb/gZMrNbbf9FdOGQXQgpFoaGnvyGw2oGU1Spb+Tx1QbK8NUWCdc8KNo1WB\n" + - "XH37EY8XJJxdjjoocLlFxRBUothYEUk+HdE5MGNqF3egtFKVvDk2OC8redCQ6dDC\n" + - "MKkGc7Avhn43gkRpzuush9Ph79aT1lf4Mm4Rs0FSYm8e62bQspH8UTdh\n" + + "QVFWUm9vdENBMUczLmNydDAJBgNVHRMEAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0E\n" + + "ggFpAWcAdgCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAAAX9cPNEg\n" + + "AAAEAwBHMEUCIEcb3zz7lhKT26HkZpFPF9e7AsHY4HR3pO5LJ5+b2iDGAiEAjEHh\n" + + "4H3Vl+j95X65uBdkODnqjlxRc6OrqCRor71nKTYAdQA1zxkbv7FsV78PrUxtQsu7\n" + + "ticgJlHqP+Eq76gDwzvWTAAAAX9cPNEMAAAEAwBGMEQCIBbRZ9t9oUODHhZfa7n3\n" + + "0lGGmEpnZP9dZw375SuVX6OjAiBbfpZesx7GgSNygEF+zkBAXx+AFJF5GoGiOjFX\n" + + "0ykjDAB2ALNzdwfhhFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABf1w80SoA\n" + + "AAQDAEcwRQIgfSXjtjuKjFiVYwdlitFNgTTSc7uP9hyazlrCKO9GsaYCIQCKimXl\n" + + "j4LjJ4BlG9H1J+V747tuf7ONnAzkCPsa2ymOuzANBgkqhkiG9w0BAQsFAAOCAQEA\n" + + "b9havJS9egan+4dgMhI6gDt6rjdWRniyi7kXv7/vWJXOxR1xl2d/WYDLsfp3BbqW\n" + + "YuKQwB5tTH1hEoNhQIyGnuE1Y1ZgtX24rSVfTCkU/3dnTZaIhaZgFHyftAum7xSI\n" + + "Qzu7pwih+PXrGNXupsnZ+VUE7a7zHyRDajixhSp7dZS4zLoDTxeyKX0MDmo4e8Mi\n" + + "HNYVASYcrdld90jVJaeI/V3EkJAX7/Eyo9JqzivEwGM0e0JhCLekcVSzhjGoAlbQ\n" + + "tIzCIaeVUlWKKiNXSKr1WD4oCD3ky4Y5VekTGzyUf/0LYzV+Y7p8epc5vTWKwYx/\n" + + "vQwJ4RsgFit+c84mSg4qug==\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-1-g3-revoked.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US + // Owner: CN=quovadis-root-ca-1-g3-revoked.chain-demos.digicert.com, + // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 1 G3, O="DigiCert, Inc", C=US - // Serial number: 8fb833dd0472302df1ddc134d36840d - // Valid from: Tue Jan 19 16:00:00 PST 2021 until: Sun Feb 20 15:59:59 PST 2022 + // Serial number: e7eff4cdd14ebed1daa7bb7e07300ed + // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIG1TCCBb2gAwIBAgIQCPuDPdBHIwLfHdwTTTaEDTANBgkqhkiG9w0BAQsFADBZ\n" + + "MIIHDjCCBfagAwIBAgIQDn7/TN0U6+0dqnu34HMA7TANBgkqhkiG9w0BAQsFADBZ\n" + "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjEw\n" + - "MTIwMDAwMDAwWhcNMjIwMjIwMjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + + "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDEgRzMwHhcNMjIw\n" + + "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + "BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu\n" + "MT8wPQYDVQQDEzZxdW92YWRpcy1yb290LWNhLTEtZzMtcmV2b2tlZC5jaGFpbi1k\n" + "ZW1vcy5kaWdpY2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" + - "AQC/YHOKNPYW2a/aji68VN4EYwz5ANxRuCSHXOe6mg8pYaelrnky3hmNT3Ro86wc\n" + - "3UaXE07+fVGjXbbe4eRF5zj1pWsMe81n7NySoLud5C9CU/3okywv6SEPc/RiFKJk\n" + - "ic/BpRTE2pMtFfGsqWALjyDhM+W7SvM5eAXqcVVnqHgO5oToe2Cd0IqhgTgOUDdm\n" + - "+JuY/kY8gRmFyzfs4Oqe8nkgrdsvsyvRtQt1ldc9XKb+C/gnl8ZMiuLpuKWqezce\n" + - "2ED0SW4bVDbaDIhf97CNFeuMHHyZzI7Z0DH29WDcACOVBqVhGJl56T89COM3ISle\n" + - "WpYCOUgyzlPVODisfq/1zgepAgMBAAGjggNqMIIDZjAfBgNVHSMEGDAWgBSZEX3p\n" + - "sK0tYlpw0zyNhyCt2touQTAdBgNVHQ4EFgQUdZf0H3+QjsIMtfpwZUf3YNaVBQ0w\n" + - "fQYDVR0RBHYwdII2cXVvdmFkaXMtcm9vdC1jYS0xLWczLXJldm9rZWQuY2hhaW4t\n" + - "ZGVtb3MuZGlnaWNlcnQuY29tgjp3d3cucXVvdmFkaXMtcm9vdC1jYS0xLWczLXJl\n" + - "dm9rZWQuY2hhaW4tZGVtb3MuZGlnaWNlcnQuY29tMA4GA1UdDwEB/wQEAwIFoDAd\n" + - "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwgZcGA1UdHwSBjzCBjDBEoEKg\n" + - "QIY+aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UXVvVmFkaXNUTFNJ\n" + - "Q0FRVlJvb3RDQTFHMy5jcmwwRKBCoECGPmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv\n" + - "bS9EaWdpQ2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3JsMD4GA1UdIAQ3\n" + - "MDUwMwYGZ4EMAQICMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQu\n" + - "Y29tL0NQUzCBgwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz\n" + - "cC5kaWdpY2VydC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2lj\n" + - "ZXJ0LmNvbS9EaWdpQ2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3J0MAwG\n" + - "A1UdEwEB/wQCMAAwggEGBgorBgEEAdZ5AgQCBIH3BIH0APIAdwApeb7wnjk5IfBW\n" + - "c59jpXflvld9nGAK+PlNXSZcJV3HhAAAAXcgeVnsAAAEAwBIMEYCIQCBIKm+1buq\n" + - "Ws6nDYt1OMGxHa7yaxwQu5yaWCq6wk3kXQIhAL0ImrZZWp0Uq2i3QhDVjAfsP9lF\n" + - "LRf2f0qbqJUXzTV7AHcAIkVFB1lVJFaWP6Ev8fdthuAjJmOtwEt/XcaDXG7iDwIA\n" + - "AAF3IHlaMwAABAMASDBGAiEAm+RVoIBHAiMN+m/fuo65CLCwTRa/YVrP8wjUT4pM\n" + - "5toCIQDhV6pbmxbwGl9rM56ypsKZLJeB4LeCWqJmb7yf61E9WzANBgkqhkiG9w0B\n" + - "AQsFAAOCAQEAh82J/F2rBZ6GUFmOdIS8mhzO/ItkpAX+bta5lyPasCgP3JEmHONr\n" + - "HBX1UIvKYo7/McgFBt1V90ncQXfuutIyh0hPXSbTqK/b7XCVarh9J0ZXp8gLstQ5\n" + - "39DiuiS+qWBSc8C14VIOjeTblTBM6hjvkdnYhTZt2ip3aKYu8sHyC+3DpAYuD2og\n" + - "Lzs8Q7wvPwvBE2HMsr6c8dFjC9S8HZvrfJTwuh/7QhafueuwPEfr6a2/TExF/3B1\n" + - "QXxgYPg7pQ2gPUqucO47FcEhr5GHzTwNoGAropkFj3g0byEt0i+EwLMjdAlDABzP\n" + - "CFww1aRfNklbdRBZ/rr7QzmGtn39JzZKMQ==\n" + + "AQDCQQ2S25TEDDGHa/zvFUex4mD7pUAS7g80g8mQVII2v9Cg6F2tIEbay/IDhV3D\n" + + "NtxJcaqiMpT9oMA5jhMSOqcoq8QFzdqugtIvxQ3obrIZysxjjluB2b1T5UhlnND1\n" + + "ShXlSWRhwkCN8qfO+VJ8wrpVH45mj+DsiSLWrY8Vw4q+gcJgoUV0Vj87m1H93JTf\n" + + "pF68NjljUOOTTXZSzsvTRpDsnOizbVeyZoRawRP8D4UbxA8P28Q5W7a/uZSnUkfo\n" + + "1U1QFDd/ii/PCt6TVGYCNUehb8eSrEyjAtIZ/ricIVkKxcqzQ3Tuq7HefH/KiAqD\n" + + "GWr0NfO1JhX5ILmDZcosdsW1AgMBAAGjggOjMIIDnzAfBgNVHSMEGDAWgBSZEX3p\n" + + "sK0tYlpw0zyNhyCt2touQTAdBgNVHQ4EFgQUK6amWfyhRxRpr+fT1tpYV14n2wgw\n" + + "QQYDVR0RBDowOII2cXVvdmFkaXMtcm9vdC1jYS0xLWczLXJldm9rZWQuY2hhaW4t\n" + + "ZGVtb3MuZGlnaWNlcnQuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr\n" + + "BgEFBQcDAQYIKwYBBQUHAwIwgZcGA1UdHwSBjzCBjDBEoEKgQIY+aHR0cDovL2Ny\n" + + "bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UXVvVmFkaXNUTFNJQ0FRVlJvb3RDQTFH\n" + + "My5jcmwwRKBCoECGPmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFF1\n" + + "b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQIC\n" + + "MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBgwYI\n" + + "KwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" + + "b20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" + + "Q2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0ExRzMuY3J0MAkGA1UdEwQCMAAwggF+\n" + + "BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB3AOg+0No+9QY1MudXKLyJa8kD08vREWvs\n" + + "62nhd31tBr1uAAABf1xeMeAAAAQDAEgwRgIhALuEk3mDbnEEkboc95mrKMgibE0K\n" + + "0QAWMu1gI/teH06xAiEA7dbuLv66ScQkOq0zbfnUM8ih1Bw+Wb29jQRyTEXCaxEA\n" + + "dgA1zxkbv7FsV78PrUxtQsu7ticgJlHqP+Eq76gDwzvWTAAAAX9cXjIwAAAEAwBH\n" + + "MEUCIBvEfG23Yewp6oXQJExXQ+Am7z4i0X5NqSz8ohAXT3NiAiEAhDjy2H2Z5CV5\n" + + "gZ8TACTVgNyvEIH0cS4DjH6/ILknLDEAdQCzc3cH4YRQ+GOG1gWp3BEJSnktsWcM\n" + + "C4fc8AMOeTalmgAAAX9cXjJBAAAEAwBGMEQCIGuxWoTPcFYQlVF9q/F1JbaZj/VT\n" + + "O6Oa8ionxCC/8aqrAiAUCUoDcwphZ25ZFC+xGiP0kUiWgUwuQH7lBpTgoZp/BjAN\n" + + "BgkqhkiG9w0BAQsFAAOCAQEAFrVjcQxq81PXEgHCf48+FOle8kUpJGxpH1n1Sp0p\n" + + "V95wrXj47oT1Vt9WqXPrNDfDkxwAvvXrCMXjHEg2YN0FCEanVec8GciuRRRtXrOE\n" + + "QOXAqGv5j+KG7bEvMNUFS90fesxfxVAQkr1zIT70nMAOKV1NOyQ/q8bZ+jehcRZB\n" + + "wUKrCWAzvOw4DPytrDcQmflvQN+Bw92T3uDuoYT/oBcobpVfKpfuW/+ZxxXTIp4L\n" + + "sixlx82SZNTo6e3LOqsgZnR6TFyRJ63sK65M+W0d55bHvleUAHRCOiGhhgqE/cby\n" + + "z50hDzJMLnjskMSpkxMoeSeutAS2e7oIvA//7C37LrQccQ==\n" + "-----END CERTIFICATE-----"; public void runTest(ValidatePathWithParams pathValidator) @@ -189,7 +196,7 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Wed Jan 20 07:46:23 PST 2021", System.out); + "Tue Mar 08 11:22:28 PST 2022", System.out); } } @@ -232,17 +239,18 @@ "cy+N\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-2-g3.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US, - // SERIALNUMBER=5299537-0142, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US, - // OID.2.5.4.15=Private Organization + // Owner: CN=quovadis-root-ca-2-g3.chain-demos.digicert.com, O="DigiCert, + // Inc.", L=Lehi, ST=Utah, C=US, SERIALNUMBER=5299537-0142, OID.1.3.6.1.4 + // 1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US, + // OID.2.5.4 .15=Private Organization // Issuer: CN=DigiCert QV EV TLS ICA G1, O="DigiCert, Inc.", C=US - // Serial number: a54e525a61f2552f65885c6dce9fe21 - // Valid from: Mon Feb 01 16:00:00 PST 2021 until: Sat Mar 05 15:59:59 PST 2022 + // Serial number: 9c5e9d5f169d3a59e64db208d3e849d + // Valid from: Wed Feb 02 16:00:00 PST 2022 until: Mon Mar 06 15:59:59 PST 2023 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIGuzCCBaOgAwIBAgIQClTlJaYfJVL2WIXG3On+ITANBgkqhkiG9w0BAQsFADBK\n" + + "MIIHNDCCBhygAwIBAgIQCcXp1fFp06WeZNsgjT6EnTANBgkqhkiG9w0BAQsFADBK\n" + "MQswCQYDVQQGEwJVUzEXMBUGA1UECgwORGlnaUNlcnQsIEluYy4xIjAgBgNVBAMM\n" + - "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjEwMjAyMDAwMDAwWhcNMjIw\n" + - "MzA1MjM1OTU5WjCB3zEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzAR\n" + + "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjIwMjAzMDAwMDAwWhcNMjMw\n" + + "MzA2MjM1OTU5WjCB3zEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzAR\n" + "BgsrBgEEAYI3PAIBAxMCVVMxFTATBgsrBgEEAYI3PAIBAhMEVXRhaDEVMBMGA1UE\n" + "BRMMNTI5OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsG\n" + "A1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xNzA1BgNVBAMTLnF1\n" + @@ -253,7 +261,7 @@ "Iuf1E1Ek70DkTWAg6OrPHMe2ER3aSz2S2rNkMSopURvZuabzPovsGaz+XEZNfE4N\n" + "UfkBLa0DUjFCamOMZKIfkzxpH/NhQcigGnZgxiyUb6KRhu9ydpWeOvOHwPWwR/fV\n" + "7WT+X1DUHojoXeCk2RtIRMihDWPd+lqiUppM8IlEW/gxWbK1wP41qioiK9j5AgMB\n" + - "AAGjggMFMIIDATAfBgNVHSMEGDAWgBQTL6fobnFR9uIMmEeDnn+deHk08zAdBgNV\n" + + "AAGjggN+MIIDejAfBgNVHSMEGDAWgBQTL6fobnFR9uIMmEeDnn+deHk08zAdBgNV\n" + "HQ4EFgQUtAEN4g3bzwES6MoOINihiZQrt+owOQYDVR0RBDIwMIIucXVvdmFkaXMt\n" + "cm9vdC1jYS0yLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNvbTAOBgNVHQ8BAf8E\n" + "BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHsGA1UdHwR0MHIw\n" + @@ -263,43 +271,47 @@ "AQEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMHYG\n" + "CCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu\n" + "Y29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln\n" + - "aUNlcnRRVkVWVExTSUNBRzEuY3J0MAwGA1UdEwEB/wQCMAAwggEEBgorBgEEAdZ5\n" + - "AgQCBIH1BIHyAPAAdgApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAA\n" + - "AXdkNiYhAAAEAwBHMEUCIQDg62+lrhAGdZcklHTEzYpVIki6v6fYgsbxmkTqV6M2\n" + - "BgIgOcYjjM1DGT2FWFK5OO4Qs7T7V28neWwqbMPqLBZgRCoAdgAiRUUHWVUkVpY/\n" + - "oS/x922G4CMmY63AS39dxoNcbuIPAgAAAXdkNiaKAAAEAwBHMEUCIQC0ZH0YX6BP\n" + - "k4QAm22mVvXXG9EVBWIS5LP49f9VFhb67QIgfYqYV/wJt3czP5rA4NbJXBeFxZXy\n" + - "DVnewfs2mz7kNOIwDQYJKoZIhvcNAQELBQADggEBAHIFaq9Edv37sXl07n3H93ym\n" + - "AzvQKJGD1khWwHQCGBXVzpUBi2v9Il0oS2pTATGD3ZB81Clryy9X3gHgkJcHFRn0\n" + - "cVr88GcyEWrxE8D6sx1X4WhlQknbKXNw8eL97EpZ4zKF1nDaYmf+e/lbmjnZIcdr\n" + - "DRcMmWD6LZBWP8MMD+5uJvooO4eBYM/WKVRgg6jAj1HELBHi9E6Xwm5jPx3DKt6W\n" + - "voJqcRJg3d4TiV8U/yOs8+514iAw+1YJFtAaxg5/eUQM/22BGXki8QCJ3NaaUGrj\n" + - "UNASswMDevD8rVwZ5Bc2iC+c0WVIgHZepyioNC2XSVPovV9pF4Q3ppkSvEGQGSo=\n" + + "aUNlcnRRVkVWVExTSUNBRzEuY3J0MAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5\n" + + "AgQCBIIBbQSCAWkBZwB2AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1u\n" + + "AAABfsHcGW0AAAQDAEcwRQIgSMSWvB5/8sf6CAZYojDI+t3bmcVHtIJT3T+Z3TcZ\n" + + "MFMCIQD5Qyb6jwHOAscsPeID156bUZIw+PeB652u+Q8gTU8C5gB1ADXPGRu/sWxX\n" + + "vw+tTG1Cy7u2JyAmUeo/4SrvqAPDO9ZMAAABfsHcGUcAAAQDAEYwRAIgL68Riq9a\n" + + "l17hobjQopbfzvcQi4KT1+DlqO2dAeCuF80CIAy19t3bAxcJRmbXWo9J2dGc7WuE\n" + + "r+bLfnQoerq9KB1bAHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoA\n" + + "AAF+wdwZZAAABAMARzBFAiEA4vYazXAaD1BfJ8MqEmrfxeTIDQ6LZkmqfh8xEnVz\n" + + "8VYCIF/RgfyBhOeH40wfgwpFTa+Y+t7EWg0PtjC4IaIFTKYKMA0GCSqGSIb3DQEB\n" + + "CwUAA4IBAQC5KLlms/+5XcCIEFBpQSwT7VoRcqnrVWlhya+9ClA98LYuDUeHcHt6\n" + + "lHvfjEEmy2s2GoKHK/JxXzftBau5LbDWlvQ6EF+22fnaVDsKIwNgYwbhJb+6zr8t\n" + + "LOFS6Y51YSlRrDUvy94S3PE7N8D3wyKq18IhXOI1WUeR0bKHLlXtl+ZjKMIMkd/l\n" + + "YtLnnskRCQa0P/HLwQYLUpgiNGVZJQbjrWsVzcw12mR/gza1KjR02STJRGZad7L0\n" + + "Oz48CRhm94iaEjFcVKT3vcDUrtCKpkmhBACcdA3NNqDq10i/SLspOeDLSESkkJKF\n" + + "w8w3YCqXjZn5JyV3sVHYNezNKtLdCxn4\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-2-g3-revoked.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US, - // SERIALNUMBER=5299537-0142, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, OID.1.3.6.1.4.1.311.60.2.1.3=US, - // OID.2.5.4.15=Private Organization + // Owner: CN=quovadis-root-ca-2-g3-revoked.chain-demos.digicert.com, + // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US, SERIALNUMBER=5299537-0142, + // OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Utah, + // OID.1.3.6.1.4.1.311.60.2.1.3=US // Issuer: CN=DigiCert QV EV TLS ICA G1, O="DigiCert, Inc.", C=US - // Serial number: 27c8845dc98ebf433dc5ce8618570d1 - // Valid from: Mon Feb 01 16:00:00 PST 2021 until: Sat Mar 05 15:59:59 PST 2022 + // Serial number: 3f84605850df3ac98fcc15adec269f8 + // Valid from: Sun Apr 17 17:00:00 PDT 2022 until: Fri May 19 16:59:59 PDT 2023 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGzDCCBbSgAwIBAgIQAnyIRdyY6/Qz3FzoYYVw0TANBgkqhkiG9w0BAQsFADBK\n" + + "MIIHQDCCBiigAwIBAgIQA/hGBYUN86yY/MFa3sJp+DANBgkqhkiG9w0BAQsFADBK\n" + "MQswCQYDVQQGEwJVUzEXMBUGA1UECgwORGlnaUNlcnQsIEluYy4xIjAgBgNVBAMM\n" + - "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjEwMjAyMDAwMDAwWhcNMjIw\n" + - "MzA1MjM1OTU5WjCB5zEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzAR\n" + - "BgsrBgEEAYI3PAIBAxMCVVMxFTATBgsrBgEEAYI3PAIBAhMEVXRhaDEVMBMGA1UE\n" + + "GURpZ2lDZXJ0IFFWIEVWIFRMUyBJQ0EgRzEwHhcNMjIwNDE4MDAwMDAwWhcNMjMw\n" + + "NTE5MjM1OTU5WjCB5zETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysGAQQBgjc8\n" + + "AgECEwRVdGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEVMBMGA1UE\n" + "BRMMNTI5OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsG\n" + "A1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xPzA9BgNVBAMTNnF1\n" + "b3ZhZGlzLXJvb3QtY2EtMi1nMy1yZXZva2VkLmNoYWluLWRlbW9zLmRpZ2ljZXJ0\n" + - "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL8H5MLxLmlUrb/C\n" + - "+GndqTYyAWf7dlxmqK4bRtIQf6YIAum8sZwo7M+av3lNQAqRa9PsV4ms50lUSP6u\n" + - "sFPAKINoOIu3ABT3qlSNb7ChxYCaZAiW3D1N4Jc9SU4Pa6tfPM3mSWc2HR7kSqj+\n" + - "PtdDHgB8/wjgQwvGRFXTacM/dQVtd8cSLYGMaSgPTKqV87aps7gvd0a9jvJRPmzr\n" + - "vJihL8K5MRiKTwXofT2s8/+/XMn0qWzWzBPe/bQuTT3Ot0Ee5u54FVPi0659rDtj\n" + - "hDIf1M7GmSA/kuhcxI6vGusPZhrr+BbSbX8bRyXMPyE/V2qN2rGMVqDgo8CYP9oY\n" + - "BXBocaECAwEAAaOCAw4wggMKMB8GA1UdIwQYMBaAFBMvp+hucVH24gyYR4Oef514\n" + - "eTTzMB0GA1UdDgQWBBSxl5QSK4J6HfhClE1Vq1ElwnnNDzBBBgNVHREEOjA4gjZx\n" + + "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANfUkoe8l/AFhMH5\n" + + "NtRR2Ztx4xVINz1celdjQE7xgjyHoQY6EMhuI+tvTpwJr9wJEFl7YBiIUFUgJZo6\n" + + "lCLZtXI5t6rN0PhI+F03vGj5ukOkBBcsNVuKPJjud78sHL7u4w7RL3agrQIG7sff\n" + + "bQK4qieUDPxiE8TO8mIzUKnIvYeNA8aJe4zxWf6Mn64WvnudsxYFgMDL4L0ryYKy\n" + + "Ls53Co0OweOl4qnNSne8eIGfb6UaUBQvWbnVfRSHzf+skrF1qstWlFhUsqR07HtF\n" + + "6BqVrAsRA8tmXisyXrMp9jTcIsG7LXVLOqxN07mAvpateExZs3WWRhfQl4Z+HpHD\n" + + "80WbTI0CAwEAAaOCA4IwggN+MB8GA1UdIwQYMBaAFBMvp+hucVH24gyYR4Oef514\n" + + "eTTzMB0GA1UdDgQWBBSTXYbD9dwCDxIH/aN5vIr02uLz5DBBBgNVHREEOjA4gjZx\n" + "dW92YWRpcy1yb290LWNhLTItZzMtcmV2b2tlZC5jaGFpbi1kZW1vcy5kaWdpY2Vy\n" + "dC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\n" + "BQcDAjB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v\n" + @@ -308,19 +320,21 @@ "YIZIAYb9bAIBMDIGBWeBDAEBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGln\n" + "aWNlcnQuY29tL0NQUzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6\n" + "Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL2NhY2VydHMu\n" + - "ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UVZFVlRMU0lDQUcxLmNydDAMBgNVHRMBAf8E\n" + - "AjAAMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHcAKXm+8J45OSHwVnOfY6V35b5X\n" + - "fZxgCvj5TV0mXCVdx4QAAAF3ZDY16wAABAMASDBGAiEAxiHgWMmElnreF1ItPryX\n" + - "1zHYYy8MswsWwPSLCRoNIh8CIQCoMhTfGdeb/YfgU7ADy0zo1ktLjnoWUXy57e2s\n" + - "syevwAB2ACJFRQdZVSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABd2Q2Nh0A\n" + - "AAQDAEcwRQIhAIEUtUcXMIj/5+uNhqtRuzeppiC0dU9pcWuCkOqazlSsAiBeuAjH\n" + - "z1EyH5zDDR2dJoVJekXsihpIoXUiClDNBgCNUjANBgkqhkiG9w0BAQsFAAOCAQEA\n" + - "s/QeNaPZt8WftrnUqWI+neGyFlh6odWgpKxudOKVdvlGIUZ1bZlNzPcoHvdqgeVy\n" + - "Vys3NxfSAX812lYo+IvPM9l3CmuaHkb7l/5O8bwnEPZuLd6EExp8BVYCIwfW+9cm\n" + - "uyHXBJUEm1gkF2Utd8EYdf4jEcBCdDIXgNJI+DY05OlHE0E2IseQIHf9kttZzQHH\n" + - "QEVtowJsaa2EksksBAmDDHH6ybyee7bZl8W2xkpbzvUvb6SuK+M/XyUjS9SYtun3\n" + - "z82BhOhRMbpokpK2Eba6IeC7WoVX2Y8Wsqj198qTVvuyRiw2B3SdZarKV5VTySY3\n" + - "aqsEyxenca5EjxU7QZDAHQ==\n" + + "ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0UVZFVlRMU0lDQUcxLmNydDAJBgNVHRMEAjAA\n" + + "MIIBfAYKKwYBBAHWeQIEAgSCAWwEggFoAWYAdQDoPtDaPvUGNTLnVyi8iWvJA9PL\n" + + "0RFr7Otp4Xd9bQa9bgAAAYA+bejFAAAEAwBGMEQCIFDhmaB4BXmOw2SKONPFBU8t\n" + + "qXb7DXeG6JHGcONDqITjAiAqozEj7/1ULu6t/uzfwOSgC7xEmUsLGzQVnaOF9m3s\n" + + "swB1ADXPGRu/sWxXvw+tTG1Cy7u2JyAmUeo/4SrvqAPDO9ZMAAABgD5t6QkAAAQD\n" + + "AEYwRAIgfVEs7Ph+wOpoCGl4woa3aUWH1COGx1SwvHZ8lH21xfsCIBI1IpR6goya\n" + + "iz47tT/Uz+26RnkHiAApYsdMOPyevkzhAHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFn\n" + + "DAuH3PADDnk2pZoAAAGAPm3pPgAABAMARzBFAiAKBon1PVoqJAF49jMQd2c222TK\n" + + "sWkL5sLFqLVZj2vOugIhAODd/OUy236+9alC2U5nxl1oej9fOF4por2OZMFQfpFF\n" + + "MA0GCSqGSIb3DQEBCwUAA4IBAQAyrJzyOiRAETfoYddTmRmbnFNuHx4YAkkdxn2d\n" + + "BXdy4jPn0kTtDo4592KnbTdieSCWghmEmcEY1sQXdX6iqKwzmp408jfUDohl5evV\n" + + "oZrum3P3zgLRz1qswFM5a2HteWzCWWi/n6d6nKXj6PGGVAMQfk1s6PaWhYBuiaag\n" + + "myYss/LTPzaLGUfFzlt/HfomiD+BNuBOVa+pPrmTWhex+e02z95n6RPYCiazuZNZ\n" + + "xiarN83pRNu/fIjVXw2jENg7+kaC1wwLqET0x6/EJa6YI3Xa7Aumb8Pp2r2UZ5Tr\n" + + "7BUhmiRLkvw/9SI8ceXNSwuTTGK2fKHm2/CWqI0cS3zWk3dC\n" + "-----END CERTIFICATE-----"; public void runTest(ValidatePathWithParams pathValidator) @@ -332,7 +346,7 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Tue Feb 02 11:26:52 PST 2021", System.out); + "Mon Apr 18 14:07:46 PDT 2022", System.out); } } @@ -375,25 +389,26 @@ "l8Sd/Kpqwde/sJkoqwDcBSJygh0=\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-3-g3.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US + // Owner: CN=quovadis-root-ca-3-g3.chain-demos.digicert.com, O="DigiCert, Inc.", + // L=Lehi, ST=Utah, C=US // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 3 G3, O="DigiCert, Inc", C=US - // Serial number: 19a05758f4ac7061ce9b3badd54d9b3 - // Valid from: Tue Jan 19 16:00:00 PST 2021 until: Sun Feb 20 15:59:59 PST 2022 + // Serial number: f27ee3fad1d754ae78d7866da0a4f6f + // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIGhjCCBW6gAwIBAgIQAZoFdY9KxwYc6bO63VTZszANBgkqhkiG9w0BAQsFADBZ\n" + + "MIIG/jCCBeagAwIBAgIQDyfuP60ddUrnjXhm2gpPbzANBgkqhkiG9w0BAQsFADBZ\n" + "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjEw\n" + - "MTIwMDAwMDAwWhcNMjIwMjIwMjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + + "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjIw\n" + + "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjB9MQswCQYDVQQGEwJVUzENMAsGA1UE\n" + "CBMEVXRhaDENMAsGA1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x\n" + "NzA1BgNVBAMTLnF1b3ZhZGlzLXJvb3QtY2EtMy1nMy5jaGFpbi1kZW1vcy5kaWdp\n" + - "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCm/KON4FI\n" + - "zslgCHcJkdamTiryUif9w+BD1xGb7W7hCo+JuLkMzDSH+gGAdwdjYK1NY5c0gFiw\n" + - "Ud3OeHbNe7dZJSXhBP1oF3Xwl0f0DWIfa9nJObzQrN94PnYzDNGuFZut69dqzghO\n" + - "1QGG/+dVdITvzqyA/Mqy7TUsZyoaG4OALTdOXAlFmeMf5UP7EDrAEC0dlUoYJnwK\n" + - "0BeRNZDPYc/OsHviNa6/PnBli81C1QSrAT93STEAnWsCJrG8KlbSElYz2zwPwBZ7\n" + - "ye1m8vH/K7npIIL0d/vSCxLUbC1pstOUahXvZE/Wl1zIV+JyCRmZS7sxTy6s5M4+\n" + - "31Va8Y9jdbeBAgMBAAGjggMkMIIDIDAfBgNVHSMEGDAWgBQzZvsvkQXMs2JS7808\n" + - "9X4czqcXljAdBgNVHQ4EFgQUsVGPx+H0EHp+wefHsSq0rN9eOzMwOQYDVR0RBDIw\n" + + "Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOZpBBS8yo\n" + + "ioVgFUQDCVcnkHTL4/PfaPKGK1owE0+mKz1AXmYX1rzFfp6gFqjbZeclhWCKoINE\n" + + "OrZ2+1mGp75+nCP89NgoGzPgjYLVsM97gN2Y36/jXu8TwsZdYfBw9gxL+YApvq2r\n" + + "NbPfxXaYfWdq8bz0RzqXRgS8BqKi1q8tKyahx5EJ3fCpozY9NPvCnipwbWXL9evF\n" + + "Oak3c5Ip2YME4mHh8PujrznCVBte7KGLDn2KwbOUbh5SKKBL32vzTPOERWEDMbAu\n" + + "3XqQh/cc4LTp32Lf/XkfnUOSbzNh+Te8ZjeDzI+SYNg9bleKpPxLSkBZyurs4mCD\n" + + "92L8BXPlMaGjAgMBAAGjggOcMIIDmDAfBgNVHSMEGDAWgBQzZvsvkQXMs2JS7808\n" + + "9X4czqcXljAdBgNVHQ4EFgQUnf71SuL2Z73DAgGKgO7UVFDBIkgwOQYDVR0RBDIw\n" + "MIIucXVvdmFkaXMtcm9vdC1jYS0zLWczLmNoYWluLWRlbW9zLmRpZ2ljZXJ0LmNv\n" + "bTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" + "MIGXBgNVHR8EgY8wgYwwRKBCoECGPmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E\n" + @@ -403,39 +418,43 @@ "dHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggr\n" + "BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFo\n" + "dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRRdW9WYWRpc1RMU0lD\n" + - "QVFWUm9vdENBM0czLmNydDAMBgNVHRMBAf8EAjAAMIIBBAYKKwYBBAHWeQIEAgSB\n" + - "9QSB8gDwAHYAKXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4QAAAF3IHx1\n" + - "rwAABAMARzBFAiAHK4QuN606ween6tDb2EiNdYTNGhWayvJemSNKuGIELgIhAKaF\n" + - "1/emwlNTMJDlG+kqEhqeO/+XjtfUfhdIeT8dR7dPAHYAIkVFB1lVJFaWP6Ev8fdt\n" + - "huAjJmOtwEt/XcaDXG7iDwIAAAF3IHx13QAABAMARzBFAiEA7qBblGimuzeSA3S5\n" + - "hkE+fVi0DLn/eElclZRk/RSCcsECIDN91iQV6iQryAeD597RExuxunvz+DXn6iz7\n" + - "43/4LdbkMA0GCSqGSIb3DQEBCwUAA4IBAQBZl4PoBJhh6j32nW39aRpOWTEhxZt+\n" + - "NItfFhaQSrJWWmWkKyIQ6roKf8mDyf2x6PGiWV1+ZLEJ5iUmuFtcjlvdd6PjP2J9\n" + - "qEev/kWfdnBY0Ocvfo6ZYhXy/9lW/1s9RQSNiEXTAi+C3R6iTQ5RYW6w4mStynqH\n" + - "dDO763+aE7vxSh6BxvbZugbkDkrHpjrpoWceT0huwbS7y7U0mk94eXXnTzisBHPY\n" + - "zbWlJNJVmt2ut9L9TIAZfqTmdWNKVXiVd2tOB2vKwHYzKM55/LqwcX+XfSpT2FQP\n" + - "OQ1TllgAl+B+4PexVRfO7MNuZgKwT8LuJp1d6xZNvXiNx6dhNBnaY7eE\n" + + "QVFWUm9vdENBM0czLmNydDAJBgNVHRMEAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8E\n" + + "ggFrAWkAdwDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAX9cGyUR\n" + + "AAAEAwBIMEYCIQDjpwE/uiXodkY8Cx3ecooM7gxZp+Qi3aQSIi3SWam6YwIhAPqz\n" + + "8AdaOw+FTZApiEiO2PXww8Y98YtivwXay8v/ZFxrAHYANc8ZG7+xbFe/D61MbULL\n" + + "u7YnICZR6j/hKu+oA8M71kwAAAF/XBsk5gAABAMARzBFAiEA4v9FfzFKPr8hPM1O\n" + + "jPSlboD96ufdyFBy9KmD8pFcI6ECIBY6pcURmWtsE/G2jQgC+qvueJqSycNP2qTM\n" + + "iJ3pO/U1AHYAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoAAAF/XBsl\n" + + "BwAABAMARzBFAiEAsHzOaXv9OIo4RvaKUEscoLpnM98C+4hc6v4Z26d41aICIC2o\n" + + "aTrc5JsqgDhJXp7UArQPziUqDso967W2mrLa0nLdMA0GCSqGSIb3DQEBCwUAA4IB\n" + + "AQC2CaUwlIb+uKsELGw5U2KV0q8uMp/nBIyFaW/HNOJUf8j1keaf31WWBAFfUQVY\n" + + "pzFRUnRmNTtGxCvzyY1YhoQSwswGghz8ZCSQPWCST/Tl8kKuVFas8wSUXaEV23t4\n" + + "G0pfIlXL2oIuJwREjzv54SK7xsQ4whco0nw8DvLt+/5us4t96u8r1EuBKkF45ngz\n" + + "t77MTqpa0nvWUT7q9POT7xwQNui7P0j5t7prVX/fBKm5EfK1Jdi1Toj9+VxTIWYk\n" + + "splUCXw7zxaA3nlrncAmnHxZEY8sQjpGY1OGY0udd+m5bldJNbRTA1Q+VoPVMiU6\n" + + "osdBQGUbbWrqm1fnoFW1VvUt\n" + "-----END CERTIFICATE-----"; - // Owner: CN=quovadis-root-ca-3-g3-revoked.chain-demos.digicert.com, O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US + // Owner: CN=quovadis-root-ca-3-g3-revoked.chain-demos.digicert.com, + // O="DigiCert, Inc.", L=Lehi, ST=Utah, C=US // Issuer: CN=DigiCert QuoVadis TLS ICA QV Root CA 3 G3, O="DigiCert, Inc", C=US - // Serial number: 804a1f35d45fb0f799c9dd1e54f0a41 - // Valid from: Tue Jan 19 16:00:00 PST 2021 until: Sun Feb 20 15:59:59 PST 2022 + // Serial number: aafa7cafda91796626f5fc8bcb38702 + // Valid from: Fri Mar 04 16:00:00 PST 2022 until: Wed Apr 05 16:59:59 PDT 2023 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIGlzCCBX+gAwIBAgIQCASh811F+w95nJ3R5U8KQTANBgkqhkiG9w0BAQsFADBZ\n" + + "MIIHDTCCBfWgAwIBAgIQCq+nyv2pF5Zib1/IvLOHAjANBgkqhkiG9w0BAQsFADBZ\n" + "MQswCQYDVQQGEwJVUzEWMBQGA1UECgwNRGlnaUNlcnQsIEluYzEyMDAGA1UEAwwp\n" + - "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjEw\n" + - "MTIwMDAwMDAwWhcNMjIwMjIwMjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + + "RGlnaUNlcnQgUXVvVmFkaXMgVExTIElDQSBRViBSb290IENBIDMgRzMwHhcNMjIw\n" + + "MzA1MDAwMDAwWhcNMjMwNDA1MjM1OTU5WjCBhTELMAkGA1UEBhMCVVMxDTALBgNV\n" + "BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu\n" + "MT8wPQYDVQQDEzZxdW92YWRpcy1yb290LWNhLTMtZzMtcmV2b2tlZC5jaGFpbi1k\n" + "ZW1vcy5kaWdpY2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" + - "AQC1ZjOf9P8AsZUMI2utVu8I9Ap1xOfIrZ0CGh5ZT1O/+PqE27hnqwG7Ed0yuQs7\n" + - "OMyo0BP5d8Fg7dbW4LqaA+al3vRH+CQQoeD8zsQd1jWS6ZuitB3CQecZpCaMdzBe\n" + - "kQrmj0ofmyEcI5tvQTh4UeGkT66ONB0t4Urol0PCanX8Y3jQVt3FdPDdDTiIHRnl\n" + - "maOD1nCkkEEKGbRhxHH/8p8NCQD+i1Rn6KVMjy/hdMVEJCdFDMfKETgfcs2ZgKce\n" + - "A8UyPo5pfpvPEptss2Ndj80ou4X0ACV8x0nqWpOojFsml5BYIzRK8s8adAmcUUkG\n" + - "uukBGeJTQLd3Ygt6wa2gkeP/AgMBAAGjggMsMIIDKDAfBgNVHSMEGDAWgBQzZvsv\n" + - "kQXMs2JS78089X4czqcXljAdBgNVHQ4EFgQUidJlKGbvtsxFbZ+KM2iajjjrEdcw\n" + + "AQDofDJ1xHHWMhbWwU7e4cY3u2NjvE4ur/A0Y13UK53zoH8qDunV6ORAXQ+zSpev\n" + + "kPlnIbdjYOK1v5RJn2ZRgCafj8Bc/9GnfQ1uE7P9dRkC9ZQwvb6Eh6f4RT7gaOPX\n" + + "UXSXwtr96xdXDvtlJqWx13YQPnSGXUNNT1NH8bs2Myr9j+I5bUcUGsKsGheZoib3\n" + + "6IFINss+ouOhZ+HP6ganS5cQVsUGk5u6BT6oH9VgwfVMjpDqmRkwc6UJmiij/Nz4\n" + + "NOLOx2tivUjhk0eTPUaErUqYipGBSuwww6Linc/0IAIxGJ2k0J3Qz9PthJzG0P47\n" + + "J5U5ej6FimnRS6Rrk5Ywk2HNAgMBAAGjggOiMIIDnjAfBgNVHSMEGDAWgBQzZvsv\n" + + "kQXMs2JS78089X4czqcXljAdBgNVHQ4EFgQU9qXify+xtHlQIniZABL1pv7gcb4w\n" + "QQYDVR0RBDowOII2cXVvdmFkaXMtcm9vdC1jYS0zLWczLXJldm9rZWQuY2hhaW4t\n" + "ZGVtb3MuZGlnaWNlcnQuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr\n" + "BgEFBQcDAQYIKwYBBQUHAwIwgZcGA1UdHwSBjzCBjDBEoEKgQIY+aHR0cDovL2Ny\n" + @@ -445,19 +464,21 @@ "MCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBgwYI\n" + "KwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j\n" + "b20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp\n" + - "Q2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0EzRzMuY3J0MAwGA1UdEwEB/wQCMAAw\n" + - "ggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQApeb7wnjk5IfBWc59jpXflvld9nGAK\n" + - "+PlNXSZcJV3HhAAAAXcgfZ+yAAAEAwBGMEQCIC/jlb+hFwAO0CDUL1hJSIQ9QZOH\n" + - "y0fR4gQ3dIXicm26AiAeYJl/ldEn2ojtlL5SYlkpMyf0ry6dNVP0iD8ctUNyngB3\n" + - "ACJFRQdZVSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABdyB9oAUAAAQDAEgw\n" + - "RgIhAMc2AQO/4o79MHwNZAaAFicxyvLCxjKbmR2kPxmL6oSUAiEA1ue6oGS9cIoy\n" + - "gTYMxvrLLcETbvapKRFu49dUeger7aUwDQYJKoZIhvcNAQELBQADggEBAG9vJ2sF\n" + - "Q/guZdJr8tnMcHNISmZSTCXPvc20kjkVF0M0kW979sskISxEmV9pI49FJqQB1hoz\n" + - "4YJhtOKAg5a9PsvOlMaeM/QNtGHdIf+BKJelpH38klHZ51zMPoWJZVDs+FX1s2fZ\n" + - "O9kJyU6u22eKhsea2Zt726sIQpL+d4cfBqyXWdUBFp+Kapa/tYhVYW5wo3lxGdf+\n" + - "ZgtZMd8tRrYtqD7Zz4fxB9SQj4uqbUydb6n95CR4agO+yNH0mzkD3csoeFfTyKkU\n" + - "93P11+3GMBIMY+Tqtm37eDQlZiJZt8zxdjQLO8oM8MgwimKvNeOIdETvZq6dHu8L\n" + - "d9QqGEKe5acHUL0=\n" + + "Q2VydFF1b1ZhZGlzVExTSUNBUVZSb290Q0EzRzMuY3J0MAkGA1UdEwQCMAAwggF9\n" + + "BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB1AOg+0No+9QY1MudXKLyJa8kD08vREWvs\n" + + "62nhd31tBr1uAAABf1wc0LIAAAQDAEYwRAIgdmF6UFe2jgbM3FjYRMmcNaXfpleT\n" + + "E8hmYfmAVy5lSoUCIDPCV27IP9wpdGoxnnCMBwuekg6E4SB0lj49+o9OHHjDAHUA\n" + + "Nc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kwAAAF/XBzQ0QAABAMARjBE\n" + + "AiBO6vYHFci7OWvqDHRlgTn+Q6zNG/LysZEOlrO4W8ZZ2gIgDY5+qjlar3esPN0b\n" + + "JUR5vfITl7UiZoqINJSm1gZ4Nm4AdwCzc3cH4YRQ+GOG1gWp3BEJSnktsWcMC4fc\n" + + "8AMOeTalmgAAAX9cHNDdAAAEAwBIMEYCIQCB52OPhdnYybsWzmkdSGSbgQVmS0V7\n" + + "ZumbThJSJwpuiwIhAP+JRx+Eu3MYRp5iyLb+xlWqghMnDnF9aCfm1VuW4aDuMA0G\n" + + "CSqGSIb3DQEBCwUAA4IBAQBO/4LljBpMGYYxBang12UIQ+FIjxAfKqqIklSa+du2\n" + + "ea0VHqaRrdfh/aTxzb0WaU++bgQN+MeHmQdvwYSgAyU/lY7mIvDTNxFOO6IG2vfR\n" + + "+JAUnS9iVUQ1rXHU72cxUsne5aRyLQ0W/2Zayx85O6/C9gIUJgJVRuk0dTPZ6tnq\n" + + "FoW1S4GwqEpzTuJU8rP5IvMYoYo8jItpjzS0W90gtDvev/XBRs1ig28Ky7ZS5AtQ\n" + + "S2Q6Ikg9YzegE9YNj2wqdZnEneoce0G1InysM/geY1BZ57G9RAUZkzWVTJRLJgbg\n" + + "2nWSqpQJ765gg9JdsRo+zqj1kUBbUYoTSlaAJG6ucrlB\n" + "-----END CERTIFICATE-----"; public void runTest(ValidatePathWithParams pathValidator) @@ -469,6 +490,6 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Wed Jan 20 07:51:03 PST 2021", System.out); + "Tue Mar 08 11:23:06 PST 2022", System.out); } } diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/java2d/cmm/ColorConvertOp/UnexpectedSourceImageSize.java openjdk-17-17.0.6+10/test/jdk/sun/java2d/cmm/ColorConvertOp/UnexpectedSourceImageSize.java --- openjdk-17-17.0.5+8/test/jdk/sun/java2d/cmm/ColorConvertOp/UnexpectedSourceImageSize.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/java2d/cmm/ColorConvertOp/UnexpectedSourceImageSize.java 2023-01-10 13:21:55.000000000 +0000 @@ -44,6 +44,7 @@ * @test * @bug 8264666 * @summary No exception or errors should occur in ColorConvertOp.filter(). + * @run main/othervm/timeout=600 UnexpectedSourceImageSize */ public final class UnexpectedSourceImageSize { diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java openjdk-17-17.0.6+10/test/jdk/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java --- openjdk-17-17.0.5+8/test/jdk/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/java2d/DirectX/OnScreenRenderingResizeTest/OnScreenRenderingResizeTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2022, 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,25 +25,21 @@ * @key headful * @bug 6664068 6666931 * @summary Tests that resizing a window to which a tight loop is rendering - * doesn't produce artifacts or crashes - * @author Dmitri.Trembovetski@sun.com: area=Graphics + * doesn't produce artifacts or crashes * @run main/othervm OnScreenRenderingResizeTest * @run main/othervm -Dsun.java2d.d3d=false OnScreenRenderingResizeTest */ import java.awt.AWTException; import java.awt.Color; -import java.awt.EventQueue; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; -import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.awt.EventQueue; import java.awt.image.BufferedImage; import java.awt.image.VolatileImage; import java.io.File; @@ -52,19 +48,33 @@ public class OnScreenRenderingResizeTest { - private static volatile boolean done = false; private static volatile boolean nocheck = false; - private static final int FRAME_W = 256; - private static final int FRAME_H = 256; - private static final int IMAGE_W = 128; - private static final int IMAGE_H = 128; + private static int FRAME_W; + private static int FRAME_H; + private static int IMAGE_W; + private static int IMAGE_H; + private static final int tolerance = 12; private static long RUN_TIME = 1000*20; private static final Color renderColor = Color.green; private static final Color bgColor = Color.white; - public static void main(String[] args) { + private static Frame frame; + + private static void createAndShowGUI() { + frame = new Frame() { + public void paint(Graphics g) {} + public void update(Graphics g) {} + }; + frame.setBackground(bgColor); + frame.setUndecorated(true); + frame.setAlwaysOnTop(true); + frame.pack(); + frame.setVisible(true); + } + + public static void main(String[] args) throws Exception { for (String arg : args) { if ("-inf".equals(arg)) { @@ -74,126 +84,138 @@ System.err.println("Test will not check rendering results"); nocheck = true; } else { - System.err.println("Usage: OnScreenRenderingResizeTest [-inf][-nocheck]"); + System.err.println("Usage: OnScreenRenderingResizeTest" + + " [-inf][-nocheck]"); } } - BufferedImage output = - new BufferedImage(IMAGE_W, IMAGE_H, BufferedImage.TYPE_INT_RGB); - output.setAccelerationPriority(0.0f); - Graphics g = output.getGraphics(); - g.setColor(renderColor); - g.fillRect(0, 0, output.getWidth(), output.getHeight()); - - final Frame frame = new Frame("OnScreenRenderingResizeTest") { - public void paint(Graphics g) {} - public void update(Graphics g) {} - }; - frame.setBackground(bgColor); - frame.setUndecorated(true); - frame.pack(); - - GraphicsConfiguration gc = frame.getGraphicsConfiguration(); - Rectangle gcBounds = gc.getBounds(); - frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, FRAME_W, FRAME_H); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - done = true; - } - }); try { EventQueue.invokeAndWait(new Runnable() { public void run() { - frame.setVisible(true); + createAndShowGUI(); } }); - // wait for Vista's effects to complete Thread.sleep(2000); } catch (Exception ex) { ex.printStackTrace(); } - int maxW = gcBounds.width /2; - int maxH = gcBounds.height/2; - int minW = frame.getWidth(); - int minH = frame.getHeight(); - int incW = 10, incH = 10, cnt = 0; - Robot robot = null; - if (!nocheck && gc.getColorModel().getPixelSize() > 8) { - try { - robot = new Robot(); - } catch (AWTException ex) { - System.err.println("Robot creation failed, continuing."); + try { + GraphicsConfiguration gc = frame.getGraphicsConfiguration(); + Rectangle gcBounds = gc.getBounds(); + FRAME_W = (gcBounds.width / 4); + FRAME_H = (gcBounds.height / 4); + IMAGE_W = (gcBounds.width / 8); + IMAGE_H = (gcBounds.height / 8); + frame.setBounds(gcBounds.width / 4, gcBounds.height / 4, + FRAME_W, FRAME_H); + + BufferedImage output = + new BufferedImage(IMAGE_W, IMAGE_H, + BufferedImage.TYPE_INT_RGB); + output.setAccelerationPriority(0.0f); + Graphics g = output.getGraphics(); + g.setColor(renderColor); + g.fillRect(0, 0, IMAGE_W, IMAGE_H); + + int maxW = gcBounds.width / 2; + int maxH = gcBounds.height / 2; + int minW = FRAME_W; + int minH = FRAME_H; + int incW = 10, incH = 10, cnt = 0; + Robot robot = null; + if (!nocheck && gc.getColorModel().getPixelSize() > 8) { + try { + robot = new Robot(); + robot.setAutoDelay(100); + robot.mouseMove(0,0); + } catch (AWTException ex) { + System.err.println("Robot creation failed, continuing."); + } + } else { + System.err.println("No screen rendering checks."); } - } else { - System.err.println("No screen rendering checks."); - } - - VolatileImage vi = gc.createCompatibleVolatileImage(512, 512); - vi.validate(gc); - - long timeStarted = System.currentTimeMillis(); - while (!done && (System.currentTimeMillis() - timeStarted) < RUN_TIME) { + VolatileImage vi = gc. + createCompatibleVolatileImage(IMAGE_W, IMAGE_H); + vi.validate(gc); + long timeStarted = System.currentTimeMillis(); + while ((System.currentTimeMillis() - timeStarted) < RUN_TIME) { - if (++cnt > 100) { - int w = frame.getWidth() + incW; - int h = frame.getHeight() + incH; - if (w < minW || w > maxW ) { - incW = -incW; + if (++cnt > 100) { + int w = frame.getWidth() + incW; + int h = frame.getHeight() + incH; + if (w < minW || w > maxW ) { + incW = -incW; + } + if (h < minH || h > maxH ) { + incH = -incH; + } + frame.setSize(w, h); + if (robot != null) { + robot.waitForIdle(); + } + cnt = 0; } - if (h < minH || h > maxH ) { - incH = -incH; + // try to put the device into non-default state, for example, + // this operation below will set the transform + vi.validate(gc); + Graphics2D vig = (Graphics2D)vi.getGraphics(); + vig.rotate(30.0f, IMAGE_W/2, IMAGE_H/2); + vig.drawImage(output, 0, 0, + IMAGE_W, IMAGE_H, null); + + frame.getGraphics(). + drawImage(output, 0, 0, null); + if (cnt == 90 && robot != null) { + robot.waitForIdle(); + // area where we blit and should be either white or green + Point p = frame.getLocationOnScreen(); + p.translate(10, 10); + BufferedImage bi = + robot.createScreenCapture( + new Rectangle(p.x, p.y, + (IMAGE_W / 2), (IMAGE_H / 2))); + int accepted1[] = {Color.white.getRGB(), + Color.green.getRGB()}; + checkBI(bi, accepted1); + + // the area where we didn't render should stay white + robot.waitForIdle(); + p = frame.getLocationOnScreen(); + p.translate(10, IMAGE_H + 10); + bi = robot.createScreenCapture( + new Rectangle(p.x, p.y, + frame.getWidth() - 20, + frame.getHeight() - 20 - (IMAGE_H))); + int accepted2[] = { Color.white.getRGB() }; + checkBI(bi, accepted2); } - frame.setSize(w, h); - cnt = 0; - } - - // try to put the device into non-default state, for example, - // this operation below will set the transform - vi.validate(gc); - Graphics2D vig = (Graphics2D)vi.getGraphics(); - vig.rotate(30.0f, vi.getWidth()/2, vi.getHeight()/2); - vig.drawImage(output, 0, 0, - vi.getWidth(), vi.getHeight(), null); - - Insets in = frame.getInsets(); - frame.getGraphics().drawImage(output, in.left, in.top, null); - if (cnt == 90 && robot != null) { - robot.waitForIdle(); - // area where we blitted to should be either white or green - Point p = frame.getLocationOnScreen(); - p.translate(in.left+10, in.top+10); - BufferedImage bi = - robot.createScreenCapture( - new Rectangle(p.x, p.y, IMAGE_W/2, IMAGE_H/2)); - int accepted1[] = { Color.white.getRGB(), Color.green.getRGB()}; - checkBI(bi, accepted1); - - // the are where we didn't render should stay white - p = frame.getLocationOnScreen(); - p.translate(in.left, in.top+IMAGE_H+5); - bi = robot.createScreenCapture( - new Rectangle(p.x, p.y, - frame.getWidth()-in.left-in.right, - frame.getHeight()-in.top-in.bottom-5-IMAGE_H)); - int accepted2[] = { Color.white.getRGB() }; - checkBI(bi, accepted2); + Thread.yield(); } - - Thread.yield(); + } finally { + frame.dispose(); } - frame.dispose(); System.out.println("Test Passed"); } private static void checkBI(BufferedImage bi, int accepted[]) { for (int x = 0; x < bi.getWidth(); x++) { for (int y = 0; y < bi.getHeight(); y++) { - int pix = bi.getRGB(x, y); + int actual = bi.getRGB(x, y); + int alpha = (actual >> 24) & 0xFF; + int red = (actual >> 16) & 0xFF; + int green = (actual >> 8) & 0xFF; + int blue = (actual) & 0xFF; boolean found = false; for (int acc : accepted) { - if (pix == acc) { + int accAlpha = (acc >> 24) & 0xFF; + int accRed = (acc >> 16) & 0xFF; + int accGreen = (acc >> 8) & 0xFF; + int accBlue = (acc) & 0xFF; + if (!(Math.abs(alpha - accAlpha) > tolerance || + Math.abs(red - accRed) > tolerance || + Math.abs(green - accGreen) > tolerance || + Math.abs(blue - accBlue) > tolerance)) { found = true; break; } @@ -204,10 +226,10 @@ ImageIO.write(bi, "png", new File(name)); System.out.println("Screen shot file: " + name); } catch (IOException ex) {} - throw new RuntimeException("Test failed at " + x + "-" + y + - " rgb=0x" + Integer.toHexString(pix)); + " rgb=0x" + Integer. + toHexString(actual)); } } } diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/java2d/GdiRendering/ClipShapeRendering.java openjdk-17-17.0.6+10/test/jdk/sun/java2d/GdiRendering/ClipShapeRendering.java --- openjdk-17-17.0.5+8/test/jdk/sun/java2d/GdiRendering/ClipShapeRendering.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/java2d/GdiRendering/ClipShapeRendering.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2003, 2022, 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 4925447 4887054 8285604 + * @key headful + * @summary verifies that most basic rendering operations going are successfully + * clipped against a complex clip shape + * @run main ClipShapeRendering +*/ + +/** + * This test creates a complex clip shape (basically, a rectangular hole + * cut out of the center of the rendering area) and then cycles through + * various rendering primitives (image copies, lines, text, and shapes) + * under various situations (default, scaled transform, and wide lines). + * After all of that, Robot is used to check whether the clip shape has + * been disturbed by any of the rendering (no pixels from the rendering + * operations should have done anything inside the clipped-out area); the + * test passes or fails based on whether the clip shape is undisturbed. + * + * There is a performance-test version of this app which runs all of the + * tests in loops and times the results. This can be useful to see, for + * example, the difference in performance between old and new internal + * implementations of this clip-shape situation. To run the performance + * test, run ClipShapeRendering -perf. + */ + +import java.awt.AWTException; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Robot; +import java.awt.Stroke; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; +import java.awt.geom.GeneralPath; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.WritableRaster; + + +public class ClipShapeRendering extends Frame { + BufferedImage image; + BufferedImage imageBM; + + static Image offScreenImage; + static boolean timeToRun = false; + static Color imageColor = Color.red; + static Color fillColor = Color.blue; + static boolean perfMode = false; + static boolean showCapture = false; + static Rectangle clipRect = new Rectangle(100, 100, 100, 100); + + // move away from cursor + private final static int OFFSET_X = 20; + private final static int OFFSET_Y = 20; + + public ClipShapeRendering() { + super("On-screen rendering test frame"); + } + + public void initImages(Color imageColor) { + int w = getWidth(); + int h = getHeight(); + + ColorModel cm = new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000); + WritableRaster wr = + cm.createCompatibleWritableRaster(w, h); + imageBM = new BufferedImage(cm, wr, + cm.isAlphaPremultiplied(), null); + Graphics g2 = imageBM.createGraphics(); + g2.setColor(imageColor); + g2.fillRect(0, 0, w, h); + + image = new BufferedImage(w, h, + BufferedImage.TYPE_INT_RGB); + g2 = image.createGraphics(); + g2.setColor(imageColor); + g2.fillRect(0,0, w, h); + g2.dispose(); + + offScreenImage = createImage(w, h); + } + + public void paint(Graphics g) { + synchronized (this) { + timeToRun = true; + notifyAll(); + } + } + + public void runTests() { + initImages(imageColor); + + // run off-screen test + System.out.println("Running OFF-SCREEN tests.."); + runTest(offScreenImage.getGraphics()); + + // run on-screen test + System.out.println("Running ON-SCREEN tests.."); + runTest(getGraphics()); + } + + /** + * Set various parameters on the Graphics object and call the + * rendering loop with each variation + */ + public void runTest(Graphics g) { + int w = getWidth(); + int h = getHeight(); + Area area = new Area( new Rectangle(0,0, w, h)); + area.subtract(new Area(clipRect)); + // Fill completely with background color + g.setColor(fillColor); + g.fillRect(0, 0, w, h); + + // Set the clip shape + g.setClip(area); + + // Now perform various rendering operations + g.setColor(Color.black); + Graphics2D g2 = (Graphics2D)g; + if (perfMode) { + System.out.println("Default Graphics Results:"); + System.out.println("-------------------------"); + } + renderingLoop(g2); + + if (perfMode) { + System.out.println("Scaling Transform Results:"); + System.out.println("-------------------------"); + } + AffineTransform oldXform = g2.getTransform(); + g2.scale(.9, 1.15); + renderingLoop(g2); + g2.setTransform(oldXform); + + if (perfMode) { + System.out.println("Wide Lines Results:"); + System.out.println("-------------------"); + } + Stroke oldStroke = g2.getStroke(); + g2.setStroke(new BasicStroke(5.0f)); + renderingLoop(g2); + g2.setStroke(oldStroke); + } + + public void renderingLoop(Graphics2D g) { + int numReps = 1; + int numTextReps = 1; + long start, end; + if (perfMode) { + numReps = 1000; + numTextReps = 50; + } + int w = getWidth(); + int h = getHeight(); + + // Image copies + robot.waitForIdle(); + start = System.currentTimeMillis(); + for (int i = 0; i < numReps; ++i) { + g.drawImage(image, 0, 0, null); + g.drawImage(image, -10, -10, null); + g.drawImage(image, 50, 50, null); + g.drawImage(image, 40, 10, null); + } + for (int i = 0; i < numReps; ++i) { + g.drawImage(imageBM, 0, 0, Color.yellow, null); + g.drawImage(imageBM, -10, -10, Color.yellow, null); + g.drawImage(imageBM, 50, 50, Color.yellow, null); + g.drawImage(imageBM, 40, 10, Color.yellow, null); + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("Image Copies : " + (end - start) + " ms"); + } + + // Image scales + start = System.currentTimeMillis(); + for (int i = 0; i < numReps; ++i) { + g.drawImage(image, 0, 0, 500, 500, null); + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("Image scales : " + (end - start) + " ms"); + } + + // Lines + start = System.currentTimeMillis(); + for (int i = 0; i < numReps; ++i) { + g.drawLine(0, 0, w, h); + g.drawLine(0, h, w, 0); + g.drawLine(0, h / 2, w, h / 2); + g.drawLine(w / 2, 0, w / 2, h); + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("drawLine : " + (end - start) + " ms"); + } + + // Text + + // Non-AA + start = System.currentTimeMillis(); + for (int i = 0; i < numTextReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawString("This is a string, this is only a string", x, + y); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("Text Non-AA : " + (end - start) + " ms"); + } + // Anti-Aliased + Graphics2D g2 = (Graphics2D)g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + start = System.currentTimeMillis(); + for (int i = 0; i < numTextReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawString("This is a string, this is only a string", x, + y); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("Text General AA: " + (end - start) + " ms"); + } + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + // Text AA + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + start = System.currentTimeMillis(); + for (int i = 0; i < numTextReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawString("This is a string, this is only a string", x, + y); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("Text textAA : " + (end - start) + " ms"); + } + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); + + // Arcs + start = System.currentTimeMillis(); + if (numReps > 1) { + numReps /= 10; + } + for (int i = 0; i < numReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawArc(x, y, 30, 30, 0, 45); + g.fillArc(x, y, 25, 25, 0, 45); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("arcs : " + (end - start) + " ms"); + } + + // Ovals + start = System.currentTimeMillis(); + if (numReps > 1) { + numReps /= 10; + } + for (int i = 0; i < numReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawOval(x, y, 20, 20); + g.fillOval(x, y, 15, 15); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("ovals : " + (end - start) + " ms"); + } + + // Rects + start = System.currentTimeMillis(); + for (int i = 0; i < numReps; ++i) { + for (int x = 0; x < w; x += 20) { + for (int y = 0; y < h; y += 17) { + g.drawRect(x, y, 20, 20); + g.fillRect(x, y, 18, 18); + } + } + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("rects : " + (end - start) + " ms"); + } + + // GeneralPath rendering + GeneralPath drawGP = new GeneralPath(); + for (int i = 0; i < 30; ++i) { + Rectangle rect = new Rectangle(5 * i, 2 * i, 27, 19); + drawGP.append(rect, false); + } + GeneralPath fillGP = new GeneralPath(); + for (int i = 0; i < 30; ++i) { + Rectangle rect = new Rectangle(5 * i, 100 + 2 * i, 27, 19); + fillGP.append(rect, false); + } + Graphics2D g2d = (Graphics2D)g; + start = System.currentTimeMillis(); + for (int i = 0; i < numReps; ++i) { + g2d.draw(drawGP); + g2d.fill(fillGP); + } + robot.waitForIdle(); + end = System.currentTimeMillis(); + if (perfMode) { + System.out.println("GeneralPath : " + (end - start) + " ms"); + } + + } + + public static void usage() { + System.err.println("java ClipShapeRendering [-perf] [-show]"); + System.err.println(" -perf : runs performance benchmark (1000 reps)"); + System.err.println(" -show : shows a frame with captured clip area"); + System.exit(1); + } + + public static boolean checkResult(BufferedImage clientPixels) { + int pixels[] = new int[clipRect.width * clipRect.height]; + clientPixels.getRGB(0, 0, clipRect.width, + clipRect.height, pixels, 0, + clipRect.width); + int pixelIndex = 0; + for (int row = 0; row < clipRect.height; ++row) { + for (int col = 0; col < clipRect.width; ++col) { + if (!(new Color(pixels[pixelIndex])).equals(fillColor)) { + System.err.println("Incorrect color " + + Integer.toHexString(pixels[pixelIndex]) + + " instead of " + + Integer.toHexString(fillColor.getRGB()) + + " in pixel (" + (clipRect.x + col) + + ", " + (clipRect.y + row) + ")"); + return false; + } + pixelIndex++; + } + } + return true; + } + + static volatile Robot robot; + public static void main(String args[]) throws Exception { + + for (int i = 0; i < args.length; ++i) { + if (args[i].equals("-perf")) { + perfMode = true; + } else if (args[i].equals("-show")) { + showCapture = true; + } else { + usage(); + } + } + + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Can't create robot: " + e); + } + + ClipShapeRendering clipTest = new ClipShapeRendering(); + clipTest.setSize(300, 300); + clipTest.setLocationRelativeTo(null); + clipTest.setAlwaysOnTop(true); + clipTest.setVisible(true); + try { + synchronized (clipTest) { + while (!timeToRun) { + clipTest.wait(300); + } + } + } catch (InterruptedException e) {} + + clipTest.runTests(); + + // check off-screen rendering; + BufferedImage offScreenClientPixels = + (BufferedImage)clipTest.createImage(clipRect.width, + clipRect.height); + Graphics clientG = offScreenClientPixels.getGraphics(); + clientG.drawImage(offScreenImage, + 0, 0, clipRect.width, clipRect.height, + clipRect.x, clipRect.y, + clipRect.x + clipRect.width, + clipRect.y + clipRect.height, + null); + if (showCapture) { + CaptureFrame f = + new CaptureFrame("OffScreen Image", offScreenImage); + f.setVisible(true); + } + + // check onscreen rendering + Point clientLoc = clipTest.getLocationOnScreen(); + Rectangle r = (Rectangle)clipRect.clone(); + r.translate(clientLoc.x, clientLoc.y); + + // move mouse cursor away from captured region as in some system + // cursor remain visible in composite captured image + robot.mouseMove(r.x - OFFSET_X, r.y - OFFSET_Y); + robot.waitForIdle(); + BufferedImage onScreenClientPixels = robot.createScreenCapture(r); + try { Thread.sleep(1000); } catch (Exception e) {} + if (showCapture) { + CaptureFrame f = + new CaptureFrame("Onscreen clip area", onScreenClientPixels); + f.setVisible(true); + } else { + clipTest.dispose(); + } + + + System.out.print("Checking results for off-screen rendering.."); + boolean offScreenPassed = checkResult(offScreenClientPixels); + System.out.println("done."); + + System.out.print("Checking results for on-screen rendering.."); + boolean onScreenPassed = checkResult(onScreenClientPixels); + System.out.println("done."); + if (!offScreenPassed || !onScreenPassed) { + javax.imageio.ImageIO.write(offScreenClientPixels, "png", new java.io.File("offscreen.png")); + javax.imageio.ImageIO.write(onScreenClientPixels, "png", new java.io.File("onscreen.png")); + throw new RuntimeException("Test failed. off-screen: " + + (offScreenPassed?"passed":"failed") + + " on-screen: " + + (onScreenPassed?"passed":"failed")); + } + System.out.println("Passed"); + } + + static { + System.setProperty("sun.java2d.pmoffscreen", "true"); + } + +} + +class CaptureFrame extends Frame { + static int x = 300, y = 0; + Image clientPixels; + public CaptureFrame(String title, Image clientPixels) { + super("Capture Frame: " + title); + this.clientPixels = clientPixels; + int w = clientPixels.getWidth(null); + int h = clientPixels.getHeight(null); + setSize(w, h + 30); + setLocation(x, y); + x += w; + if (x + w > 1024) { + x = 300; + y += h; + } + add(new Component() { + public void paint(Graphics g) { + g.drawImage(CaptureFrame.this.clientPixels, 0, 0, null); + } + }); + } +}; diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/java2d/SunGraphics2D/CoordinateTruncationBug.java openjdk-17-17.0.6+10/test/jdk/sun/java2d/SunGraphics2D/CoordinateTruncationBug.java --- openjdk-17-17.0.5+8/test/jdk/sun/java2d/SunGraphics2D/CoordinateTruncationBug.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/java2d/SunGraphics2D/CoordinateTruncationBug.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2003, 2022, 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 4975116 7040022 8023577 8025447 8286624 + * @key headful + * @summary verify the rounding of negative coordinates in Shape objects + * @run main/othervm CoordinateTruncationBug + */ + +import java.awt.Frame; +import java.awt.Canvas; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Robot; +import java.awt.Rectangle; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Color; +import java.awt.AWTException; +import java.awt.geom.Line2D; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; + +public class CoordinateTruncationBug { + static boolean failure; + static boolean verbose; + + static final int W = 80; + static final int H = 80; + + static final Line2D vertline = new Line2D.Float(-0.7f, 0f, -0.7f, H); + static final Line2D horizline = new Line2D.Float(0f, -0.7f, W, -0.7f); + + public static void main(String argv[]) { + verbose = (argv.length > 0); + new Screen().test(); + new BufImg().test(); + new VolImg().test(); + if (failure) { + throw new RuntimeException("Test failed due to 1 or more failures"); + } + } + + public static abstract class Test { + public abstract String getName(); + public abstract void makeDest(); + public abstract void runTest(); + public abstract void dispose(); + public abstract BufferedImage getSnapshot(); + + public void test() { + makeDest(); + runTest(); + dispose(); + } + + public void runTest(Graphics2D g2d) { + g2d.setColor(Color.white); + g2d.fillRect(0, 0, W, H); + + if (!checkAllWhite()) { + System.err.println("Aborting test of "+getName()+ + " due to readback failure!"); + return; + } + + g2d.setColor(Color.red); + g2d.draw(vertline); + g2d.draw(horizline); + if (!checkAllWhite()) { + System.err.println(getName()+" failed!"); + failure = true; + } + } + + public boolean checkAllWhite() { + BufferedImage bimg = getSnapshot(); + if (bimg == null) { + System.err.println(getName()+" returned null snapshot!"); + return false; + } + boolean ret = true; + for (int y = 0; y < H; y++) { + for (int x = 0; x < W; x++) { + int rgb = bimg.getRGB(x, y); + if (rgb != -1) { + System.err.println(getName()+"("+x+", "+y+") == "+ + Integer.toHexString(rgb)); + if (verbose) { + ret = false; + } else { + return false; + } + } + } + } + return ret; + } + } + + public static class Screen extends Test { + Frame frame; + TestCanvas canvas; + + public String getName() { + return "Screen"; + } + + public void makeDest() { + frame = new Frame("Screen test"); + frame.setUndecorated(true); + canvas = new TestCanvas(this); + frame.add(canvas); + frame.pack(); + frame.setLocationRelativeTo(null); + } + + public void runTest() { + frame.show(); + canvas.waitForTest(); + } + + public Graphics2D createGraphics() { + return null; + } + + public BufferedImage getSnapshot() { + // bypass window animation + try { + Thread.sleep(500); + } catch (InterruptedException e) { + }; + + try { + Robot r = new Robot(); + Point p = canvas.getLocationOnScreen(); + return r.createScreenCapture(new Rectangle(p.x, p.y, W, H)); + } catch (AWTException e) { + return null; + } + } + + public void dispose() { + frame.hide(); + frame.dispose(); + } + + public static class TestCanvas extends Canvas { + Test test; + boolean done; + + public TestCanvas(Test test) { + this.test = test; + } + + public Dimension getPreferredSize() { + return new Dimension(W, H); + } + + public synchronized void waitForTest() { + while (!done) { + try { + wait(); + } catch (InterruptedException e) { + System.err.println(getName()+" interrupted!"); + failure = true; + break; + } + } + } + + public void paint(Graphics g) { + if (!done) { + test.runTest((Graphics2D) g); + notifyDone(); + } + } + + public synchronized void notifyDone() { + done = true; + notifyAll(); + } + } + } + + public abstract static class Standalone extends Test { + public abstract Graphics2D createGraphics(); + + public void runTest() { + Graphics2D g2d = createGraphics(); + runTest(g2d); + g2d.dispose(); + } + } + + public static class BufImg extends Standalone { + public BufferedImage bimg; + + public String getName() { + return "BufferedImage"; + } + + public void makeDest() { + bimg = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB); + } + + public Graphics2D createGraphics() { + return bimg.createGraphics(); + } + + public BufferedImage getSnapshot() { + return bimg; + } + + public void dispose() { + } + } + + public static class VolImg extends Standalone { + Frame frame; + VolatileImage vimg; + + public String getName() { + return "VolatileImage"; + } + + public void makeDest() { + frame = new Frame(); + frame.setSize(W, H); + frame.setLocationRelativeTo(null); + frame.show(); + vimg = frame.createVolatileImage(W, H); + } + + public Graphics2D createGraphics() { + return vimg.createGraphics(); + } + + public BufferedImage getSnapshot() { + return vimg.getSnapshot(); + } + + public void dispose() { + vimg.flush(); + frame.hide(); + frame.dispose(); + } + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in openjdk-17-17.0.6+10/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in --- openjdk-17-17.0.5+8/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ -com.sun.management.jmxremote.ssl.enabled.cipher.suites=TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 +com.sun.management.jmxremote.ssl.enabled.cipher.suites=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA com.sun.management.jmxremote.ssl.enabled.protocols=SSLv2Hello,SSLv3,TLSv1 com.sun.management.jmxremote.ssl.need.client.auth=true com.sun.management.jmxremote.authenticate=false -javax.rmi.ssl.client.enabledCipherSuites=TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 +javax.rmi.ssl.client.enabledCipherSuites=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java openjdk-17-17.0.6+10/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java --- openjdk-17-17.0.5+8/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/net/www/http/KeepAliveCache/KeepAliveProperty.java 2023-01-10 13:21:55.000000000 +0000 @@ -40,6 +40,7 @@ public class KeepAliveProperty { static volatile boolean pass = false; + static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); static class Server extends Thread { final ServerSocket server; @@ -138,7 +139,6 @@ public static void main(String args[]) throws Exception { // exercise the logging code - Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); logger.setLevel(Level.FINEST); ConsoleHandler h = new ConsoleHandler(); h.setLevel(Level.FINEST); @@ -171,6 +171,7 @@ if (!expectClose) throw e; } + s.join(); if (!pass) throw new RuntimeException("Failed in server"); diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/pkcs11/Cipher/TestPaddingOOB.java openjdk-17-17.0.6+10/test/jdk/sun/security/pkcs11/Cipher/TestPaddingOOB.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/pkcs11/Cipher/TestPaddingOOB.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/pkcs11/Cipher/TestPaddingOOB.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * 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 8289301 + * @summary P11Cipher should not throw OOB exception during padding when "reqBlockUpdates" == true + * @library /test/lib .. + * @run main/othervm TestPaddingOOB + */ + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.security.Key; +import java.security.Provider; + +public class TestPaddingOOB extends PKCS11Test { + + public static void main(String[] args) throws Exception { + main(new TestPaddingOOB(), args); + } + + @Override + public void main(Provider p) throws Exception { + KeyGenerator kg = KeyGenerator.getInstance("AES", p); + Key key = kg.generateKey(); + + Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding", p); + int bs = c.getBlockSize(); + + // Test with arrays + byte[] plainArr = new byte[bs]; + Arrays.fill(plainArr, (byte) 'a'); + c.init(Cipher.ENCRYPT_MODE, key); + byte[] encArr = new byte[c.getOutputSize(plainArr.length)]; + int off = c.update(plainArr, 0, 1, encArr, 0); + off += c.doFinal(plainArr, 1, plainArr.length - 1, encArr, off); + if (off != 2 * bs) { + throw new Exception("Unexpected encrypted size (array): " + off); + } + c.init(Cipher.DECRYPT_MODE, key); + byte[] plainArr2 = new byte[c.getOutputSize(encArr.length)]; + off = c.doFinal(encArr, 0, encArr.length, plainArr2, 0); + if (off != bs) { + throw new Exception("Unexpected decrypted size (array): " + off); + } + if (!Arrays.equals(plainArr, Arrays.copyOfRange(plainArr2, 0, off))) { + throw new Exception("Invalid decrypted data (array)"); + } + + // Test with buffers + ByteBuffer plainBuf = ByteBuffer.allocate(bs); + Arrays.fill(plainArr, (byte) 'b'); + plainBuf.put(plainArr); + plainBuf.flip(); + c.init(Cipher.ENCRYPT_MODE, key); + ByteBuffer encBuf = ByteBuffer.allocate(c.getOutputSize(plainBuf.limit())); + plainBuf.limit(1); + off = c.update(plainBuf, encBuf); + plainBuf.limit(bs); + off += c.doFinal(plainBuf, encBuf); + if (off != 2 * bs) { + throw new Exception("Unexpected encrypted size (buffer): " + off); + } + encBuf.flip(); + c.init(Cipher.DECRYPT_MODE, key); + ByteBuffer plainBuf2 = ByteBuffer.allocate(c.getOutputSize(encBuf.limit())); + off = c.doFinal(encBuf, plainBuf2); + if (off != bs) { + throw new Exception("Unexpected decrypted size (buffer): " + off); + } + plainBuf2.flip(); + plainBuf2.get(plainArr2, 0, off); + if (!Arrays.equals(plainArr, Arrays.copyOfRange(plainArr2, 0, off))) { + throw new Exception("Invalid decrypted data (buffer)"); + } + } + +} diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/pkcs11/Signature/TestDSAKeyLength.java openjdk-17-17.0.6+10/test/jdk/sun/security/pkcs11/Signature/TestDSAKeyLength.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/pkcs11/Signature/TestDSAKeyLength.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/pkcs11/Signature/TestDSAKeyLength.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2022, 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 @@ -48,7 +48,7 @@ @Override protected boolean skipTest(Provider provider) { - if (isNSS(provider) && getNSSVersion() >= 3.14) { + if (isNSS(provider) && (getNSSVersion() == 0.0 || getNSSVersion() >= 3.14)) { System.out.println("Skip testing NSS " + getNSSVersion()); return true; } diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, 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 @@ -30,7 +30,7 @@ /* * @test - * @bug 8274736 + * @bug 8274736 8277970 * @summary Concurrent read/close of SSLSockets causes SSLSessions to be * invalidated unnecessarily * @library /javax/net/ssl/templates diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketSSLEngineCloseInbound.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2011, 2022, 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. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 8273553 8253368 + * @summary sun.security.ssl.SSLEngineImpl.closeInbound also has similar error + * of JDK-8253368 + * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.3 + * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.2 + * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.1 + * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1 + * @run main/othervm SSLSocketSSLEngineCloseInbound TLS + */ + +/** + * A SSLSocket/SSLEngine interop test case. This is not the way to + * code SSLEngine-based servers, but works for what we need to do here, + * which is to make sure that SSLEngine/SSLSockets can talk to each other. + * SSLEngines can use direct or indirect buffers, and different code + * is used to get at the buffer contents internally, so we test that here. + * + * The test creates one SSLSocket (client) and one SSLEngine (server). + * The SSLSocket talks to a raw ServerSocket, and the server code + * does the translation between byte [] and ByteBuffers that the SSLEngine + * can use. The "transport" layer consists of a Socket Input/OutputStream + * and two byte buffers for the SSLEngines: think of them + * as directly connected pipes. + * + * Again, this is a *very* simple example: real code will be much more + * involved. For example, different threading and I/O models could be + * used, transport mechanisms could close unexpectedly, and so on. + * + * When this application runs, notice that several messages + * (wrap/unwrap) pass before any application data is consumed or + * produced. (For more information, please see the SSL/TLS + * specifications.) There may several steps for a successful handshake, + * so it's typical to see the following series of operations: + * + * client server message + * ====== ====== ======= + * write() ... ClientHello + * ... unwrap() ClientHello + * ... wrap() ServerHello/Certificate + * read() ... ServerHello/Certificate + * write() ... ClientKeyExchange + * write() ... ChangeCipherSpec + * write() ... Finished + * ... unwrap() ClientKeyExchange + * ... unwrap() ChangeCipherSpec + * ... unwrap() Finished + * ... wrap() ChangeCipherSpec + * ... wrap() Finished + * read() ... ChangeCipherSpec + * read() ... Finished + */ +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.*; +import java.io.*; +import java.net.*; +import java.security.*; +import java.nio.*; + +public class SSLSocketSSLEngineCloseInbound { + + /* + * Enables logging of the SSL/TLS operations. + */ + private static final boolean logging = true; + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private final SSLContext sslc; + private SSLEngine serverEngine; // server-side SSLEngine + private SSLSocket clientSocket; + + private final byte[] serverMsg = + "Hi there Client, I'm a Server.".getBytes(); + private final byte[] clientMsg = + "Hello Server, I'm a Client! Pleased to meet you!".getBytes(); + + private ByteBuffer serverOut; // write side of serverEngine + private ByteBuffer serverIn; // read side of serverEngine + + private volatile Exception clientException; + private volatile Exception serverException; + + /* + * For data transport, this example uses local ByteBuffers. + */ + private ByteBuffer cTOs; // "reliable" transport client->server + private ByteBuffer sTOc; // "reliable" transport server->client + + /* + * The following is to set up the keystores/trust material. + */ + private static final String pathToStores = "../../../../javax/net/ssl/etc"; + private static final String keyStoreFile = "keystore"; + private static final String trustStoreFile = "truststore"; + private static final String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + private static final String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + /* + * Main entry point for this test. + */ + public static void main(String[] args) throws Exception { + String protocol = args[0]; + + // reset security properties to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.tls.disabledAlgorithms", ""); + Security.setProperty("jdk.certpath.disabledAlgorithms", ""); + + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + /* + * Run the tests with direct and indirect buffers. + */ + SSLSocketSSLEngineCloseInbound test = + new SSLSocketSSLEngineCloseInbound(protocol); + log("-------------------------------------"); + log("Testing " + protocol + " for direct buffers ..."); + test.runTest(true); + + log("---------------------------------------"); + log("Testing " + protocol + " for indirect buffers ..."); + test.runTest(false); + + log("Test Passed."); + } + + /* + * Create an initialized SSLContext to use for these tests. + */ + public SSLSocketSSLEngineCloseInbound(String protocol) throws Exception { + + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + + char[] passphrase = "passphrase".toCharArray(); + + try (FileInputStream keyFile = new FileInputStream(keyFilename); + FileInputStream trustFile = new FileInputStream(trustFilename)) { + ks.load(keyFile, passphrase); + ts.load(trustFile, passphrase); + } + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance(protocol); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + sslc = sslCtx; + } + + /* + * Run the test. + * + * Sit in a tight loop, with the server engine calling wrap/unwrap + * regardless of whether data is available or not. We do this until + * we get the application data. Then we shutdown and go to the next one. + * + * The main loop handles all the I/O phases of the SSLEngine's + * lifetime: + * + * initial handshaking + * application data transfer + * engine closing + * + * One could easily separate these phases into separate + * sections of code. + */ + private void runTest(boolean direct) throws Exception { + clientSocket = null; + + // generates the server-side Socket + try (ServerSocket serverSocket = new ServerSocket()) { + serverSocket.setReuseAddress(false); + serverSocket.bind(null); + int port = serverSocket.getLocalPort(); + log("Port: " + port); + Thread thread = createClientThread(port); + + createSSLEngine(); + createBuffers(direct); + + // server-side socket that will read + try (Socket socket = serverSocket.accept()) { + socket.setSoTimeout(500); + + InputStream is = socket.getInputStream(); + OutputStream os = socket.getOutputStream(); + + SSLEngineResult serverResult; // results from last operation + + /* + * Examining the SSLEngineResults could be much more involved, + * and may alter the overall flow of the application. + * + * For example, if we received a BUFFER_OVERFLOW when trying + * to write to the output pipe, we could reallocate a larger + * pipe, but instead we wait for the peer to drain it. + */ + byte[] inbound = new byte[8192]; + byte[] outbound = new byte[8192]; + + while (!isEngineClosed(serverEngine)) { + int len; + + // Inbound data + log("================"); + + // Try reading Client side, even if it's already closed. + try { + len = is.read(inbound); + if (len > 0) { + cTOs.put(inbound, 0, len); + } + } catch (IOException e) { + /* + * swallow IO/SocketTimeoutExceptions. We'll do + * the testing/exit after the unwraps. + */ + } + + cTOs.flip(); + + serverResult = serverEngine.unwrap(cTOs, serverIn); + log("server unwrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + cTOs.compact(); + + // Outbound data + log("----"); + + // After we've received our app bytes, close input side + // and see what happens. Exit the test at the end. + if (serverIn.position() != 0) { + try { + serverEngine.closeInbound(); + throw new Exception( + "No error shutting down client's input"); + } catch (SSLException e) { + System.out.println( + "Server caught the right Exception"); + } + + if (serverEngine.getSession().isValid()) { + System.out.println("Server session is still valid"); + } else { + throw new Exception("Server session is not valid"); + } + + return; + } + + serverResult = serverEngine.wrap(serverOut, sTOc); + log("server wrap: ", serverResult); + runDelegatedTasks(serverResult, serverEngine); + + sTOc.flip(); + + if ((len = sTOc.remaining()) != 0) { + sTOc.get(outbound, 0, len); + os.write(outbound, 0, len); + // Give the other side a chance to process + } + + sTOc.compact(); + } + } catch (Exception e) { + serverException = e; + } finally { + // Wait for the client to join up with us. + if (thread != null) { + thread.join(); + } + } + } finally { + if (serverException != null) { + if (clientException != null) { + serverException.initCause(clientException); + } + throw serverException; + } + if (clientException != null) { + if (serverException != null) { + clientException.initCause(serverException); + } + throw clientException; + } + } + } + + /* + * Create a client thread which does simple SSLSocket operations. + * We'll write and read one data packet. + */ + private Thread createClientThread(final int port) { + + Thread t = new Thread("ClientThread") { + + @Override + public void run() { + // client-side socket + try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory(). + createSocket("localhost", port)) { + clientSocket = sslSocket; + + OutputStream os = sslSocket.getOutputStream(); + + // write(byte[]) goes in one shot. + os.write(clientMsg); + os.flush(); + + try { + sslSocket.shutdownInput(); + throw new Exception( + "No error shutting down client's input"); + } catch (SSLException e) { + System.out.println("Client caught the right Exception"); + } + + if (sslSocket.getSession().isValid()) { + System.out.println("Client session is still valid"); + } else { + throw new Exception("Client's session is not valid"); + } + + // Give server a chance to read before we shutdown via + // the try-with-resources block. + Thread.sleep(2000); + } catch (Exception e) { + clientException = e; + } + } + }; + t.start(); + return t; + } + + /* + * Using the SSLContext created during object creation, + * create/configure the SSLEngines we'll use for this test. + */ + private void createSSLEngine() { + /* + * Configure the serverEngine to act as a server in the SSL/TLS + * handshake. + */ + serverEngine = sslc.createSSLEngine(); + serverEngine.setUseClientMode(false); + serverEngine.getNeedClientAuth(); + } + + /* + * Create and size the buffers appropriately. + */ + private void createBuffers(boolean direct) { + + SSLSession session = serverEngine.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + /* + * We'll make the input buffers a bit bigger than the max needed + * size, so that unwrap()s following a successful data transfer + * won't generate BUFFER_OVERFLOWS. + * + * We'll use a mix of direct and indirect ByteBuffers for + * tutorial purposes only. In reality, only use direct + * ByteBuffers when they give a clear performance enhancement. + */ + if (direct) { + serverIn = ByteBuffer.allocateDirect(appBufferMax + 50); + cTOs = ByteBuffer.allocateDirect(netBufferMax); + sTOc = ByteBuffer.allocateDirect(netBufferMax); + } else { + serverIn = ByteBuffer.allocate(appBufferMax + 50); + cTOs = ByteBuffer.allocate(netBufferMax); + sTOc = ByteBuffer.allocate(netBufferMax); + } + + serverOut = ByteBuffer.wrap(serverMsg); + } + + /* + * If the result indicates that we have outstanding tasks to do, + * go ahead and run them in this thread. + */ + private static void runDelegatedTasks(SSLEngineResult result, + SSLEngine engine) throws Exception { + + if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log("\trunning delegated task..."); + runnable.run(); + } + HandshakeStatus hsStatus = engine.getHandshakeStatus(); + if (hsStatus == HandshakeStatus.NEED_TASK) { + throw new Exception( + "handshake shouldn't need additional tasks"); + } + log("\tnew HandshakeStatus: " + hsStatus); + } + } + + private static boolean isEngineClosed(SSLEngine engine) { + return (engine.isOutboundDone() && engine.isInboundDone()); + } + + /* + * Logging code + */ + private static boolean resultOnce = true; + + private static void log(String str, SSLEngineResult result) { + if (!logging) { + return; + } + if (resultOnce) { + resultOnce = false; + log("The format of the SSLEngineResult is: \n" + + "\t\"getStatus() / getHandshakeStatus()\" +\n" + + "\t\"bytesConsumed() / bytesProduced()\"\n"); + } + HandshakeStatus hsStatus = result.getHandshakeStatus(); + log(str + + result.getStatus() + "/" + hsStatus + ", " + + result.bytesConsumed() + "/" + result.bytesProduced() + + " bytes"); + if (hsStatus == HandshakeStatus.FINISHED) { + log("\t...ready for application data"); + } + } + + private static void log(String str) { + if (logging) { + if (debug) { + System.err.println(str); + } else { + System.out.println(str); + } + } + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/X509TrustManagerImpl/BasicConstraints12.java openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/X509TrustManagerImpl/BasicConstraints12.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/ssl/X509TrustManagerImpl/BasicConstraints12.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/ssl/X509TrustManagerImpl/BasicConstraints12.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022, 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 8293489 + * @summary Accept CAs with BasicConstraints without pathLenConstraint + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; + +import java.io.File; +import java.security.*; +import java.security.cert.*; + +import javax.net.ssl.*; + +public class BasicConstraints12 { + + public static void main(String[] args) throws Exception { + + genkey("-dname CN=TrustAnchor -alias anchor"); + genkey("-dname CN=IntermediateCA -alias ca -ext bc:critical -signer anchor"); + genkey("-dname CN=Server -alias server -signer ca"); + + KeyStore full = KeyStore.getInstance(new File("ks"), "changeit".toCharArray()); + X509Certificate anchor = (X509Certificate) full.getCertificate("anchor"); + X509Certificate ca = (X509Certificate) full.getCertificate("ca"); + X509Certificate server = (X509Certificate) full.getCertificate("server"); + + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + ks.setCertificateEntry("anchor", anchor); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + + X509TrustManager tm = (X509TrustManager)tmf.getTrustManagers()[0]; + + X509Certificate[] chain = new X509Certificate[] {server, ca, anchor}; + + System.out.println("Calling trustmanager..."); + + tm.checkServerTrusted(chain, "RSA"); + System.out.println("Test ok"); + } + + static void genkey(String s) throws Exception { + SecurityTools.keytool("-storepass changeit -keystore ks -genkeypair -keyalg RSA " + s) + .shouldHaveExitValue(0); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java openjdk-17-17.0.6+10/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java 2023-01-10 13:21:55.000000000 +0000 @@ -736,51 +736,6 @@ .shouldMatch("Signature algorithm: .*key.*(disabled)"); } - static void checkWeak(String file) throws Exception { - verify(file) - .shouldHaveExitValue(0) - .shouldNotContain("treated as unsigned"); - verify(file, "-verbose") - .shouldHaveExitValue(0) - .shouldNotContain("treated as unsigned") - .shouldMatch("Digest algorithm: .*(weak)") - .shouldMatch("Signature algorithm: .*(weak)") - .shouldMatch("Timestamp digest algorithm: .*(weak)") - .shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)") - .shouldMatch("Timestamp signature algorithm: .*key.*(weak)"); - verify(file, "-J-Djava.security.debug=jar") - .shouldHaveExitValue(0) - .shouldNotMatch("SignatureException:.*disabled"); - - // keytool should print out warnings when reading or - // generating cert/cert req using legacy algorithms. - String sout = SecurityTools.keytool("-printcert -jarfile " + file) - .stderrShouldContain("The TSA certificate uses a 1024-bit RSA key" + - " which is considered a security risk." + - " This key size will be disabled in a future update.") - .getStdout(); - if (sout.indexOf("weak", sout.indexOf("Timestamp:")) < 0) { - throw new RuntimeException("timestamp not weak: " + sout); - } - } - - static void checkHalfWeak(String file) throws Exception { - verify(file) - .shouldHaveExitValue(0) - .shouldNotContain("treated as unsigned"); - verify(file, "-verbose") - .shouldHaveExitValue(0) - .shouldNotContain("treated as unsigned") - .shouldMatch("Digest algorithm: .*(weak)") - .shouldNotMatch("Signature algorithm: .*(weak)") - .shouldNotMatch("Signature algorithm: .*(disabled)") - .shouldNotMatch("Timestamp digest algorithm: .*(weak)") - .shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)") - .shouldNotMatch("Timestamp signature algorithm: .*(disabled).*(disabled)") - .shouldNotMatch("Timestamp signature algorithm: .*key.*(weak)") - .shouldNotMatch("Timestamp signature algorithm: .*key.*(disabled)"); - } - static void checkMultipleWeak(String file) throws Exception { verify(file) .shouldHaveExitValue(0) diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/tools/keytool/ReadJar.java openjdk-17-17.0.6+10/test/jdk/sun/security/tools/keytool/ReadJar.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/tools/keytool/ReadJar.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/tools/keytool/ReadJar.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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,7 +23,7 @@ /** * @test - * @bug 6890872 8168882 + * @bug 6890872 8168882 8257722 * @summary keytool -printcert to recognize signed jar files * @library /test/lib * @build jdk.test.lib.SecurityTools @@ -42,11 +42,24 @@ import jdk.test.lib.SecurityTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.util.JarUtils; +import java.nio.file.Path; public class ReadJar { + static OutputAnalyzer kt(String cmd, String ks) throws Exception { + return SecurityTools.keytool("-storepass changeit " + cmd + + " -keystore " + ks); + } + + static void gencert(String owner, String cmd) throws Exception { + kt("-certreq -alias " + owner + " -file tmp.req", "ks"); + kt("-gencert -infile tmp.req -outfile tmp.cert " + cmd, "ks"); + kt("-importcert -alias " + owner + " -file tmp.cert", "ks"); + } + public static void main(String[] args) throws Throwable { testWithMD5(); + testCertOutput(); } // make sure that -printcert option works @@ -91,4 +104,87 @@ out.shouldHaveExitValue(0); out.shouldNotContain("Not a signed jar file"); } + + private static void testCertOutput() throws Throwable { + kt("-genkeypair -keyalg rsa -alias e0 -dname CN=E0 " + + "-keysize 512", "ks"); + JarUtils.createJarFile(Path.of("a0.jar"), Path.of("."), Path.of("ks")); + // sign a0.jar file + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + " a0.jar e0") + .shouldHaveExitValue(0); + + SecurityTools.keytool("-printcert -jarfile a0.jar") + .shouldNotContain("Signature:") + .shouldContain("Signer #1:") + .shouldContain("Certificate #1:") + .shouldNotContain("Certificate #2:") + .shouldNotContain("Signer #2:") + .shouldMatch("The certificate uses a 512-bit RSA key.*is disabled") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias ca1 -dname CN=CA1 -ext bc:c " + + "-keysize 512", "ks"); + kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks"); + gencert("e1", "-alias ca1 -ext san=dns:e1"); + + JarUtils.createJarFile(Path.of("a1.jar"), Path.of("."), Path.of("ks")); + // sign a1.jar file + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + " a1.jar e1") + .shouldHaveExitValue(0); + + SecurityTools.keytool("-printcert -jarfile a1.jar") + .shouldNotContain("Signature:") + .shouldContain("Signer #1:") + .shouldContain("Certificate #1:") + .shouldContain("Certificate #2:") + .shouldNotContain("Signer #2:") + .shouldMatch("The certificate #2 uses a 512-bit RSA key.*is disabled") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias ca2 -dname CN=CA2 -ext bc:c " + + "-sigalg SHA1withRSA", "ks"); + kt("-genkeypair -keyalg rsa -alias e2 -dname CN=E2", "ks"); + gencert("e2", "-alias ca2 -ext san=dns:e2"); + + // sign a1.jar file again with different signer + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + " a1.jar e2") + .shouldHaveExitValue(0); + + SecurityTools.keytool("-printcert -jarfile a1.jar") + .shouldNotContain("Signature:") + .shouldContain("Signer #1:") + .shouldContain("Certificate #1:") + .shouldContain("Certificate #2:") + .shouldContain("Signer #2:") + .shouldMatch("The certificate #.* of signer #.*" + "uses the SHA1withRSA.*will be disabled") + .shouldMatch("The certificate #.* of signer #.*" + "uses a 512-bit RSA key.*is disabled") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias e3 -dname CN=E3", + "ks"); + JarUtils.createJarFile(Path.of("a2.jar"), Path.of("."), Path.of("ks")); + // sign a2.jar file + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + " a2.jar e3") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias e4 -dname CN=E4 " + + "-keysize 1024", "ks"); + // sign a2.jar file again with different signer + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + " a2.jar e4") + .shouldHaveExitValue(0); + + SecurityTools.keytool("-printcert -jarfile a2.jar") + .shouldNotContain("Signature:") + .shouldContain("Signer #1:") + .shouldContain("Certificate #1:") + .shouldNotContain("Certificate #2:") + .shouldContain("Signer #2:") + .shouldMatch("The certificate of signer #.*" + "uses a 1024-bit RSA key.*will be disabled") + .shouldHaveExitValue(0); + } } diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/security/tools/keytool/TestSha1Usage.java openjdk-17-17.0.6+10/test/jdk/sun/security/tools/keytool/TestSha1Usage.java --- openjdk-17-17.0.5+8/test/jdk/sun/security/tools/keytool/TestSha1Usage.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/security/tools/keytool/TestSha1Usage.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, 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 8273236 + * @summary Test SHA1 usage SignedJAR + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestSha1Usage { + + static OutputAnalyzer kt(String cmd, String ks) throws Exception { + return SecurityTools.keytool("-storepass changeit " + cmd + + " -keystore " + ks); + } + + public static void main(String[] args) throws Exception { + + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-genkeypair -keyalg rsa -alias ca -dname CN=CA " + + "-ext eku=codeSigning -sigalg SHA1withRSA") + .shouldContain("Warning:") + .shouldMatch("The generated certificate.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks"); + kt("-certreq -alias e1 -file tmp.req", "ks"); + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-gencert -alias ca -infile tmp.req -outfile tmp.cert") + .shouldContain("Warning:") + .shouldMatch("The issuer.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + } +} diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/text/resources/LocaleData.cldr openjdk-17-17.0.6+10/test/jdk/sun/text/resources/LocaleData.cldr --- openjdk-17-17.0.5+8/test/jdk/sun/text/resources/LocaleData.cldr 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/text/resources/LocaleData.cldr 2023-01-10 13:21:55.000000000 +0000 @@ -8394,3 +8394,7 @@ FormatData/de_AT/latn.NumberElements/12=. FormatData/fr/latn.NumberElements/11= FormatData/fr_CH/latn.NumberElements/11=. + +# tzdata2022f +TimeZoneNames/en/America\/Ojinaga/1=Central Standard Time +TimeZoneNames/en/America\/Chihuahua/1=Central Standard Time diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/text/resources/LocaleDataTest.java openjdk-17-17.0.6+10/test/jdk/sun/text/resources/LocaleDataTest.java --- openjdk-17-17.0.5+8/test/jdk/sun/text/resources/LocaleDataTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/text/resources/LocaleDataTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -40,7 +40,7 @@ * 8145136 8145952 8164784 8037111 8081643 7037368 8178872 8185841 8190918 * 8187946 8195478 8181157 8179071 8193552 8202026 8204269 8202537 8208746 * 8209775 8221432 8227127 8230284 8231273 8233579 8234288 8250665 8255086 - * 8251317 8274658 8283277 + * 8251317 8274658 8283277 8296715 * @summary Verify locale data * @modules java.base/sun.util.resources * @modules jdk.localedata diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java openjdk-17-17.0.6+10/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java --- openjdk-17-17.0.5+8/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/util/calendar/zi/TestZoneInfo310.java 2023-01-10 13:21:55.000000000 +0000 @@ -176,11 +176,12 @@ * save time in IANA tzdata. This bug is tracked via JDK-8223388. * * These are the zones/rules that employ negative DST in vanguard - * format (as of 2019a): + * format (as of 2019a), Palestine added in 2022d: * * - Rule "Eire" * - Rule "Morocco" * - Rule "Namibia" + * - Rule "Palestine" * - Zone "Europe/Prague" * * Tehran/Iran rule has rules beyond 2037, in which javazic assumes @@ -196,6 +197,8 @@ zid.equals("Europe/Dublin") || // uses "Eire" rule zid.equals("Europe/Prague") || zid.equals("Asia/Tehran") || // last rule mismatch + zid.equals("Asia/Gaza") || // uses "Palestine" rule + zid.equals("Asia/Hebron") || // uses "Palestine" rule zid.equals("Iran")) { // last rule mismatch continue; } diff -Nru openjdk-17-17.0.5+8/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java openjdk-17-17.0.6+10/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java --- openjdk-17-17.0.5+8/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8181157 8202537 8234347 8236548 8261279 + * @bug 8181157 8202537 8234347 8236548 8261279 8293834 * @modules jdk.localedata * @summary Checks CLDR time zone names are generated correctly at runtime * @run testng/othervm -Djava.locale.providers=CLDR TimeZoneNamesTest @@ -102,6 +102,24 @@ "UTC+04:00", "heure : Astrakhan", "UTC+04:00"}, + {"Europe/Kyiv", Locale.US, "Eastern European Standard Time", + "GMT+02:00", + "Eastern European Summer Time", + "GMT+03:00", + "Eastern European Time", + "GMT+02:00"}, + {"Europe/Kyiv", Locale.FRANCE, "heure normale d\u2019Europe de l\u2019Est", + "UTC+02:00", + "heure d\u2019\u00e9t\u00e9 d\u2019Europe de l\u2019Est", + "UTC+03:00", + "heure d\u2019Europe de l\u2019Est", + "UTC+02:00"}, + {"Europe/Kyiv", Locale.GERMANY, "Osteurop\u00e4ische Normalzeit", + "OEZ", + "Osteurop\u00e4ische Sommerzeit", + "OESZ", + "Osteurop\u00e4ische Zeit", + "OEZ"}, {"Europe/Saratov", Locale.US, "Saratov Standard Time", "GMT+04:00", "Saratov Daylight Time", diff -Nru openjdk-17-17.0.5+8/test/jdk/TEST.ROOT openjdk-17-17.0.6+10/test/jdk/TEST.ROOT --- openjdk-17-17.0.5+8/test/jdk/TEST.ROOT 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/jdk/TEST.ROOT 2023-01-10 13:21:55.000000000 +0000 @@ -11,11 +11,15 @@ # # A "headful" test requires a graphical environment to meaningfully # run. Tests that are not headful are "headless". +# A test flagged with key sound needs audio devices on the system, this +# may be accompanied by the headful keyword since audio device access +# is often linked to access to desktop resources and headful systems are +# also more likely to have audio devices (ie meaning both input and output) # A test flagged with key "printer" requires a printer to succeed, else # throws a PrinterException or the like. # A test flagged with cgroups uses cgroups. -keys=2d dnd headful i18n intermittent printer randomness jfr cgroups +keys=2d dnd headful sound i18n intermittent printer randomness jfr cgroups # Tests that must run in othervm mode othervm.dirs=java/awt java/beans javax/accessibility javax/imageio javax/sound javax/swing javax/print \ diff -Nru openjdk-17-17.0.5+8/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java openjdk-17-17.0.6+10/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java --- openjdk-17-17.0.5+8/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFxMode.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -77,13 +77,16 @@ checkExit(Exit.OK); checkOrder("pkg/A.html", "Property Summary", - "javafx.beans.property.Property", "prop", + """ + prop""", "Field Summary", - "javafx.beans.property.Property", "prop", + """ + prop""", "Method Summary", - "getProp", "Gets the value of the property prop.", """ - propProperty""", "Sets the value of the property prop."); + getProp""", + """ + propProperty"""); } void createTestClass(Path src) throws Exception { diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/doclint/CrashInAnnotateTest.java openjdk-17-17.0.6+10/test/langtools/tools/doclint/CrashInAnnotateTest.java --- openjdk-17-17.0.5+8/test/langtools/tools/doclint/CrashInAnnotateTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/doclint/CrashInAnnotateTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,31 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8266082 + * @summary javac should not crash when seeing type annotations in links + * @compile/fail/ref=CrashInAnnotateTest.out -Xdoclint -XDrawDiagnostics CrashInAnnotateTest.java + */ + +import java.util.List; + +/** {@link #equals(@Deprecated Object)} + * {@link java.util.Map.@Deprecated Entry#getKey()} + */ +class CrashInAnnotateTest { +} + +/** {@link #compare(Object, List>)} */ +class CrashInAnnotateTest2 { + void compare(Object o, List> l) {} +} + +/** {@link @Deprecated java.lang.Object#hashCode()} */ +class CrashInAnnotateTest3 { } + +/** {@link CrashInAnnotateTest4.@java.lang.Deprecated Inner#aField} + * {@link java.util.Map.@Deprecated#getKey()} + */ +class CrashInAnnotateTest4 { + class Inner { + Object aField; + } +} \ No newline at end of file diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/doclint/CrashInAnnotateTest.out openjdk-17-17.0.6+10/test/langtools/tools/doclint/CrashInAnnotateTest.out --- openjdk-17-17.0.5+8/test/langtools/tools/doclint/CrashInAnnotateTest.out 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/doclint/CrashInAnnotateTest.out 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,11 @@ +CrashInAnnotateTest.java:10:5: compiler.err.proc.messager: annotations not allowed +CrashInAnnotateTest.java:11:5: compiler.err.proc.messager: syntax error in reference +CrashInAnnotateTest.java:16:5: compiler.err.proc.messager: annotations not allowed +CrashInAnnotateTest.java:18:10: compiler.warn.proc.messager: no comment +CrashInAnnotateTest.java:21:5: compiler.err.proc.messager: syntax error in reference +CrashInAnnotateTest.java:24:5: compiler.err.proc.messager: syntax error in reference +CrashInAnnotateTest.java:25:5: compiler.err.proc.messager: syntax error in reference +CrashInAnnotateTest.java:28:5: compiler.warn.proc.messager: no comment +CrashInAnnotateTest.java:29:16: compiler.warn.proc.messager: no comment +6 errors +3 warnings \ No newline at end of file diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/javac/diags/examples/NoAnnotationsInLink.java openjdk-17-17.0.6+10/test/langtools/tools/javac/diags/examples/NoAnnotationsInLink.java --- openjdk-17-17.0.5+8/test/langtools/tools/javac/diags/examples/NoAnnotationsInLink.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/javac/diags/examples/NoAnnotationsInLink.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021, 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. + */ + +// key: compiler.err.dc.ref.annotations.not.allowed +// key: compiler.note.note +// key: compiler.note.proc.messager +// run: backdoor +// options: -processor DocCommentProcessor -proc:only + +/** {@link #equals(@Deprecated Object)} */ +class NoAnnotationsInLink { +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.java openjdk-17-17.0.6+10/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.java --- openjdk-17-17.0.5+8/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,24 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8029633 + * @summary Raw inner class constructor ref should not perform diamond inference + * @compile/fail/ref=MethodRefNewInnerRawTest.out -Werror -Xlint:unchecked -XDrawDiagnostics MethodRefNewInnerRawTest.java + */ + +import java.util.function.*; + +class MethodRefNewInnerRawTest { + class Inner1 {} + class Inner2 {} + + Supplier s1 = MethodRefNewInnerRawTest.Inner1::new; + Supplier s2 = MethodRefNewInnerRawTest.Inner2::new; + Supplier.Inner1> s3 = MethodRefNewInnerRawTest.Inner1::new; + Supplier.Inner2> s4 = MethodRefNewInnerRawTest.Inner2::new; + + static class Outer { + class Inner3 {} + + Supplier> s5 = Outer.Inner3::new; + } +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.out openjdk-17-17.0.6+10/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.out --- openjdk-17-17.0.5+8/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.out 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/javac/lambda/methodReference/MethodRefNewInnerRawTest.out 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,5 @@ +MethodRefNewInnerRawTest.java:16:55: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), MethodRefNewInnerRawTest.Inner1, MethodRefNewInnerRawTest.Inner1 +MethodRefNewInnerRawTest.java:17:63: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), MethodRefNewInnerRawTest.Inner2, MethodRefNewInnerRawTest.Inner2 +- compiler.err.warnings.and.werror +1 error +2 warnings diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/javac/lvti/ConstantTypes.java openjdk-17-17.0.6+10/test/langtools/tools/javac/lvti/ConstantTypes.java --- openjdk-17-17.0.5+8/test/langtools/tools/javac/lvti/ConstantTypes.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/javac/lvti/ConstantTypes.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022, 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 8293578 + * @summary Ensure constant types are removed correctly for .getClass(). + * @compile ConstantTypes.java + * @run main ConstantTypes + */ + +import java.util.Objects; + +public class ConstantTypes { + public static void main(String... args) throws Throwable { + new ConstantTypes().testStringCreation1(); + new ConstantTypes().testStringCreation2(); + new ConstantTypes().testStringCreation3(); + new ConstantTypes().testStringCreation4(); + new ConstantTypes().testStringFolding(); + } + + private void testStringCreation1() throws Throwable { + var testC = "incorrect".getClass(); + var testV = testC.getConstructor(String.class) + .newInstance("correct"); + String actual = testV; + String expected = "correct"; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Unexpected result: " + actual); + } + } + + private void testStringCreation2() throws Throwable { + var test = "incorrect".getClass() + .getConstructor(String.class) + .newInstance("correct"); + String actual = test; + String expected = "correct"; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Unexpected result: " + actual); + } + } + + private void testStringCreation3() throws Throwable { + final var testC = "incorrect"; + var testV = testC.getClass() + .getConstructor(String.class) + .newInstance("correct"); + String actual = testV; + String expected = "correct"; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Unexpected result: " + actual); + } + } + + private void testStringCreation4() throws Throwable { + var testC = "incorrect"; + var testV = testC.getClass() + .getConstructor(String.class) + .newInstance("correct"); + String actual = testV; + String expected = "correct"; + if (!Objects.equals(actual, expected)) { + throw new AssertionError("Unexpected result: " + actual); + } + } + + private void testStringFolding() { + final var v1 = "1"; + final var v2 = "2"; + String actual = v1 + v2; + String expected = "12"; + if (actual != expected) { //intentional reference comparison + throw new AssertionError("Value not interned!"); + } + } + +} \ No newline at end of file diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/javac/patterns/NullSwitch.java openjdk-17-17.0.6+10/test/langtools/tools/javac/patterns/NullSwitch.java --- openjdk-17-17.0.5+8/test/langtools/tools/javac/patterns/NullSwitch.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/javac/patterns/NullSwitch.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8262891 + * @bug 8262891 8272776 * @summary Check null handling for non-pattern switches. * @compile --enable-preview -source ${jdk.version} NullSwitch.java * @run main/othervm --enable-preview NullSwitch @@ -57,6 +57,9 @@ assertEquals(0, matchingSwitch12("")); assertEquals(2, matchingSwitch12(null)); assertEquals(1, matchingSwitch12(0.0)); + assertEquals(0, matchingSwitch13("")); + assertEquals(1, matchingSwitch13(0.0)); + assertEquals(2, matchingSwitch13(null)); } private int matchingSwitch1(Object obj) { @@ -156,6 +159,17 @@ } } catch (NullPointerException ex) { return 2; + } + } + + private int matchingSwitch13(Object obj) { + try { + switch (obj) { + default: return 1; + case String s: return 0; + } + } catch (NullPointerException ex) { + return 2; } } diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/OptionalDependencyTest.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/OptionalDependencyTest.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/OptionalDependencyTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/OptionalDependencyTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022, 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 8293701 + * @library ../lib + * @build CompilerUtils + * @run testng OptionalDependencyTest + * @summary Tests optional dependency handling + */ + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; +import java.util.spi.ToolProvider; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; + +public class OptionalDependencyTest { + private static final String TEST_SRC = System.getProperty("test.src"); + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + + private static final Path MODS_DIR = Paths.get("mods"); + + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar").orElseThrow(); + private static final Set modules = Set.of("m1", "m2", "m3"); + + @BeforeTest + public void compileAll() throws Exception { + CompilerUtils.cleanDir(MODS_DIR); + modules.forEach(mn -> + assertTrue(CompilerUtils.compileModule(SRC_DIR, MODS_DIR, mn))); + + Path m1 = MODS_DIR.resolve("m1"); + Path m2 = MODS_DIR.resolve("m2"); + Path m3 = MODS_DIR.resolve("m3"); + jar("cf", "m1.jar", "-C", m1.toString(), "p1/P.class", + "-C", m1.toString(), "module-info.class"); + jar("cf", "m2.jar", "-C", m2.toString(), "p2/Q.class", + "-C", m2.toString(), "module-info.class"); + jar("cf", "m3.jar", "-C", m3.toString(), "p3/R.class", + "-C", m3.toString(), "module-info.class"); + } + + /* + * Test if a requires static dependence is not resolved in the configuration. + */ + @Test + public void optionalDependenceNotResolved() { + JdepsRunner jdepsRunner = new JdepsRunner("--module-path", "m2.jar" + File.pathSeparator + "m3.jar", + "--inverse", + "--package", "p2", "m1.jar"); + int rc = jdepsRunner.run(true); + assertTrue(rc == 0); + } + + /* + * Test if a requires static dependence is resolved in the configuration. + */ + @Test + public void optionalDependenceResolved() { + JdepsRunner jdepsRunner = new JdepsRunner("--module-path", "m2.jar" + File.pathSeparator + "m3.jar", + "--inverse", "--add-modules", "m3", + "--package", "p2", "m1.jar"); + int rc = jdepsRunner.run(true); + assertTrue(rc == 0); + } + + private static void jar(String... options) { + int rc = JAR_TOOL.run(System.out, System.err, options); + assertTrue(rc == 0); + } +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m1/module-info.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m1/module-info.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m1/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m1/module-info.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, 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. + */ + +module m1 { + requires transitive m2; + exports p1; +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m1/p1/P.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m1/p1/P.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m1/p1/P.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m1/p1/P.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, 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. + */ + +package p1; +public class P { + public void m() {} +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m2/module-info.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m2/module-info.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m2/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m2/module-info.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, 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. + */ + +module m2 { + requires static m3; + exports p2; +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m2/p2/Q.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m2/p2/Q.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m2/p2/Q.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m2/p2/Q.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, 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. + */ + +package p2; +public class Q { + @p3.R + public void m() {} +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m3/module-info.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m3/module-info.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m3/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m3/module-info.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022, 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. + */ + +module m3 { + exports p3; +} diff -Nru openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m3/p3/R.java openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m3/p3/R.java --- openjdk-17-17.0.5+8/test/langtools/tools/jdeps/optionalDependency/src/m3/p3/R.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/langtools/tools/jdeps/optionalDependency/src/m3/p3/R.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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. + */ + +package p3; +import java.lang.annotation.*; + +@Retention(RetentionPolicy.SOURCE) +public @interface R { +} diff -Nru openjdk-17-17.0.5+8/test/lib/jdk/test/lib/jfr/EventNames.java openjdk-17-17.0.6+10/test/lib/jdk/test/lib/jfr/EventNames.java --- openjdk-17-17.0.5+8/test/lib/jdk/test/lib/jfr/EventNames.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib/jdk/test/lib/jfr/EventNames.java 2023-01-10 13:21:55.000000000 +0000 @@ -169,6 +169,7 @@ public final static String ObjectAllocationOutsideTLAB = PREFIX + "ObjectAllocationOutsideTLAB"; public final static String ObjectAllocationSample = PREFIX + "ObjectAllocationSample"; public final static String Deoptimization = PREFIX + "Deoptimization"; + public final static String JITRestart = PREFIX + "JITRestart"; // OS public final static String OSInformation = PREFIX + "OSInformation"; diff -Nru openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/BooleanTest.java openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/BooleanTest.java --- openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/BooleanTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/BooleanTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test BooleanTest - * @bug 8028756 + * @bug 8038756 * @library /test/lib * @modules java.base/jdk.internal.misc * java.compiler diff -Nru openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/DoubleTest.java openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/DoubleTest.java --- openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/DoubleTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/DoubleTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test DoubleTest - * @bug 8028756 + * @bug 8038756 * @library /test/lib * @modules java.base/jdk.internal.misc * @modules java.management/sun.management diff -Nru openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/StringTest.java openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/StringTest.java --- openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/StringTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/StringTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test StringTest - * @bug 8028756 + * @bug 8038756 * @library /test/lib * @modules java.base/jdk.internal.misc * @modules java.management/sun.management diff -Nru openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/Uint64Test.java openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/Uint64Test.java --- openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/Uint64Test.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/Uint64Test.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test Uint64Test - * @bug 8028756 + * @bug 8038756 * @library /test/lib * @modules java.base/jdk.internal.misc * @modules java.management/sun.management diff -Nru openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/UintxTest.java openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/UintxTest.java --- openjdk-17-17.0.5+8/test/lib-test/jdk/test/whitebox/vm_flags/UintxTest.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/lib-test/jdk/test/whitebox/vm_flags/UintxTest.java 2023-01-10 13:21:55.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test UintxTest - * @bug 8028756 + * @bug 8038756 * @library /test/lib * @modules java.base/jdk.internal.misc * java.management/sun.management diff -Nru openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/java/lang/StringDecode.java openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/java/lang/StringDecode.java --- openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/java/lang/StringDecode.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/java/lang/StringDecode.java 2023-01-10 13:21:55.000000000 +0000 @@ -40,59 +40,120 @@ @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgs = "-Xmx1g") +@Fork(value = 3) @Warmup(iterations = 5, time = 2) @Measurement(iterations = 5, time = 3) @State(Scope.Thread) public class StringDecode { - @BenchmarkMode(Mode.AverageTime) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - @Fork(value = 3, jvmArgs = "-Xmx1g") - @Warmup(iterations = 5, time = 2) - @Measurement(iterations = 5, time = 2) - @State(Scope.Thread) - public static class WithCharset { - - @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6", "ISO-2022-KR"}) - private String charsetName; - - private Charset charset; - private byte[] asciiString; - private byte[] utf16String; - - @Setup - public void setup() { - charset = Charset.forName(charsetName); - asciiString = "ascii string".getBytes(charset); - utf16String = "UTF-\uFF11\uFF16 string".getBytes(charset); - } - - @Benchmark - public void decodeCharsetName(Blackhole bh) throws Exception { - bh.consume(new String(asciiString, charsetName)); - bh.consume(new String(utf16String, charsetName)); - } - - @Benchmark - public void decodeCharset(Blackhole bh) throws Exception { - bh.consume(new String(asciiString, charset)); - bh.consume(new String(utf16String, charset)); - } - } + @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6", "ISO-2022-KR"}) + private String charsetName; - private byte[] asciiDefaultString; - private byte[] utf16DefaultString; + private Charset charset; + private byte[] asciiString; + private byte[] utf16String; + private byte[] longUtf16String; + private byte[] longUtf16StartString; + private byte[] longLatin1String; @Setup public void setup() { - asciiDefaultString = "ascii string".getBytes(); - utf16DefaultString = "UTF-\uFF11\uFF16 string".getBytes(); + charset = Charset.forName(charsetName); + asciiString = "ascii string".getBytes(charset); + utf16String = "UTF-\uFF11\uFF16 string".getBytes(charset); + longUtf16String = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac sem eu + urna egestas placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in magna porta ultricies. Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. + + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. \uFF11Donec aliquam mattis lectus eu ultrices. Duis eu nisl\uFF11 + euismod, blandit mauris vel, \uFF11placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis.\uFF11 Vivamus posuere. \uFF11 + \uFF11 + """.getBytes(charset); + longUtf16StartString = """ + \uFF11 + Lorem ipsum dolor sit amet, \uFF11consectetur adipiscing elit. Aliquam ac sem eu + urna egestas \uFF11placerat. Etiam finibus ipsum nulla, non mattis dolor cursus a. + Nulla \uFF11nec nisl consectetur, lacinia neque id, accumsan ante. Curabitur et + sapien in \uFF11magna porta ultricies. \uFF11Sed vel pellentesque nibh. Pellentesque dictum + dignissim diam eu ultricies. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Suspendisse erat diam, fringilla + sed massa sed, posuere viverra orci. Suspendisse tempor libero non gravida + efficitur. Vivamus lacinia risus non orci viverra, at consectetur odio laoreet. + Suspendisse potenti. + + Phasellus vel nisi iaculis, accumsan quam sed, bibendum eros. Sed venenatis + nulla tortor, et eleifend urna sodales id. Nullam tempus ac metus sit amet + sollicitudin. Nam sed ex diam. Praesent vitae eros et neque condimentum + consectetur eget non tortor. Praesent bibendum vel felis nec dignissim. + Maecenas a enim diam. Suspendisse quis ligula at nisi accumsan lacinia id + hendrerit sapien. Donec aliquam mattis lectus eu ultrices. Duis eu nisl + euismod, blandit mauris vel, placerat urna. Etiam malesuada enim purus, + tristique mollis odio blandit quis. Vivamus posuere. + """.getBytes(charset); + + longLatin1String = """ + a\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + b\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + c\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + d\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + e\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + f\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + g\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + h\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + i\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6 + j\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6\u00F6 + k\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6\u00F6 + l\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6\u00F6 + m\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00F6\u00B6\u00F6\u00F6 + """.getBytes(charset); + } + + @Benchmark + public String decodeAsciiCharsetName() throws Exception { + return new String(asciiString, charsetName); + } + + @Benchmark + public String decodeAscii() throws Exception { + return new String(asciiString, charset); + } + + @Benchmark + public String decodeLatin1Long() throws Exception { + return new String(longLatin1String, charset); + } + + @Benchmark + public String decodeUTF16Short() throws Exception { + return new String(utf16String, charset); + } + + @Benchmark + public String decodeUTF16LongEnd() throws Exception { + return new String(longUtf16String, charset); + } + + @Benchmark + public String decodeUTF16LongStart() throws Exception { + return new String(longUtf16StartString, charset); } @Benchmark - public void decodeDefault(Blackhole bh) throws Exception { - bh.consume(new String(asciiDefaultString)); - bh.consume(new String(utf16DefaultString)); + public void decodeUTF16LongMixed(Blackhole bh) throws Exception { + bh.consume(new String(longUtf16StartString, charset)); + bh.consume(new String(longUtf16String, charset)); } } diff -Nru openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/java/util/TestCRC32C.java openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/java/util/TestCRC32C.java --- openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/java/util/TestCRC32C.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/java/util/TestCRC32C.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021, 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. + */ +package org.openjdk.bench.java.util; + +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.zip.CRC32C; +import org.openjdk.jmh.annotations.*; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Fork(value = 2) + +public class TestCRC32C { + + private CRC32C crc32c; + private Random random; + private byte[] bytes; + + @Param({"64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768", "65536"}) + private int count; + + public TestCRC32C() { + crc32c = new CRC32C(); + random = new Random(2147483648L); + bytes = new byte[1000000]; + random.nextBytes(bytes); + } + + @Setup(Level.Iteration) + public void setupBytes() { + crc32c.reset(); + } + + @Benchmark + public void testCRC32CUpdate() { + crc32c.update(bytes, 0, count); + } +} diff -Nru openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/vm/gc/Alloc.java openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/vm/gc/Alloc.java --- openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/vm/gc/Alloc.java 2022-10-10 13:07:22.000000000 +0000 +++ openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/vm/gc/Alloc.java 2023-01-10 13:21:55.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2022, 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 @@ -38,13 +38,14 @@ public class Alloc { public static final int LENGTH = 400; - public static final int ARR_LEN = 100; - public int largeLen = 100; - public int smalllen = 6; + public static final int largeConstLen = 100; + public static final int smallConstLen = 6; + public int largeVariableLen = 100; + public int smallVariableLen = 6; @Benchmark public void testLargeConstArray(Blackhole bh) throws Exception { - int localArrlen = ARR_LEN; + int localArrlen = largeConstLen; for (int i = 0; i < LENGTH; i++) { Object[] tmp = new Object[localArrlen]; bh.consume(tmp); @@ -53,7 +54,7 @@ @Benchmark public void testLargeVariableArray(Blackhole bh) throws Exception { - int localArrlen = largeLen; + int localArrlen = largeVariableLen; for (int i = 0; i < LENGTH; i++) { Object[] tmp = new Object[localArrlen]; bh.consume(tmp); @@ -62,7 +63,7 @@ @Benchmark public void testSmallConstArray(Blackhole bh) throws Exception { - int localArrlen = largeLen; + int localArrlen = smallConstLen; for (int i = 0; i < LENGTH; i++) { Object[] tmp = new Object[localArrlen]; bh.consume(tmp); @@ -82,7 +83,7 @@ @Benchmark public void testSmallVariableArray(Blackhole bh) throws Exception { - int localArrlen = smalllen; + int localArrlen = smallVariableLen; for (int i = 0; i < LENGTH; i++) { Object[] tmp = new Object[localArrlen]; bh.consume(tmp); diff -Nru openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/vm/gc/RawAllocationRate.java openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/vm/gc/RawAllocationRate.java --- openjdk-17-17.0.5+8/test/micro/org/openjdk/bench/vm/gc/RawAllocationRate.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-17-17.0.6+10/test/micro/org/openjdk/bench/vm/gc/RawAllocationRate.java 2023-01-10 13:21:55.000000000 +0000 @@ -0,0 +1,28732 @@ +/* + * Copyright (c) 2021, Red Hat Inc. 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. + */ +package org.openjdk.bench.vm.gc; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +// Test the raw allocation rate for long arrays. Allocate 1 megabyte +// of memory, in chunks of varying size. The resulting score is the +// allocation rate in megabytes per second. + +@OutputTimeUnit(TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1) +@Warmup(iterations = 15, time = 1) +@Fork(value = 1) +@State(Scope.Thread) +public class RawAllocationRate { + + @Param({"32", "64", "256", "1024", "2048", "4096", "8192", "16384", "65536", "131072"}) // Object size in bytes. + public int size; + + Object[] objects; + + private static final long megabyte = 1024 * 1024; + private static final long bytesPerLong = 8; + private static final int longsPerHeader = 2; + + @Setup(Level.Iteration) + public void up() throws Throwable { + if (size % bytesPerLong != 0) { + throw new RuntimeException("I'm sorry Dave, I can't do that"); + } + objects = new Object[1_000_000]; + } + + @TearDown(Level.Iteration) + public void down() throws Throwable { + objects = null; + } + + @Benchmark + public Object[] arrayTest() { + var arrays = objects; + final int longElements = (int)(size/bytesPerLong) - longsPerHeader; + int i, j; + for (i = 0, j = 0; ; i += size, j++) { + if (i + size < megabyte) { + arrays[j] = new long[longElements]; + } else { + long remaining = megabyte - i; + int elements = (int)(remaining/bytesPerLong) - longsPerHeader; + if (elements >= 0) { + arrays[j] = new long[elements]; + } + break; + } + } + return arrays; + } + + @Benchmark + @Fork(jvmArgsAppend={"-XX:TieredStopAtLevel=1"}) + public Object[] arrayTest_C1() { + return arrayTest(); + } + + @Benchmark + public Object[] instanceTest() { + var objects = this.objects; + final int longElements = (int)(size); + int i, j; + for (i = 0, j = 0; ; i += size, j++) { + if (i + size < megabyte) { + objects[j] = newInstance(longElements); + } else { + long remaining = megabyte - i; + int elements = (int)(remaining/bytesPerLong) - longsPerHeader; + if (elements >= 0) { + objects[j] = new long[elements]; + } + break; + } + } + return objects; + } + + @Benchmark + @Fork(jvmArgsAppend={"-XX:TieredStopAtLevel=1"}) + public Object[] instanceTest_C1() { + return instanceTest(); + } + + static class BaseClass { + } + + static class Class32 extends BaseClass { + long i0; + long i1; + } + static class Class64 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + } + static class Class256 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + } + static class Class1024 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + } + static class Class2048 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + } + static class Class4096 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + long i254; + long i255; + long i256; + long i257; + long i258; + long i259; + long i260; + long i261; + long i262; + long i263; + long i264; + long i265; + long i266; + long i267; + long i268; + long i269; + long i270; + long i271; + long i272; + long i273; + long i274; + long i275; + long i276; + long i277; + long i278; + long i279; + long i280; + long i281; + long i282; + long i283; + long i284; + long i285; + long i286; + long i287; + long i288; + long i289; + long i290; + long i291; + long i292; + long i293; + long i294; + long i295; + long i296; + long i297; + long i298; + long i299; + long i300; + long i301; + long i302; + long i303; + long i304; + long i305; + long i306; + long i307; + long i308; + long i309; + long i310; + long i311; + long i312; + long i313; + long i314; + long i315; + long i316; + long i317; + long i318; + long i319; + long i320; + long i321; + long i322; + long i323; + long i324; + long i325; + long i326; + long i327; + long i328; + long i329; + long i330; + long i331; + long i332; + long i333; + long i334; + long i335; + long i336; + long i337; + long i338; + long i339; + long i340; + long i341; + long i342; + long i343; + long i344; + long i345; + long i346; + long i347; + long i348; + long i349; + long i350; + long i351; + long i352; + long i353; + long i354; + long i355; + long i356; + long i357; + long i358; + long i359; + long i360; + long i361; + long i362; + long i363; + long i364; + long i365; + long i366; + long i367; + long i368; + long i369; + long i370; + long i371; + long i372; + long i373; + long i374; + long i375; + long i376; + long i377; + long i378; + long i379; + long i380; + long i381; + long i382; + long i383; + long i384; + long i385; + long i386; + long i387; + long i388; + long i389; + long i390; + long i391; + long i392; + long i393; + long i394; + long i395; + long i396; + long i397; + long i398; + long i399; + long i400; + long i401; + long i402; + long i403; + long i404; + long i405; + long i406; + long i407; + long i408; + long i409; + long i410; + long i411; + long i412; + long i413; + long i414; + long i415; + long i416; + long i417; + long i418; + long i419; + long i420; + long i421; + long i422; + long i423; + long i424; + long i425; + long i426; + long i427; + long i428; + long i429; + long i430; + long i431; + long i432; + long i433; + long i434; + long i435; + long i436; + long i437; + long i438; + long i439; + long i440; + long i441; + long i442; + long i443; + long i444; + long i445; + long i446; + long i447; + long i448; + long i449; + long i450; + long i451; + long i452; + long i453; + long i454; + long i455; + long i456; + long i457; + long i458; + long i459; + long i460; + long i461; + long i462; + long i463; + long i464; + long i465; + long i466; + long i467; + long i468; + long i469; + long i470; + long i471; + long i472; + long i473; + long i474; + long i475; + long i476; + long i477; + long i478; + long i479; + long i480; + long i481; + long i482; + long i483; + long i484; + long i485; + long i486; + long i487; + long i488; + long i489; + long i490; + long i491; + long i492; + long i493; + long i494; + long i495; + long i496; + long i497; + long i498; + long i499; + long i500; + long i501; + long i502; + long i503; + long i504; + long i505; + long i506; + long i507; + long i508; + long i509; + } + static class Class8192 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + long i254; + long i255; + long i256; + long i257; + long i258; + long i259; + long i260; + long i261; + long i262; + long i263; + long i264; + long i265; + long i266; + long i267; + long i268; + long i269; + long i270; + long i271; + long i272; + long i273; + long i274; + long i275; + long i276; + long i277; + long i278; + long i279; + long i280; + long i281; + long i282; + long i283; + long i284; + long i285; + long i286; + long i287; + long i288; + long i289; + long i290; + long i291; + long i292; + long i293; + long i294; + long i295; + long i296; + long i297; + long i298; + long i299; + long i300; + long i301; + long i302; + long i303; + long i304; + long i305; + long i306; + long i307; + long i308; + long i309; + long i310; + long i311; + long i312; + long i313; + long i314; + long i315; + long i316; + long i317; + long i318; + long i319; + long i320; + long i321; + long i322; + long i323; + long i324; + long i325; + long i326; + long i327; + long i328; + long i329; + long i330; + long i331; + long i332; + long i333; + long i334; + long i335; + long i336; + long i337; + long i338; + long i339; + long i340; + long i341; + long i342; + long i343; + long i344; + long i345; + long i346; + long i347; + long i348; + long i349; + long i350; + long i351; + long i352; + long i353; + long i354; + long i355; + long i356; + long i357; + long i358; + long i359; + long i360; + long i361; + long i362; + long i363; + long i364; + long i365; + long i366; + long i367; + long i368; + long i369; + long i370; + long i371; + long i372; + long i373; + long i374; + long i375; + long i376; + long i377; + long i378; + long i379; + long i380; + long i381; + long i382; + long i383; + long i384; + long i385; + long i386; + long i387; + long i388; + long i389; + long i390; + long i391; + long i392; + long i393; + long i394; + long i395; + long i396; + long i397; + long i398; + long i399; + long i400; + long i401; + long i402; + long i403; + long i404; + long i405; + long i406; + long i407; + long i408; + long i409; + long i410; + long i411; + long i412; + long i413; + long i414; + long i415; + long i416; + long i417; + long i418; + long i419; + long i420; + long i421; + long i422; + long i423; + long i424; + long i425; + long i426; + long i427; + long i428; + long i429; + long i430; + long i431; + long i432; + long i433; + long i434; + long i435; + long i436; + long i437; + long i438; + long i439; + long i440; + long i441; + long i442; + long i443; + long i444; + long i445; + long i446; + long i447; + long i448; + long i449; + long i450; + long i451; + long i452; + long i453; + long i454; + long i455; + long i456; + long i457; + long i458; + long i459; + long i460; + long i461; + long i462; + long i463; + long i464; + long i465; + long i466; + long i467; + long i468; + long i469; + long i470; + long i471; + long i472; + long i473; + long i474; + long i475; + long i476; + long i477; + long i478; + long i479; + long i480; + long i481; + long i482; + long i483; + long i484; + long i485; + long i486; + long i487; + long i488; + long i489; + long i490; + long i491; + long i492; + long i493; + long i494; + long i495; + long i496; + long i497; + long i498; + long i499; + long i500; + long i501; + long i502; + long i503; + long i504; + long i505; + long i506; + long i507; + long i508; + long i509; + long i510; + long i511; + long i512; + long i513; + long i514; + long i515; + long i516; + long i517; + long i518; + long i519; + long i520; + long i521; + long i522; + long i523; + long i524; + long i525; + long i526; + long i527; + long i528; + long i529; + long i530; + long i531; + long i532; + long i533; + long i534; + long i535; + long i536; + long i537; + long i538; + long i539; + long i540; + long i541; + long i542; + long i543; + long i544; + long i545; + long i546; + long i547; + long i548; + long i549; + long i550; + long i551; + long i552; + long i553; + long i554; + long i555; + long i556; + long i557; + long i558; + long i559; + long i560; + long i561; + long i562; + long i563; + long i564; + long i565; + long i566; + long i567; + long i568; + long i569; + long i570; + long i571; + long i572; + long i573; + long i574; + long i575; + long i576; + long i577; + long i578; + long i579; + long i580; + long i581; + long i582; + long i583; + long i584; + long i585; + long i586; + long i587; + long i588; + long i589; + long i590; + long i591; + long i592; + long i593; + long i594; + long i595; + long i596; + long i597; + long i598; + long i599; + long i600; + long i601; + long i602; + long i603; + long i604; + long i605; + long i606; + long i607; + long i608; + long i609; + long i610; + long i611; + long i612; + long i613; + long i614; + long i615; + long i616; + long i617; + long i618; + long i619; + long i620; + long i621; + long i622; + long i623; + long i624; + long i625; + long i626; + long i627; + long i628; + long i629; + long i630; + long i631; + long i632; + long i633; + long i634; + long i635; + long i636; + long i637; + long i638; + long i639; + long i640; + long i641; + long i642; + long i643; + long i644; + long i645; + long i646; + long i647; + long i648; + long i649; + long i650; + long i651; + long i652; + long i653; + long i654; + long i655; + long i656; + long i657; + long i658; + long i659; + long i660; + long i661; + long i662; + long i663; + long i664; + long i665; + long i666; + long i667; + long i668; + long i669; + long i670; + long i671; + long i672; + long i673; + long i674; + long i675; + long i676; + long i677; + long i678; + long i679; + long i680; + long i681; + long i682; + long i683; + long i684; + long i685; + long i686; + long i687; + long i688; + long i689; + long i690; + long i691; + long i692; + long i693; + long i694; + long i695; + long i696; + long i697; + long i698; + long i699; + long i700; + long i701; + long i702; + long i703; + long i704; + long i705; + long i706; + long i707; + long i708; + long i709; + long i710; + long i711; + long i712; + long i713; + long i714; + long i715; + long i716; + long i717; + long i718; + long i719; + long i720; + long i721; + long i722; + long i723; + long i724; + long i725; + long i726; + long i727; + long i728; + long i729; + long i730; + long i731; + long i732; + long i733; + long i734; + long i735; + long i736; + long i737; + long i738; + long i739; + long i740; + long i741; + long i742; + long i743; + long i744; + long i745; + long i746; + long i747; + long i748; + long i749; + long i750; + long i751; + long i752; + long i753; + long i754; + long i755; + long i756; + long i757; + long i758; + long i759; + long i760; + long i761; + long i762; + long i763; + long i764; + long i765; + long i766; + long i767; + long i768; + long i769; + long i770; + long i771; + long i772; + long i773; + long i774; + long i775; + long i776; + long i777; + long i778; + long i779; + long i780; + long i781; + long i782; + long i783; + long i784; + long i785; + long i786; + long i787; + long i788; + long i789; + long i790; + long i791; + long i792; + long i793; + long i794; + long i795; + long i796; + long i797; + long i798; + long i799; + long i800; + long i801; + long i802; + long i803; + long i804; + long i805; + long i806; + long i807; + long i808; + long i809; + long i810; + long i811; + long i812; + long i813; + long i814; + long i815; + long i816; + long i817; + long i818; + long i819; + long i820; + long i821; + long i822; + long i823; + long i824; + long i825; + long i826; + long i827; + long i828; + long i829; + long i830; + long i831; + long i832; + long i833; + long i834; + long i835; + long i836; + long i837; + long i838; + long i839; + long i840; + long i841; + long i842; + long i843; + long i844; + long i845; + long i846; + long i847; + long i848; + long i849; + long i850; + long i851; + long i852; + long i853; + long i854; + long i855; + long i856; + long i857; + long i858; + long i859; + long i860; + long i861; + long i862; + long i863; + long i864; + long i865; + long i866; + long i867; + long i868; + long i869; + long i870; + long i871; + long i872; + long i873; + long i874; + long i875; + long i876; + long i877; + long i878; + long i879; + long i880; + long i881; + long i882; + long i883; + long i884; + long i885; + long i886; + long i887; + long i888; + long i889; + long i890; + long i891; + long i892; + long i893; + long i894; + long i895; + long i896; + long i897; + long i898; + long i899; + long i900; + long i901; + long i902; + long i903; + long i904; + long i905; + long i906; + long i907; + long i908; + long i909; + long i910; + long i911; + long i912; + long i913; + long i914; + long i915; + long i916; + long i917; + long i918; + long i919; + long i920; + long i921; + long i922; + long i923; + long i924; + long i925; + long i926; + long i927; + long i928; + long i929; + long i930; + long i931; + long i932; + long i933; + long i934; + long i935; + long i936; + long i937; + long i938; + long i939; + long i940; + long i941; + long i942; + long i943; + long i944; + long i945; + long i946; + long i947; + long i948; + long i949; + long i950; + long i951; + long i952; + long i953; + long i954; + long i955; + long i956; + long i957; + long i958; + long i959; + long i960; + long i961; + long i962; + long i963; + long i964; + long i965; + long i966; + long i967; + long i968; + long i969; + long i970; + long i971; + long i972; + long i973; + long i974; + long i975; + long i976; + long i977; + long i978; + long i979; + long i980; + long i981; + long i982; + long i983; + long i984; + long i985; + long i986; + long i987; + long i988; + long i989; + long i990; + long i991; + long i992; + long i993; + long i994; + long i995; + long i996; + long i997; + long i998; + long i999; + long i1000; + long i1001; + long i1002; + long i1003; + long i1004; + long i1005; + long i1006; + long i1007; + long i1008; + long i1009; + long i1010; + long i1011; + long i1012; + long i1013; + long i1014; + long i1015; + long i1016; + long i1017; + long i1018; + long i1019; + long i1020; + long i1021; + } + static class Class16384 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + long i254; + long i255; + long i256; + long i257; + long i258; + long i259; + long i260; + long i261; + long i262; + long i263; + long i264; + long i265; + long i266; + long i267; + long i268; + long i269; + long i270; + long i271; + long i272; + long i273; + long i274; + long i275; + long i276; + long i277; + long i278; + long i279; + long i280; + long i281; + long i282; + long i283; + long i284; + long i285; + long i286; + long i287; + long i288; + long i289; + long i290; + long i291; + long i292; + long i293; + long i294; + long i295; + long i296; + long i297; + long i298; + long i299; + long i300; + long i301; + long i302; + long i303; + long i304; + long i305; + long i306; + long i307; + long i308; + long i309; + long i310; + long i311; + long i312; + long i313; + long i314; + long i315; + long i316; + long i317; + long i318; + long i319; + long i320; + long i321; + long i322; + long i323; + long i324; + long i325; + long i326; + long i327; + long i328; + long i329; + long i330; + long i331; + long i332; + long i333; + long i334; + long i335; + long i336; + long i337; + long i338; + long i339; + long i340; + long i341; + long i342; + long i343; + long i344; + long i345; + long i346; + long i347; + long i348; + long i349; + long i350; + long i351; + long i352; + long i353; + long i354; + long i355; + long i356; + long i357; + long i358; + long i359; + long i360; + long i361; + long i362; + long i363; + long i364; + long i365; + long i366; + long i367; + long i368; + long i369; + long i370; + long i371; + long i372; + long i373; + long i374; + long i375; + long i376; + long i377; + long i378; + long i379; + long i380; + long i381; + long i382; + long i383; + long i384; + long i385; + long i386; + long i387; + long i388; + long i389; + long i390; + long i391; + long i392; + long i393; + long i394; + long i395; + long i396; + long i397; + long i398; + long i399; + long i400; + long i401; + long i402; + long i403; + long i404; + long i405; + long i406; + long i407; + long i408; + long i409; + long i410; + long i411; + long i412; + long i413; + long i414; + long i415; + long i416; + long i417; + long i418; + long i419; + long i420; + long i421; + long i422; + long i423; + long i424; + long i425; + long i426; + long i427; + long i428; + long i429; + long i430; + long i431; + long i432; + long i433; + long i434; + long i435; + long i436; + long i437; + long i438; + long i439; + long i440; + long i441; + long i442; + long i443; + long i444; + long i445; + long i446; + long i447; + long i448; + long i449; + long i450; + long i451; + long i452; + long i453; + long i454; + long i455; + long i456; + long i457; + long i458; + long i459; + long i460; + long i461; + long i462; + long i463; + long i464; + long i465; + long i466; + long i467; + long i468; + long i469; + long i470; + long i471; + long i472; + long i473; + long i474; + long i475; + long i476; + long i477; + long i478; + long i479; + long i480; + long i481; + long i482; + long i483; + long i484; + long i485; + long i486; + long i487; + long i488; + long i489; + long i490; + long i491; + long i492; + long i493; + long i494; + long i495; + long i496; + long i497; + long i498; + long i499; + long i500; + long i501; + long i502; + long i503; + long i504; + long i505; + long i506; + long i507; + long i508; + long i509; + long i510; + long i511; + long i512; + long i513; + long i514; + long i515; + long i516; + long i517; + long i518; + long i519; + long i520; + long i521; + long i522; + long i523; + long i524; + long i525; + long i526; + long i527; + long i528; + long i529; + long i530; + long i531; + long i532; + long i533; + long i534; + long i535; + long i536; + long i537; + long i538; + long i539; + long i540; + long i541; + long i542; + long i543; + long i544; + long i545; + long i546; + long i547; + long i548; + long i549; + long i550; + long i551; + long i552; + long i553; + long i554; + long i555; + long i556; + long i557; + long i558; + long i559; + long i560; + long i561; + long i562; + long i563; + long i564; + long i565; + long i566; + long i567; + long i568; + long i569; + long i570; + long i571; + long i572; + long i573; + long i574; + long i575; + long i576; + long i577; + long i578; + long i579; + long i580; + long i581; + long i582; + long i583; + long i584; + long i585; + long i586; + long i587; + long i588; + long i589; + long i590; + long i591; + long i592; + long i593; + long i594; + long i595; + long i596; + long i597; + long i598; + long i599; + long i600; + long i601; + long i602; + long i603; + long i604; + long i605; + long i606; + long i607; + long i608; + long i609; + long i610; + long i611; + long i612; + long i613; + long i614; + long i615; + long i616; + long i617; + long i618; + long i619; + long i620; + long i621; + long i622; + long i623; + long i624; + long i625; + long i626; + long i627; + long i628; + long i629; + long i630; + long i631; + long i632; + long i633; + long i634; + long i635; + long i636; + long i637; + long i638; + long i639; + long i640; + long i641; + long i642; + long i643; + long i644; + long i645; + long i646; + long i647; + long i648; + long i649; + long i650; + long i651; + long i652; + long i653; + long i654; + long i655; + long i656; + long i657; + long i658; + long i659; + long i660; + long i661; + long i662; + long i663; + long i664; + long i665; + long i666; + long i667; + long i668; + long i669; + long i670; + long i671; + long i672; + long i673; + long i674; + long i675; + long i676; + long i677; + long i678; + long i679; + long i680; + long i681; + long i682; + long i683; + long i684; + long i685; + long i686; + long i687; + long i688; + long i689; + long i690; + long i691; + long i692; + long i693; + long i694; + long i695; + long i696; + long i697; + long i698; + long i699; + long i700; + long i701; + long i702; + long i703; + long i704; + long i705; + long i706; + long i707; + long i708; + long i709; + long i710; + long i711; + long i712; + long i713; + long i714; + long i715; + long i716; + long i717; + long i718; + long i719; + long i720; + long i721; + long i722; + long i723; + long i724; + long i725; + long i726; + long i727; + long i728; + long i729; + long i730; + long i731; + long i732; + long i733; + long i734; + long i735; + long i736; + long i737; + long i738; + long i739; + long i740; + long i741; + long i742; + long i743; + long i744; + long i745; + long i746; + long i747; + long i748; + long i749; + long i750; + long i751; + long i752; + long i753; + long i754; + long i755; + long i756; + long i757; + long i758; + long i759; + long i760; + long i761; + long i762; + long i763; + long i764; + long i765; + long i766; + long i767; + long i768; + long i769; + long i770; + long i771; + long i772; + long i773; + long i774; + long i775; + long i776; + long i777; + long i778; + long i779; + long i780; + long i781; + long i782; + long i783; + long i784; + long i785; + long i786; + long i787; + long i788; + long i789; + long i790; + long i791; + long i792; + long i793; + long i794; + long i795; + long i796; + long i797; + long i798; + long i799; + long i800; + long i801; + long i802; + long i803; + long i804; + long i805; + long i806; + long i807; + long i808; + long i809; + long i810; + long i811; + long i812; + long i813; + long i814; + long i815; + long i816; + long i817; + long i818; + long i819; + long i820; + long i821; + long i822; + long i823; + long i824; + long i825; + long i826; + long i827; + long i828; + long i829; + long i830; + long i831; + long i832; + long i833; + long i834; + long i835; + long i836; + long i837; + long i838; + long i839; + long i840; + long i841; + long i842; + long i843; + long i844; + long i845; + long i846; + long i847; + long i848; + long i849; + long i850; + long i851; + long i852; + long i853; + long i854; + long i855; + long i856; + long i857; + long i858; + long i859; + long i860; + long i861; + long i862; + long i863; + long i864; + long i865; + long i866; + long i867; + long i868; + long i869; + long i870; + long i871; + long i872; + long i873; + long i874; + long i875; + long i876; + long i877; + long i878; + long i879; + long i880; + long i881; + long i882; + long i883; + long i884; + long i885; + long i886; + long i887; + long i888; + long i889; + long i890; + long i891; + long i892; + long i893; + long i894; + long i895; + long i896; + long i897; + long i898; + long i899; + long i900; + long i901; + long i902; + long i903; + long i904; + long i905; + long i906; + long i907; + long i908; + long i909; + long i910; + long i911; + long i912; + long i913; + long i914; + long i915; + long i916; + long i917; + long i918; + long i919; + long i920; + long i921; + long i922; + long i923; + long i924; + long i925; + long i926; + long i927; + long i928; + long i929; + long i930; + long i931; + long i932; + long i933; + long i934; + long i935; + long i936; + long i937; + long i938; + long i939; + long i940; + long i941; + long i942; + long i943; + long i944; + long i945; + long i946; + long i947; + long i948; + long i949; + long i950; + long i951; + long i952; + long i953; + long i954; + long i955; + long i956; + long i957; + long i958; + long i959; + long i960; + long i961; + long i962; + long i963; + long i964; + long i965; + long i966; + long i967; + long i968; + long i969; + long i970; + long i971; + long i972; + long i973; + long i974; + long i975; + long i976; + long i977; + long i978; + long i979; + long i980; + long i981; + long i982; + long i983; + long i984; + long i985; + long i986; + long i987; + long i988; + long i989; + long i990; + long i991; + long i992; + long i993; + long i994; + long i995; + long i996; + long i997; + long i998; + long i999; + long i1000; + long i1001; + long i1002; + long i1003; + long i1004; + long i1005; + long i1006; + long i1007; + long i1008; + long i1009; + long i1010; + long i1011; + long i1012; + long i1013; + long i1014; + long i1015; + long i1016; + long i1017; + long i1018; + long i1019; + long i1020; + long i1021; + long i1022; + long i1023; + long i1024; + long i1025; + long i1026; + long i1027; + long i1028; + long i1029; + long i1030; + long i1031; + long i1032; + long i1033; + long i1034; + long i1035; + long i1036; + long i1037; + long i1038; + long i1039; + long i1040; + long i1041; + long i1042; + long i1043; + long i1044; + long i1045; + long i1046; + long i1047; + long i1048; + long i1049; + long i1050; + long i1051; + long i1052; + long i1053; + long i1054; + long i1055; + long i1056; + long i1057; + long i1058; + long i1059; + long i1060; + long i1061; + long i1062; + long i1063; + long i1064; + long i1065; + long i1066; + long i1067; + long i1068; + long i1069; + long i1070; + long i1071; + long i1072; + long i1073; + long i1074; + long i1075; + long i1076; + long i1077; + long i1078; + long i1079; + long i1080; + long i1081; + long i1082; + long i1083; + long i1084; + long i1085; + long i1086; + long i1087; + long i1088; + long i1089; + long i1090; + long i1091; + long i1092; + long i1093; + long i1094; + long i1095; + long i1096; + long i1097; + long i1098; + long i1099; + long i1100; + long i1101; + long i1102; + long i1103; + long i1104; + long i1105; + long i1106; + long i1107; + long i1108; + long i1109; + long i1110; + long i1111; + long i1112; + long i1113; + long i1114; + long i1115; + long i1116; + long i1117; + long i1118; + long i1119; + long i1120; + long i1121; + long i1122; + long i1123; + long i1124; + long i1125; + long i1126; + long i1127; + long i1128; + long i1129; + long i1130; + long i1131; + long i1132; + long i1133; + long i1134; + long i1135; + long i1136; + long i1137; + long i1138; + long i1139; + long i1140; + long i1141; + long i1142; + long i1143; + long i1144; + long i1145; + long i1146; + long i1147; + long i1148; + long i1149; + long i1150; + long i1151; + long i1152; + long i1153; + long i1154; + long i1155; + long i1156; + long i1157; + long i1158; + long i1159; + long i1160; + long i1161; + long i1162; + long i1163; + long i1164; + long i1165; + long i1166; + long i1167; + long i1168; + long i1169; + long i1170; + long i1171; + long i1172; + long i1173; + long i1174; + long i1175; + long i1176; + long i1177; + long i1178; + long i1179; + long i1180; + long i1181; + long i1182; + long i1183; + long i1184; + long i1185; + long i1186; + long i1187; + long i1188; + long i1189; + long i1190; + long i1191; + long i1192; + long i1193; + long i1194; + long i1195; + long i1196; + long i1197; + long i1198; + long i1199; + long i1200; + long i1201; + long i1202; + long i1203; + long i1204; + long i1205; + long i1206; + long i1207; + long i1208; + long i1209; + long i1210; + long i1211; + long i1212; + long i1213; + long i1214; + long i1215; + long i1216; + long i1217; + long i1218; + long i1219; + long i1220; + long i1221; + long i1222; + long i1223; + long i1224; + long i1225; + long i1226; + long i1227; + long i1228; + long i1229; + long i1230; + long i1231; + long i1232; + long i1233; + long i1234; + long i1235; + long i1236; + long i1237; + long i1238; + long i1239; + long i1240; + long i1241; + long i1242; + long i1243; + long i1244; + long i1245; + long i1246; + long i1247; + long i1248; + long i1249; + long i1250; + long i1251; + long i1252; + long i1253; + long i1254; + long i1255; + long i1256; + long i1257; + long i1258; + long i1259; + long i1260; + long i1261; + long i1262; + long i1263; + long i1264; + long i1265; + long i1266; + long i1267; + long i1268; + long i1269; + long i1270; + long i1271; + long i1272; + long i1273; + long i1274; + long i1275; + long i1276; + long i1277; + long i1278; + long i1279; + long i1280; + long i1281; + long i1282; + long i1283; + long i1284; + long i1285; + long i1286; + long i1287; + long i1288; + long i1289; + long i1290; + long i1291; + long i1292; + long i1293; + long i1294; + long i1295; + long i1296; + long i1297; + long i1298; + long i1299; + long i1300; + long i1301; + long i1302; + long i1303; + long i1304; + long i1305; + long i1306; + long i1307; + long i1308; + long i1309; + long i1310; + long i1311; + long i1312; + long i1313; + long i1314; + long i1315; + long i1316; + long i1317; + long i1318; + long i1319; + long i1320; + long i1321; + long i1322; + long i1323; + long i1324; + long i1325; + long i1326; + long i1327; + long i1328; + long i1329; + long i1330; + long i1331; + long i1332; + long i1333; + long i1334; + long i1335; + long i1336; + long i1337; + long i1338; + long i1339; + long i1340; + long i1341; + long i1342; + long i1343; + long i1344; + long i1345; + long i1346; + long i1347; + long i1348; + long i1349; + long i1350; + long i1351; + long i1352; + long i1353; + long i1354; + long i1355; + long i1356; + long i1357; + long i1358; + long i1359; + long i1360; + long i1361; + long i1362; + long i1363; + long i1364; + long i1365; + long i1366; + long i1367; + long i1368; + long i1369; + long i1370; + long i1371; + long i1372; + long i1373; + long i1374; + long i1375; + long i1376; + long i1377; + long i1378; + long i1379; + long i1380; + long i1381; + long i1382; + long i1383; + long i1384; + long i1385; + long i1386; + long i1387; + long i1388; + long i1389; + long i1390; + long i1391; + long i1392; + long i1393; + long i1394; + long i1395; + long i1396; + long i1397; + long i1398; + long i1399; + long i1400; + long i1401; + long i1402; + long i1403; + long i1404; + long i1405; + long i1406; + long i1407; + long i1408; + long i1409; + long i1410; + long i1411; + long i1412; + long i1413; + long i1414; + long i1415; + long i1416; + long i1417; + long i1418; + long i1419; + long i1420; + long i1421; + long i1422; + long i1423; + long i1424; + long i1425; + long i1426; + long i1427; + long i1428; + long i1429; + long i1430; + long i1431; + long i1432; + long i1433; + long i1434; + long i1435; + long i1436; + long i1437; + long i1438; + long i1439; + long i1440; + long i1441; + long i1442; + long i1443; + long i1444; + long i1445; + long i1446; + long i1447; + long i1448; + long i1449; + long i1450; + long i1451; + long i1452; + long i1453; + long i1454; + long i1455; + long i1456; + long i1457; + long i1458; + long i1459; + long i1460; + long i1461; + long i1462; + long i1463; + long i1464; + long i1465; + long i1466; + long i1467; + long i1468; + long i1469; + long i1470; + long i1471; + long i1472; + long i1473; + long i1474; + long i1475; + long i1476; + long i1477; + long i1478; + long i1479; + long i1480; + long i1481; + long i1482; + long i1483; + long i1484; + long i1485; + long i1486; + long i1487; + long i1488; + long i1489; + long i1490; + long i1491; + long i1492; + long i1493; + long i1494; + long i1495; + long i1496; + long i1497; + long i1498; + long i1499; + long i1500; + long i1501; + long i1502; + long i1503; + long i1504; + long i1505; + long i1506; + long i1507; + long i1508; + long i1509; + long i1510; + long i1511; + long i1512; + long i1513; + long i1514; + long i1515; + long i1516; + long i1517; + long i1518; + long i1519; + long i1520; + long i1521; + long i1522; + long i1523; + long i1524; + long i1525; + long i1526; + long i1527; + long i1528; + long i1529; + long i1530; + long i1531; + long i1532; + long i1533; + long i1534; + long i1535; + long i1536; + long i1537; + long i1538; + long i1539; + long i1540; + long i1541; + long i1542; + long i1543; + long i1544; + long i1545; + long i1546; + long i1547; + long i1548; + long i1549; + long i1550; + long i1551; + long i1552; + long i1553; + long i1554; + long i1555; + long i1556; + long i1557; + long i1558; + long i1559; + long i1560; + long i1561; + long i1562; + long i1563; + long i1564; + long i1565; + long i1566; + long i1567; + long i1568; + long i1569; + long i1570; + long i1571; + long i1572; + long i1573; + long i1574; + long i1575; + long i1576; + long i1577; + long i1578; + long i1579; + long i1580; + long i1581; + long i1582; + long i1583; + long i1584; + long i1585; + long i1586; + long i1587; + long i1588; + long i1589; + long i1590; + long i1591; + long i1592; + long i1593; + long i1594; + long i1595; + long i1596; + long i1597; + long i1598; + long i1599; + long i1600; + long i1601; + long i1602; + long i1603; + long i1604; + long i1605; + long i1606; + long i1607; + long i1608; + long i1609; + long i1610; + long i1611; + long i1612; + long i1613; + long i1614; + long i1615; + long i1616; + long i1617; + long i1618; + long i1619; + long i1620; + long i1621; + long i1622; + long i1623; + long i1624; + long i1625; + long i1626; + long i1627; + long i1628; + long i1629; + long i1630; + long i1631; + long i1632; + long i1633; + long i1634; + long i1635; + long i1636; + long i1637; + long i1638; + long i1639; + long i1640; + long i1641; + long i1642; + long i1643; + long i1644; + long i1645; + long i1646; + long i1647; + long i1648; + long i1649; + long i1650; + long i1651; + long i1652; + long i1653; + long i1654; + long i1655; + long i1656; + long i1657; + long i1658; + long i1659; + long i1660; + long i1661; + long i1662; + long i1663; + long i1664; + long i1665; + long i1666; + long i1667; + long i1668; + long i1669; + long i1670; + long i1671; + long i1672; + long i1673; + long i1674; + long i1675; + long i1676; + long i1677; + long i1678; + long i1679; + long i1680; + long i1681; + long i1682; + long i1683; + long i1684; + long i1685; + long i1686; + long i1687; + long i1688; + long i1689; + long i1690; + long i1691; + long i1692; + long i1693; + long i1694; + long i1695; + long i1696; + long i1697; + long i1698; + long i1699; + long i1700; + long i1701; + long i1702; + long i1703; + long i1704; + long i1705; + long i1706; + long i1707; + long i1708; + long i1709; + long i1710; + long i1711; + long i1712; + long i1713; + long i1714; + long i1715; + long i1716; + long i1717; + long i1718; + long i1719; + long i1720; + long i1721; + long i1722; + long i1723; + long i1724; + long i1725; + long i1726; + long i1727; + long i1728; + long i1729; + long i1730; + long i1731; + long i1732; + long i1733; + long i1734; + long i1735; + long i1736; + long i1737; + long i1738; + long i1739; + long i1740; + long i1741; + long i1742; + long i1743; + long i1744; + long i1745; + long i1746; + long i1747; + long i1748; + long i1749; + long i1750; + long i1751; + long i1752; + long i1753; + long i1754; + long i1755; + long i1756; + long i1757; + long i1758; + long i1759; + long i1760; + long i1761; + long i1762; + long i1763; + long i1764; + long i1765; + long i1766; + long i1767; + long i1768; + long i1769; + long i1770; + long i1771; + long i1772; + long i1773; + long i1774; + long i1775; + long i1776; + long i1777; + long i1778; + long i1779; + long i1780; + long i1781; + long i1782; + long i1783; + long i1784; + long i1785; + long i1786; + long i1787; + long i1788; + long i1789; + long i1790; + long i1791; + long i1792; + long i1793; + long i1794; + long i1795; + long i1796; + long i1797; + long i1798; + long i1799; + long i1800; + long i1801; + long i1802; + long i1803; + long i1804; + long i1805; + long i1806; + long i1807; + long i1808; + long i1809; + long i1810; + long i1811; + long i1812; + long i1813; + long i1814; + long i1815; + long i1816; + long i1817; + long i1818; + long i1819; + long i1820; + long i1821; + long i1822; + long i1823; + long i1824; + long i1825; + long i1826; + long i1827; + long i1828; + long i1829; + long i1830; + long i1831; + long i1832; + long i1833; + long i1834; + long i1835; + long i1836; + long i1837; + long i1838; + long i1839; + long i1840; + long i1841; + long i1842; + long i1843; + long i1844; + long i1845; + long i1846; + long i1847; + long i1848; + long i1849; + long i1850; + long i1851; + long i1852; + long i1853; + long i1854; + long i1855; + long i1856; + long i1857; + long i1858; + long i1859; + long i1860; + long i1861; + long i1862; + long i1863; + long i1864; + long i1865; + long i1866; + long i1867; + long i1868; + long i1869; + long i1870; + long i1871; + long i1872; + long i1873; + long i1874; + long i1875; + long i1876; + long i1877; + long i1878; + long i1879; + long i1880; + long i1881; + long i1882; + long i1883; + long i1884; + long i1885; + long i1886; + long i1887; + long i1888; + long i1889; + long i1890; + long i1891; + long i1892; + long i1893; + long i1894; + long i1895; + long i1896; + long i1897; + long i1898; + long i1899; + long i1900; + long i1901; + long i1902; + long i1903; + long i1904; + long i1905; + long i1906; + long i1907; + long i1908; + long i1909; + long i1910; + long i1911; + long i1912; + long i1913; + long i1914; + long i1915; + long i1916; + long i1917; + long i1918; + long i1919; + long i1920; + long i1921; + long i1922; + long i1923; + long i1924; + long i1925; + long i1926; + long i1927; + long i1928; + long i1929; + long i1930; + long i1931; + long i1932; + long i1933; + long i1934; + long i1935; + long i1936; + long i1937; + long i1938; + long i1939; + long i1940; + long i1941; + long i1942; + long i1943; + long i1944; + long i1945; + long i1946; + long i1947; + long i1948; + long i1949; + long i1950; + long i1951; + long i1952; + long i1953; + long i1954; + long i1955; + long i1956; + long i1957; + long i1958; + long i1959; + long i1960; + long i1961; + long i1962; + long i1963; + long i1964; + long i1965; + long i1966; + long i1967; + long i1968; + long i1969; + long i1970; + long i1971; + long i1972; + long i1973; + long i1974; + long i1975; + long i1976; + long i1977; + long i1978; + long i1979; + long i1980; + long i1981; + long i1982; + long i1983; + long i1984; + long i1985; + long i1986; + long i1987; + long i1988; + long i1989; + long i1990; + long i1991; + long i1992; + long i1993; + long i1994; + long i1995; + long i1996; + long i1997; + long i1998; + long i1999; + long i2000; + long i2001; + long i2002; + long i2003; + long i2004; + long i2005; + long i2006; + long i2007; + long i2008; + long i2009; + long i2010; + long i2011; + long i2012; + long i2013; + long i2014; + long i2015; + long i2016; + long i2017; + long i2018; + long i2019; + long i2020; + long i2021; + long i2022; + long i2023; + long i2024; + long i2025; + long i2026; + long i2027; + long i2028; + long i2029; + long i2030; + long i2031; + long i2032; + long i2033; + long i2034; + long i2035; + long i2036; + long i2037; + long i2038; + long i2039; + long i2040; + long i2041; + long i2042; + long i2043; + long i2044; + long i2045; + } + static class Class65536 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + long i254; + long i255; + long i256; + long i257; + long i258; + long i259; + long i260; + long i261; + long i262; + long i263; + long i264; + long i265; + long i266; + long i267; + long i268; + long i269; + long i270; + long i271; + long i272; + long i273; + long i274; + long i275; + long i276; + long i277; + long i278; + long i279; + long i280; + long i281; + long i282; + long i283; + long i284; + long i285; + long i286; + long i287; + long i288; + long i289; + long i290; + long i291; + long i292; + long i293; + long i294; + long i295; + long i296; + long i297; + long i298; + long i299; + long i300; + long i301; + long i302; + long i303; + long i304; + long i305; + long i306; + long i307; + long i308; + long i309; + long i310; + long i311; + long i312; + long i313; + long i314; + long i315; + long i316; + long i317; + long i318; + long i319; + long i320; + long i321; + long i322; + long i323; + long i324; + long i325; + long i326; + long i327; + long i328; + long i329; + long i330; + long i331; + long i332; + long i333; + long i334; + long i335; + long i336; + long i337; + long i338; + long i339; + long i340; + long i341; + long i342; + long i343; + long i344; + long i345; + long i346; + long i347; + long i348; + long i349; + long i350; + long i351; + long i352; + long i353; + long i354; + long i355; + long i356; + long i357; + long i358; + long i359; + long i360; + long i361; + long i362; + long i363; + long i364; + long i365; + long i366; + long i367; + long i368; + long i369; + long i370; + long i371; + long i372; + long i373; + long i374; + long i375; + long i376; + long i377; + long i378; + long i379; + long i380; + long i381; + long i382; + long i383; + long i384; + long i385; + long i386; + long i387; + long i388; + long i389; + long i390; + long i391; + long i392; + long i393; + long i394; + long i395; + long i396; + long i397; + long i398; + long i399; + long i400; + long i401; + long i402; + long i403; + long i404; + long i405; + long i406; + long i407; + long i408; + long i409; + long i410; + long i411; + long i412; + long i413; + long i414; + long i415; + long i416; + long i417; + long i418; + long i419; + long i420; + long i421; + long i422; + long i423; + long i424; + long i425; + long i426; + long i427; + long i428; + long i429; + long i430; + long i431; + long i432; + long i433; + long i434; + long i435; + long i436; + long i437; + long i438; + long i439; + long i440; + long i441; + long i442; + long i443; + long i444; + long i445; + long i446; + long i447; + long i448; + long i449; + long i450; + long i451; + long i452; + long i453; + long i454; + long i455; + long i456; + long i457; + long i458; + long i459; + long i460; + long i461; + long i462; + long i463; + long i464; + long i465; + long i466; + long i467; + long i468; + long i469; + long i470; + long i471; + long i472; + long i473; + long i474; + long i475; + long i476; + long i477; + long i478; + long i479; + long i480; + long i481; + long i482; + long i483; + long i484; + long i485; + long i486; + long i487; + long i488; + long i489; + long i490; + long i491; + long i492; + long i493; + long i494; + long i495; + long i496; + long i497; + long i498; + long i499; + long i500; + long i501; + long i502; + long i503; + long i504; + long i505; + long i506; + long i507; + long i508; + long i509; + long i510; + long i511; + long i512; + long i513; + long i514; + long i515; + long i516; + long i517; + long i518; + long i519; + long i520; + long i521; + long i522; + long i523; + long i524; + long i525; + long i526; + long i527; + long i528; + long i529; + long i530; + long i531; + long i532; + long i533; + long i534; + long i535; + long i536; + long i537; + long i538; + long i539; + long i540; + long i541; + long i542; + long i543; + long i544; + long i545; + long i546; + long i547; + long i548; + long i549; + long i550; + long i551; + long i552; + long i553; + long i554; + long i555; + long i556; + long i557; + long i558; + long i559; + long i560; + long i561; + long i562; + long i563; + long i564; + long i565; + long i566; + long i567; + long i568; + long i569; + long i570; + long i571; + long i572; + long i573; + long i574; + long i575; + long i576; + long i577; + long i578; + long i579; + long i580; + long i581; + long i582; + long i583; + long i584; + long i585; + long i586; + long i587; + long i588; + long i589; + long i590; + long i591; + long i592; + long i593; + long i594; + long i595; + long i596; + long i597; + long i598; + long i599; + long i600; + long i601; + long i602; + long i603; + long i604; + long i605; + long i606; + long i607; + long i608; + long i609; + long i610; + long i611; + long i612; + long i613; + long i614; + long i615; + long i616; + long i617; + long i618; + long i619; + long i620; + long i621; + long i622; + long i623; + long i624; + long i625; + long i626; + long i627; + long i628; + long i629; + long i630; + long i631; + long i632; + long i633; + long i634; + long i635; + long i636; + long i637; + long i638; + long i639; + long i640; + long i641; + long i642; + long i643; + long i644; + long i645; + long i646; + long i647; + long i648; + long i649; + long i650; + long i651; + long i652; + long i653; + long i654; + long i655; + long i656; + long i657; + long i658; + long i659; + long i660; + long i661; + long i662; + long i663; + long i664; + long i665; + long i666; + long i667; + long i668; + long i669; + long i670; + long i671; + long i672; + long i673; + long i674; + long i675; + long i676; + long i677; + long i678; + long i679; + long i680; + long i681; + long i682; + long i683; + long i684; + long i685; + long i686; + long i687; + long i688; + long i689; + long i690; + long i691; + long i692; + long i693; + long i694; + long i695; + long i696; + long i697; + long i698; + long i699; + long i700; + long i701; + long i702; + long i703; + long i704; + long i705; + long i706; + long i707; + long i708; + long i709; + long i710; + long i711; + long i712; + long i713; + long i714; + long i715; + long i716; + long i717; + long i718; + long i719; + long i720; + long i721; + long i722; + long i723; + long i724; + long i725; + long i726; + long i727; + long i728; + long i729; + long i730; + long i731; + long i732; + long i733; + long i734; + long i735; + long i736; + long i737; + long i738; + long i739; + long i740; + long i741; + long i742; + long i743; + long i744; + long i745; + long i746; + long i747; + long i748; + long i749; + long i750; + long i751; + long i752; + long i753; + long i754; + long i755; + long i756; + long i757; + long i758; + long i759; + long i760; + long i761; + long i762; + long i763; + long i764; + long i765; + long i766; + long i767; + long i768; + long i769; + long i770; + long i771; + long i772; + long i773; + long i774; + long i775; + long i776; + long i777; + long i778; + long i779; + long i780; + long i781; + long i782; + long i783; + long i784; + long i785; + long i786; + long i787; + long i788; + long i789; + long i790; + long i791; + long i792; + long i793; + long i794; + long i795; + long i796; + long i797; + long i798; + long i799; + long i800; + long i801; + long i802; + long i803; + long i804; + long i805; + long i806; + long i807; + long i808; + long i809; + long i810; + long i811; + long i812; + long i813; + long i814; + long i815; + long i816; + long i817; + long i818; + long i819; + long i820; + long i821; + long i822; + long i823; + long i824; + long i825; + long i826; + long i827; + long i828; + long i829; + long i830; + long i831; + long i832; + long i833; + long i834; + long i835; + long i836; + long i837; + long i838; + long i839; + long i840; + long i841; + long i842; + long i843; + long i844; + long i845; + long i846; + long i847; + long i848; + long i849; + long i850; + long i851; + long i852; + long i853; + long i854; + long i855; + long i856; + long i857; + long i858; + long i859; + long i860; + long i861; + long i862; + long i863; + long i864; + long i865; + long i866; + long i867; + long i868; + long i869; + long i870; + long i871; + long i872; + long i873; + long i874; + long i875; + long i876; + long i877; + long i878; + long i879; + long i880; + long i881; + long i882; + long i883; + long i884; + long i885; + long i886; + long i887; + long i888; + long i889; + long i890; + long i891; + long i892; + long i893; + long i894; + long i895; + long i896; + long i897; + long i898; + long i899; + long i900; + long i901; + long i902; + long i903; + long i904; + long i905; + long i906; + long i907; + long i908; + long i909; + long i910; + long i911; + long i912; + long i913; + long i914; + long i915; + long i916; + long i917; + long i918; + long i919; + long i920; + long i921; + long i922; + long i923; + long i924; + long i925; + long i926; + long i927; + long i928; + long i929; + long i930; + long i931; + long i932; + long i933; + long i934; + long i935; + long i936; + long i937; + long i938; + long i939; + long i940; + long i941; + long i942; + long i943; + long i944; + long i945; + long i946; + long i947; + long i948; + long i949; + long i950; + long i951; + long i952; + long i953; + long i954; + long i955; + long i956; + long i957; + long i958; + long i959; + long i960; + long i961; + long i962; + long i963; + long i964; + long i965; + long i966; + long i967; + long i968; + long i969; + long i970; + long i971; + long i972; + long i973; + long i974; + long i975; + long i976; + long i977; + long i978; + long i979; + long i980; + long i981; + long i982; + long i983; + long i984; + long i985; + long i986; + long i987; + long i988; + long i989; + long i990; + long i991; + long i992; + long i993; + long i994; + long i995; + long i996; + long i997; + long i998; + long i999; + long i1000; + long i1001; + long i1002; + long i1003; + long i1004; + long i1005; + long i1006; + long i1007; + long i1008; + long i1009; + long i1010; + long i1011; + long i1012; + long i1013; + long i1014; + long i1015; + long i1016; + long i1017; + long i1018; + long i1019; + long i1020; + long i1021; + long i1022; + long i1023; + long i1024; + long i1025; + long i1026; + long i1027; + long i1028; + long i1029; + long i1030; + long i1031; + long i1032; + long i1033; + long i1034; + long i1035; + long i1036; + long i1037; + long i1038; + long i1039; + long i1040; + long i1041; + long i1042; + long i1043; + long i1044; + long i1045; + long i1046; + long i1047; + long i1048; + long i1049; + long i1050; + long i1051; + long i1052; + long i1053; + long i1054; + long i1055; + long i1056; + long i1057; + long i1058; + long i1059; + long i1060; + long i1061; + long i1062; + long i1063; + long i1064; + long i1065; + long i1066; + long i1067; + long i1068; + long i1069; + long i1070; + long i1071; + long i1072; + long i1073; + long i1074; + long i1075; + long i1076; + long i1077; + long i1078; + long i1079; + long i1080; + long i1081; + long i1082; + long i1083; + long i1084; + long i1085; + long i1086; + long i1087; + long i1088; + long i1089; + long i1090; + long i1091; + long i1092; + long i1093; + long i1094; + long i1095; + long i1096; + long i1097; + long i1098; + long i1099; + long i1100; + long i1101; + long i1102; + long i1103; + long i1104; + long i1105; + long i1106; + long i1107; + long i1108; + long i1109; + long i1110; + long i1111; + long i1112; + long i1113; + long i1114; + long i1115; + long i1116; + long i1117; + long i1118; + long i1119; + long i1120; + long i1121; + long i1122; + long i1123; + long i1124; + long i1125; + long i1126; + long i1127; + long i1128; + long i1129; + long i1130; + long i1131; + long i1132; + long i1133; + long i1134; + long i1135; + long i1136; + long i1137; + long i1138; + long i1139; + long i1140; + long i1141; + long i1142; + long i1143; + long i1144; + long i1145; + long i1146; + long i1147; + long i1148; + long i1149; + long i1150; + long i1151; + long i1152; + long i1153; + long i1154; + long i1155; + long i1156; + long i1157; + long i1158; + long i1159; + long i1160; + long i1161; + long i1162; + long i1163; + long i1164; + long i1165; + long i1166; + long i1167; + long i1168; + long i1169; + long i1170; + long i1171; + long i1172; + long i1173; + long i1174; + long i1175; + long i1176; + long i1177; + long i1178; + long i1179; + long i1180; + long i1181; + long i1182; + long i1183; + long i1184; + long i1185; + long i1186; + long i1187; + long i1188; + long i1189; + long i1190; + long i1191; + long i1192; + long i1193; + long i1194; + long i1195; + long i1196; + long i1197; + long i1198; + long i1199; + long i1200; + long i1201; + long i1202; + long i1203; + long i1204; + long i1205; + long i1206; + long i1207; + long i1208; + long i1209; + long i1210; + long i1211; + long i1212; + long i1213; + long i1214; + long i1215; + long i1216; + long i1217; + long i1218; + long i1219; + long i1220; + long i1221; + long i1222; + long i1223; + long i1224; + long i1225; + long i1226; + long i1227; + long i1228; + long i1229; + long i1230; + long i1231; + long i1232; + long i1233; + long i1234; + long i1235; + long i1236; + long i1237; + long i1238; + long i1239; + long i1240; + long i1241; + long i1242; + long i1243; + long i1244; + long i1245; + long i1246; + long i1247; + long i1248; + long i1249; + long i1250; + long i1251; + long i1252; + long i1253; + long i1254; + long i1255; + long i1256; + long i1257; + long i1258; + long i1259; + long i1260; + long i1261; + long i1262; + long i1263; + long i1264; + long i1265; + long i1266; + long i1267; + long i1268; + long i1269; + long i1270; + long i1271; + long i1272; + long i1273; + long i1274; + long i1275; + long i1276; + long i1277; + long i1278; + long i1279; + long i1280; + long i1281; + long i1282; + long i1283; + long i1284; + long i1285; + long i1286; + long i1287; + long i1288; + long i1289; + long i1290; + long i1291; + long i1292; + long i1293; + long i1294; + long i1295; + long i1296; + long i1297; + long i1298; + long i1299; + long i1300; + long i1301; + long i1302; + long i1303; + long i1304; + long i1305; + long i1306; + long i1307; + long i1308; + long i1309; + long i1310; + long i1311; + long i1312; + long i1313; + long i1314; + long i1315; + long i1316; + long i1317; + long i1318; + long i1319; + long i1320; + long i1321; + long i1322; + long i1323; + long i1324; + long i1325; + long i1326; + long i1327; + long i1328; + long i1329; + long i1330; + long i1331; + long i1332; + long i1333; + long i1334; + long i1335; + long i1336; + long i1337; + long i1338; + long i1339; + long i1340; + long i1341; + long i1342; + long i1343; + long i1344; + long i1345; + long i1346; + long i1347; + long i1348; + long i1349; + long i1350; + long i1351; + long i1352; + long i1353; + long i1354; + long i1355; + long i1356; + long i1357; + long i1358; + long i1359; + long i1360; + long i1361; + long i1362; + long i1363; + long i1364; + long i1365; + long i1366; + long i1367; + long i1368; + long i1369; + long i1370; + long i1371; + long i1372; + long i1373; + long i1374; + long i1375; + long i1376; + long i1377; + long i1378; + long i1379; + long i1380; + long i1381; + long i1382; + long i1383; + long i1384; + long i1385; + long i1386; + long i1387; + long i1388; + long i1389; + long i1390; + long i1391; + long i1392; + long i1393; + long i1394; + long i1395; + long i1396; + long i1397; + long i1398; + long i1399; + long i1400; + long i1401; + long i1402; + long i1403; + long i1404; + long i1405; + long i1406; + long i1407; + long i1408; + long i1409; + long i1410; + long i1411; + long i1412; + long i1413; + long i1414; + long i1415; + long i1416; + long i1417; + long i1418; + long i1419; + long i1420; + long i1421; + long i1422; + long i1423; + long i1424; + long i1425; + long i1426; + long i1427; + long i1428; + long i1429; + long i1430; + long i1431; + long i1432; + long i1433; + long i1434; + long i1435; + long i1436; + long i1437; + long i1438; + long i1439; + long i1440; + long i1441; + long i1442; + long i1443; + long i1444; + long i1445; + long i1446; + long i1447; + long i1448; + long i1449; + long i1450; + long i1451; + long i1452; + long i1453; + long i1454; + long i1455; + long i1456; + long i1457; + long i1458; + long i1459; + long i1460; + long i1461; + long i1462; + long i1463; + long i1464; + long i1465; + long i1466; + long i1467; + long i1468; + long i1469; + long i1470; + long i1471; + long i1472; + long i1473; + long i1474; + long i1475; + long i1476; + long i1477; + long i1478; + long i1479; + long i1480; + long i1481; + long i1482; + long i1483; + long i1484; + long i1485; + long i1486; + long i1487; + long i1488; + long i1489; + long i1490; + long i1491; + long i1492; + long i1493; + long i1494; + long i1495; + long i1496; + long i1497; + long i1498; + long i1499; + long i1500; + long i1501; + long i1502; + long i1503; + long i1504; + long i1505; + long i1506; + long i1507; + long i1508; + long i1509; + long i1510; + long i1511; + long i1512; + long i1513; + long i1514; + long i1515; + long i1516; + long i1517; + long i1518; + long i1519; + long i1520; + long i1521; + long i1522; + long i1523; + long i1524; + long i1525; + long i1526; + long i1527; + long i1528; + long i1529; + long i1530; + long i1531; + long i1532; + long i1533; + long i1534; + long i1535; + long i1536; + long i1537; + long i1538; + long i1539; + long i1540; + long i1541; + long i1542; + long i1543; + long i1544; + long i1545; + long i1546; + long i1547; + long i1548; + long i1549; + long i1550; + long i1551; + long i1552; + long i1553; + long i1554; + long i1555; + long i1556; + long i1557; + long i1558; + long i1559; + long i1560; + long i1561; + long i1562; + long i1563; + long i1564; + long i1565; + long i1566; + long i1567; + long i1568; + long i1569; + long i1570; + long i1571; + long i1572; + long i1573; + long i1574; + long i1575; + long i1576; + long i1577; + long i1578; + long i1579; + long i1580; + long i1581; + long i1582; + long i1583; + long i1584; + long i1585; + long i1586; + long i1587; + long i1588; + long i1589; + long i1590; + long i1591; + long i1592; + long i1593; + long i1594; + long i1595; + long i1596; + long i1597; + long i1598; + long i1599; + long i1600; + long i1601; + long i1602; + long i1603; + long i1604; + long i1605; + long i1606; + long i1607; + long i1608; + long i1609; + long i1610; + long i1611; + long i1612; + long i1613; + long i1614; + long i1615; + long i1616; + long i1617; + long i1618; + long i1619; + long i1620; + long i1621; + long i1622; + long i1623; + long i1624; + long i1625; + long i1626; + long i1627; + long i1628; + long i1629; + long i1630; + long i1631; + long i1632; + long i1633; + long i1634; + long i1635; + long i1636; + long i1637; + long i1638; + long i1639; + long i1640; + long i1641; + long i1642; + long i1643; + long i1644; + long i1645; + long i1646; + long i1647; + long i1648; + long i1649; + long i1650; + long i1651; + long i1652; + long i1653; + long i1654; + long i1655; + long i1656; + long i1657; + long i1658; + long i1659; + long i1660; + long i1661; + long i1662; + long i1663; + long i1664; + long i1665; + long i1666; + long i1667; + long i1668; + long i1669; + long i1670; + long i1671; + long i1672; + long i1673; + long i1674; + long i1675; + long i1676; + long i1677; + long i1678; + long i1679; + long i1680; + long i1681; + long i1682; + long i1683; + long i1684; + long i1685; + long i1686; + long i1687; + long i1688; + long i1689; + long i1690; + long i1691; + long i1692; + long i1693; + long i1694; + long i1695; + long i1696; + long i1697; + long i1698; + long i1699; + long i1700; + long i1701; + long i1702; + long i1703; + long i1704; + long i1705; + long i1706; + long i1707; + long i1708; + long i1709; + long i1710; + long i1711; + long i1712; + long i1713; + long i1714; + long i1715; + long i1716; + long i1717; + long i1718; + long i1719; + long i1720; + long i1721; + long i1722; + long i1723; + long i1724; + long i1725; + long i1726; + long i1727; + long i1728; + long i1729; + long i1730; + long i1731; + long i1732; + long i1733; + long i1734; + long i1735; + long i1736; + long i1737; + long i1738; + long i1739; + long i1740; + long i1741; + long i1742; + long i1743; + long i1744; + long i1745; + long i1746; + long i1747; + long i1748; + long i1749; + long i1750; + long i1751; + long i1752; + long i1753; + long i1754; + long i1755; + long i1756; + long i1757; + long i1758; + long i1759; + long i1760; + long i1761; + long i1762; + long i1763; + long i1764; + long i1765; + long i1766; + long i1767; + long i1768; + long i1769; + long i1770; + long i1771; + long i1772; + long i1773; + long i1774; + long i1775; + long i1776; + long i1777; + long i1778; + long i1779; + long i1780; + long i1781; + long i1782; + long i1783; + long i1784; + long i1785; + long i1786; + long i1787; + long i1788; + long i1789; + long i1790; + long i1791; + long i1792; + long i1793; + long i1794; + long i1795; + long i1796; + long i1797; + long i1798; + long i1799; + long i1800; + long i1801; + long i1802; + long i1803; + long i1804; + long i1805; + long i1806; + long i1807; + long i1808; + long i1809; + long i1810; + long i1811; + long i1812; + long i1813; + long i1814; + long i1815; + long i1816; + long i1817; + long i1818; + long i1819; + long i1820; + long i1821; + long i1822; + long i1823; + long i1824; + long i1825; + long i1826; + long i1827; + long i1828; + long i1829; + long i1830; + long i1831; + long i1832; + long i1833; + long i1834; + long i1835; + long i1836; + long i1837; + long i1838; + long i1839; + long i1840; + long i1841; + long i1842; + long i1843; + long i1844; + long i1845; + long i1846; + long i1847; + long i1848; + long i1849; + long i1850; + long i1851; + long i1852; + long i1853; + long i1854; + long i1855; + long i1856; + long i1857; + long i1858; + long i1859; + long i1860; + long i1861; + long i1862; + long i1863; + long i1864; + long i1865; + long i1866; + long i1867; + long i1868; + long i1869; + long i1870; + long i1871; + long i1872; + long i1873; + long i1874; + long i1875; + long i1876; + long i1877; + long i1878; + long i1879; + long i1880; + long i1881; + long i1882; + long i1883; + long i1884; + long i1885; + long i1886; + long i1887; + long i1888; + long i1889; + long i1890; + long i1891; + long i1892; + long i1893; + long i1894; + long i1895; + long i1896; + long i1897; + long i1898; + long i1899; + long i1900; + long i1901; + long i1902; + long i1903; + long i1904; + long i1905; + long i1906; + long i1907; + long i1908; + long i1909; + long i1910; + long i1911; + long i1912; + long i1913; + long i1914; + long i1915; + long i1916; + long i1917; + long i1918; + long i1919; + long i1920; + long i1921; + long i1922; + long i1923; + long i1924; + long i1925; + long i1926; + long i1927; + long i1928; + long i1929; + long i1930; + long i1931; + long i1932; + long i1933; + long i1934; + long i1935; + long i1936; + long i1937; + long i1938; + long i1939; + long i1940; + long i1941; + long i1942; + long i1943; + long i1944; + long i1945; + long i1946; + long i1947; + long i1948; + long i1949; + long i1950; + long i1951; + long i1952; + long i1953; + long i1954; + long i1955; + long i1956; + long i1957; + long i1958; + long i1959; + long i1960; + long i1961; + long i1962; + long i1963; + long i1964; + long i1965; + long i1966; + long i1967; + long i1968; + long i1969; + long i1970; + long i1971; + long i1972; + long i1973; + long i1974; + long i1975; + long i1976; + long i1977; + long i1978; + long i1979; + long i1980; + long i1981; + long i1982; + long i1983; + long i1984; + long i1985; + long i1986; + long i1987; + long i1988; + long i1989; + long i1990; + long i1991; + long i1992; + long i1993; + long i1994; + long i1995; + long i1996; + long i1997; + long i1998; + long i1999; + long i2000; + long i2001; + long i2002; + long i2003; + long i2004; + long i2005; + long i2006; + long i2007; + long i2008; + long i2009; + long i2010; + long i2011; + long i2012; + long i2013; + long i2014; + long i2015; + long i2016; + long i2017; + long i2018; + long i2019; + long i2020; + long i2021; + long i2022; + long i2023; + long i2024; + long i2025; + long i2026; + long i2027; + long i2028; + long i2029; + long i2030; + long i2031; + long i2032; + long i2033; + long i2034; + long i2035; + long i2036; + long i2037; + long i2038; + long i2039; + long i2040; + long i2041; + long i2042; + long i2043; + long i2044; + long i2045; + long i2046; + long i2047; + long i2048; + long i2049; + long i2050; + long i2051; + long i2052; + long i2053; + long i2054; + long i2055; + long i2056; + long i2057; + long i2058; + long i2059; + long i2060; + long i2061; + long i2062; + long i2063; + long i2064; + long i2065; + long i2066; + long i2067; + long i2068; + long i2069; + long i2070; + long i2071; + long i2072; + long i2073; + long i2074; + long i2075; + long i2076; + long i2077; + long i2078; + long i2079; + long i2080; + long i2081; + long i2082; + long i2083; + long i2084; + long i2085; + long i2086; + long i2087; + long i2088; + long i2089; + long i2090; + long i2091; + long i2092; + long i2093; + long i2094; + long i2095; + long i2096; + long i2097; + long i2098; + long i2099; + long i2100; + long i2101; + long i2102; + long i2103; + long i2104; + long i2105; + long i2106; + long i2107; + long i2108; + long i2109; + long i2110; + long i2111; + long i2112; + long i2113; + long i2114; + long i2115; + long i2116; + long i2117; + long i2118; + long i2119; + long i2120; + long i2121; + long i2122; + long i2123; + long i2124; + long i2125; + long i2126; + long i2127; + long i2128; + long i2129; + long i2130; + long i2131; + long i2132; + long i2133; + long i2134; + long i2135; + long i2136; + long i2137; + long i2138; + long i2139; + long i2140; + long i2141; + long i2142; + long i2143; + long i2144; + long i2145; + long i2146; + long i2147; + long i2148; + long i2149; + long i2150; + long i2151; + long i2152; + long i2153; + long i2154; + long i2155; + long i2156; + long i2157; + long i2158; + long i2159; + long i2160; + long i2161; + long i2162; + long i2163; + long i2164; + long i2165; + long i2166; + long i2167; + long i2168; + long i2169; + long i2170; + long i2171; + long i2172; + long i2173; + long i2174; + long i2175; + long i2176; + long i2177; + long i2178; + long i2179; + long i2180; + long i2181; + long i2182; + long i2183; + long i2184; + long i2185; + long i2186; + long i2187; + long i2188; + long i2189; + long i2190; + long i2191; + long i2192; + long i2193; + long i2194; + long i2195; + long i2196; + long i2197; + long i2198; + long i2199; + long i2200; + long i2201; + long i2202; + long i2203; + long i2204; + long i2205; + long i2206; + long i2207; + long i2208; + long i2209; + long i2210; + long i2211; + long i2212; + long i2213; + long i2214; + long i2215; + long i2216; + long i2217; + long i2218; + long i2219; + long i2220; + long i2221; + long i2222; + long i2223; + long i2224; + long i2225; + long i2226; + long i2227; + long i2228; + long i2229; + long i2230; + long i2231; + long i2232; + long i2233; + long i2234; + long i2235; + long i2236; + long i2237; + long i2238; + long i2239; + long i2240; + long i2241; + long i2242; + long i2243; + long i2244; + long i2245; + long i2246; + long i2247; + long i2248; + long i2249; + long i2250; + long i2251; + long i2252; + long i2253; + long i2254; + long i2255; + long i2256; + long i2257; + long i2258; + long i2259; + long i2260; + long i2261; + long i2262; + long i2263; + long i2264; + long i2265; + long i2266; + long i2267; + long i2268; + long i2269; + long i2270; + long i2271; + long i2272; + long i2273; + long i2274; + long i2275; + long i2276; + long i2277; + long i2278; + long i2279; + long i2280; + long i2281; + long i2282; + long i2283; + long i2284; + long i2285; + long i2286; + long i2287; + long i2288; + long i2289; + long i2290; + long i2291; + long i2292; + long i2293; + long i2294; + long i2295; + long i2296; + long i2297; + long i2298; + long i2299; + long i2300; + long i2301; + long i2302; + long i2303; + long i2304; + long i2305; + long i2306; + long i2307; + long i2308; + long i2309; + long i2310; + long i2311; + long i2312; + long i2313; + long i2314; + long i2315; + long i2316; + long i2317; + long i2318; + long i2319; + long i2320; + long i2321; + long i2322; + long i2323; + long i2324; + long i2325; + long i2326; + long i2327; + long i2328; + long i2329; + long i2330; + long i2331; + long i2332; + long i2333; + long i2334; + long i2335; + long i2336; + long i2337; + long i2338; + long i2339; + long i2340; + long i2341; + long i2342; + long i2343; + long i2344; + long i2345; + long i2346; + long i2347; + long i2348; + long i2349; + long i2350; + long i2351; + long i2352; + long i2353; + long i2354; + long i2355; + long i2356; + long i2357; + long i2358; + long i2359; + long i2360; + long i2361; + long i2362; + long i2363; + long i2364; + long i2365; + long i2366; + long i2367; + long i2368; + long i2369; + long i2370; + long i2371; + long i2372; + long i2373; + long i2374; + long i2375; + long i2376; + long i2377; + long i2378; + long i2379; + long i2380; + long i2381; + long i2382; + long i2383; + long i2384; + long i2385; + long i2386; + long i2387; + long i2388; + long i2389; + long i2390; + long i2391; + long i2392; + long i2393; + long i2394; + long i2395; + long i2396; + long i2397; + long i2398; + long i2399; + long i2400; + long i2401; + long i2402; + long i2403; + long i2404; + long i2405; + long i2406; + long i2407; + long i2408; + long i2409; + long i2410; + long i2411; + long i2412; + long i2413; + long i2414; + long i2415; + long i2416; + long i2417; + long i2418; + long i2419; + long i2420; + long i2421; + long i2422; + long i2423; + long i2424; + long i2425; + long i2426; + long i2427; + long i2428; + long i2429; + long i2430; + long i2431; + long i2432; + long i2433; + long i2434; + long i2435; + long i2436; + long i2437; + long i2438; + long i2439; + long i2440; + long i2441; + long i2442; + long i2443; + long i2444; + long i2445; + long i2446; + long i2447; + long i2448; + long i2449; + long i2450; + long i2451; + long i2452; + long i2453; + long i2454; + long i2455; + long i2456; + long i2457; + long i2458; + long i2459; + long i2460; + long i2461; + long i2462; + long i2463; + long i2464; + long i2465; + long i2466; + long i2467; + long i2468; + long i2469; + long i2470; + long i2471; + long i2472; + long i2473; + long i2474; + long i2475; + long i2476; + long i2477; + long i2478; + long i2479; + long i2480; + long i2481; + long i2482; + long i2483; + long i2484; + long i2485; + long i2486; + long i2487; + long i2488; + long i2489; + long i2490; + long i2491; + long i2492; + long i2493; + long i2494; + long i2495; + long i2496; + long i2497; + long i2498; + long i2499; + long i2500; + long i2501; + long i2502; + long i2503; + long i2504; + long i2505; + long i2506; + long i2507; + long i2508; + long i2509; + long i2510; + long i2511; + long i2512; + long i2513; + long i2514; + long i2515; + long i2516; + long i2517; + long i2518; + long i2519; + long i2520; + long i2521; + long i2522; + long i2523; + long i2524; + long i2525; + long i2526; + long i2527; + long i2528; + long i2529; + long i2530; + long i2531; + long i2532; + long i2533; + long i2534; + long i2535; + long i2536; + long i2537; + long i2538; + long i2539; + long i2540; + long i2541; + long i2542; + long i2543; + long i2544; + long i2545; + long i2546; + long i2547; + long i2548; + long i2549; + long i2550; + long i2551; + long i2552; + long i2553; + long i2554; + long i2555; + long i2556; + long i2557; + long i2558; + long i2559; + long i2560; + long i2561; + long i2562; + long i2563; + long i2564; + long i2565; + long i2566; + long i2567; + long i2568; + long i2569; + long i2570; + long i2571; + long i2572; + long i2573; + long i2574; + long i2575; + long i2576; + long i2577; + long i2578; + long i2579; + long i2580; + long i2581; + long i2582; + long i2583; + long i2584; + long i2585; + long i2586; + long i2587; + long i2588; + long i2589; + long i2590; + long i2591; + long i2592; + long i2593; + long i2594; + long i2595; + long i2596; + long i2597; + long i2598; + long i2599; + long i2600; + long i2601; + long i2602; + long i2603; + long i2604; + long i2605; + long i2606; + long i2607; + long i2608; + long i2609; + long i2610; + long i2611; + long i2612; + long i2613; + long i2614; + long i2615; + long i2616; + long i2617; + long i2618; + long i2619; + long i2620; + long i2621; + long i2622; + long i2623; + long i2624; + long i2625; + long i2626; + long i2627; + long i2628; + long i2629; + long i2630; + long i2631; + long i2632; + long i2633; + long i2634; + long i2635; + long i2636; + long i2637; + long i2638; + long i2639; + long i2640; + long i2641; + long i2642; + long i2643; + long i2644; + long i2645; + long i2646; + long i2647; + long i2648; + long i2649; + long i2650; + long i2651; + long i2652; + long i2653; + long i2654; + long i2655; + long i2656; + long i2657; + long i2658; + long i2659; + long i2660; + long i2661; + long i2662; + long i2663; + long i2664; + long i2665; + long i2666; + long i2667; + long i2668; + long i2669; + long i2670; + long i2671; + long i2672; + long i2673; + long i2674; + long i2675; + long i2676; + long i2677; + long i2678; + long i2679; + long i2680; + long i2681; + long i2682; + long i2683; + long i2684; + long i2685; + long i2686; + long i2687; + long i2688; + long i2689; + long i2690; + long i2691; + long i2692; + long i2693; + long i2694; + long i2695; + long i2696; + long i2697; + long i2698; + long i2699; + long i2700; + long i2701; + long i2702; + long i2703; + long i2704; + long i2705; + long i2706; + long i2707; + long i2708; + long i2709; + long i2710; + long i2711; + long i2712; + long i2713; + long i2714; + long i2715; + long i2716; + long i2717; + long i2718; + long i2719; + long i2720; + long i2721; + long i2722; + long i2723; + long i2724; + long i2725; + long i2726; + long i2727; + long i2728; + long i2729; + long i2730; + long i2731; + long i2732; + long i2733; + long i2734; + long i2735; + long i2736; + long i2737; + long i2738; + long i2739; + long i2740; + long i2741; + long i2742; + long i2743; + long i2744; + long i2745; + long i2746; + long i2747; + long i2748; + long i2749; + long i2750; + long i2751; + long i2752; + long i2753; + long i2754; + long i2755; + long i2756; + long i2757; + long i2758; + long i2759; + long i2760; + long i2761; + long i2762; + long i2763; + long i2764; + long i2765; + long i2766; + long i2767; + long i2768; + long i2769; + long i2770; + long i2771; + long i2772; + long i2773; + long i2774; + long i2775; + long i2776; + long i2777; + long i2778; + long i2779; + long i2780; + long i2781; + long i2782; + long i2783; + long i2784; + long i2785; + long i2786; + long i2787; + long i2788; + long i2789; + long i2790; + long i2791; + long i2792; + long i2793; + long i2794; + long i2795; + long i2796; + long i2797; + long i2798; + long i2799; + long i2800; + long i2801; + long i2802; + long i2803; + long i2804; + long i2805; + long i2806; + long i2807; + long i2808; + long i2809; + long i2810; + long i2811; + long i2812; + long i2813; + long i2814; + long i2815; + long i2816; + long i2817; + long i2818; + long i2819; + long i2820; + long i2821; + long i2822; + long i2823; + long i2824; + long i2825; + long i2826; + long i2827; + long i2828; + long i2829; + long i2830; + long i2831; + long i2832; + long i2833; + long i2834; + long i2835; + long i2836; + long i2837; + long i2838; + long i2839; + long i2840; + long i2841; + long i2842; + long i2843; + long i2844; + long i2845; + long i2846; + long i2847; + long i2848; + long i2849; + long i2850; + long i2851; + long i2852; + long i2853; + long i2854; + long i2855; + long i2856; + long i2857; + long i2858; + long i2859; + long i2860; + long i2861; + long i2862; + long i2863; + long i2864; + long i2865; + long i2866; + long i2867; + long i2868; + long i2869; + long i2870; + long i2871; + long i2872; + long i2873; + long i2874; + long i2875; + long i2876; + long i2877; + long i2878; + long i2879; + long i2880; + long i2881; + long i2882; + long i2883; + long i2884; + long i2885; + long i2886; + long i2887; + long i2888; + long i2889; + long i2890; + long i2891; + long i2892; + long i2893; + long i2894; + long i2895; + long i2896; + long i2897; + long i2898; + long i2899; + long i2900; + long i2901; + long i2902; + long i2903; + long i2904; + long i2905; + long i2906; + long i2907; + long i2908; + long i2909; + long i2910; + long i2911; + long i2912; + long i2913; + long i2914; + long i2915; + long i2916; + long i2917; + long i2918; + long i2919; + long i2920; + long i2921; + long i2922; + long i2923; + long i2924; + long i2925; + long i2926; + long i2927; + long i2928; + long i2929; + long i2930; + long i2931; + long i2932; + long i2933; + long i2934; + long i2935; + long i2936; + long i2937; + long i2938; + long i2939; + long i2940; + long i2941; + long i2942; + long i2943; + long i2944; + long i2945; + long i2946; + long i2947; + long i2948; + long i2949; + long i2950; + long i2951; + long i2952; + long i2953; + long i2954; + long i2955; + long i2956; + long i2957; + long i2958; + long i2959; + long i2960; + long i2961; + long i2962; + long i2963; + long i2964; + long i2965; + long i2966; + long i2967; + long i2968; + long i2969; + long i2970; + long i2971; + long i2972; + long i2973; + long i2974; + long i2975; + long i2976; + long i2977; + long i2978; + long i2979; + long i2980; + long i2981; + long i2982; + long i2983; + long i2984; + long i2985; + long i2986; + long i2987; + long i2988; + long i2989; + long i2990; + long i2991; + long i2992; + long i2993; + long i2994; + long i2995; + long i2996; + long i2997; + long i2998; + long i2999; + long i3000; + long i3001; + long i3002; + long i3003; + long i3004; + long i3005; + long i3006; + long i3007; + long i3008; + long i3009; + long i3010; + long i3011; + long i3012; + long i3013; + long i3014; + long i3015; + long i3016; + long i3017; + long i3018; + long i3019; + long i3020; + long i3021; + long i3022; + long i3023; + long i3024; + long i3025; + long i3026; + long i3027; + long i3028; + long i3029; + long i3030; + long i3031; + long i3032; + long i3033; + long i3034; + long i3035; + long i3036; + long i3037; + long i3038; + long i3039; + long i3040; + long i3041; + long i3042; + long i3043; + long i3044; + long i3045; + long i3046; + long i3047; + long i3048; + long i3049; + long i3050; + long i3051; + long i3052; + long i3053; + long i3054; + long i3055; + long i3056; + long i3057; + long i3058; + long i3059; + long i3060; + long i3061; + long i3062; + long i3063; + long i3064; + long i3065; + long i3066; + long i3067; + long i3068; + long i3069; + long i3070; + long i3071; + long i3072; + long i3073; + long i3074; + long i3075; + long i3076; + long i3077; + long i3078; + long i3079; + long i3080; + long i3081; + long i3082; + long i3083; + long i3084; + long i3085; + long i3086; + long i3087; + long i3088; + long i3089; + long i3090; + long i3091; + long i3092; + long i3093; + long i3094; + long i3095; + long i3096; + long i3097; + long i3098; + long i3099; + long i3100; + long i3101; + long i3102; + long i3103; + long i3104; + long i3105; + long i3106; + long i3107; + long i3108; + long i3109; + long i3110; + long i3111; + long i3112; + long i3113; + long i3114; + long i3115; + long i3116; + long i3117; + long i3118; + long i3119; + long i3120; + long i3121; + long i3122; + long i3123; + long i3124; + long i3125; + long i3126; + long i3127; + long i3128; + long i3129; + long i3130; + long i3131; + long i3132; + long i3133; + long i3134; + long i3135; + long i3136; + long i3137; + long i3138; + long i3139; + long i3140; + long i3141; + long i3142; + long i3143; + long i3144; + long i3145; + long i3146; + long i3147; + long i3148; + long i3149; + long i3150; + long i3151; + long i3152; + long i3153; + long i3154; + long i3155; + long i3156; + long i3157; + long i3158; + long i3159; + long i3160; + long i3161; + long i3162; + long i3163; + long i3164; + long i3165; + long i3166; + long i3167; + long i3168; + long i3169; + long i3170; + long i3171; + long i3172; + long i3173; + long i3174; + long i3175; + long i3176; + long i3177; + long i3178; + long i3179; + long i3180; + long i3181; + long i3182; + long i3183; + long i3184; + long i3185; + long i3186; + long i3187; + long i3188; + long i3189; + long i3190; + long i3191; + long i3192; + long i3193; + long i3194; + long i3195; + long i3196; + long i3197; + long i3198; + long i3199; + long i3200; + long i3201; + long i3202; + long i3203; + long i3204; + long i3205; + long i3206; + long i3207; + long i3208; + long i3209; + long i3210; + long i3211; + long i3212; + long i3213; + long i3214; + long i3215; + long i3216; + long i3217; + long i3218; + long i3219; + long i3220; + long i3221; + long i3222; + long i3223; + long i3224; + long i3225; + long i3226; + long i3227; + long i3228; + long i3229; + long i3230; + long i3231; + long i3232; + long i3233; + long i3234; + long i3235; + long i3236; + long i3237; + long i3238; + long i3239; + long i3240; + long i3241; + long i3242; + long i3243; + long i3244; + long i3245; + long i3246; + long i3247; + long i3248; + long i3249; + long i3250; + long i3251; + long i3252; + long i3253; + long i3254; + long i3255; + long i3256; + long i3257; + long i3258; + long i3259; + long i3260; + long i3261; + long i3262; + long i3263; + long i3264; + long i3265; + long i3266; + long i3267; + long i3268; + long i3269; + long i3270; + long i3271; + long i3272; + long i3273; + long i3274; + long i3275; + long i3276; + long i3277; + long i3278; + long i3279; + long i3280; + long i3281; + long i3282; + long i3283; + long i3284; + long i3285; + long i3286; + long i3287; + long i3288; + long i3289; + long i3290; + long i3291; + long i3292; + long i3293; + long i3294; + long i3295; + long i3296; + long i3297; + long i3298; + long i3299; + long i3300; + long i3301; + long i3302; + long i3303; + long i3304; + long i3305; + long i3306; + long i3307; + long i3308; + long i3309; + long i3310; + long i3311; + long i3312; + long i3313; + long i3314; + long i3315; + long i3316; + long i3317; + long i3318; + long i3319; + long i3320; + long i3321; + long i3322; + long i3323; + long i3324; + long i3325; + long i3326; + long i3327; + long i3328; + long i3329; + long i3330; + long i3331; + long i3332; + long i3333; + long i3334; + long i3335; + long i3336; + long i3337; + long i3338; + long i3339; + long i3340; + long i3341; + long i3342; + long i3343; + long i3344; + long i3345; + long i3346; + long i3347; + long i3348; + long i3349; + long i3350; + long i3351; + long i3352; + long i3353; + long i3354; + long i3355; + long i3356; + long i3357; + long i3358; + long i3359; + long i3360; + long i3361; + long i3362; + long i3363; + long i3364; + long i3365; + long i3366; + long i3367; + long i3368; + long i3369; + long i3370; + long i3371; + long i3372; + long i3373; + long i3374; + long i3375; + long i3376; + long i3377; + long i3378; + long i3379; + long i3380; + long i3381; + long i3382; + long i3383; + long i3384; + long i3385; + long i3386; + long i3387; + long i3388; + long i3389; + long i3390; + long i3391; + long i3392; + long i3393; + long i3394; + long i3395; + long i3396; + long i3397; + long i3398; + long i3399; + long i3400; + long i3401; + long i3402; + long i3403; + long i3404; + long i3405; + long i3406; + long i3407; + long i3408; + long i3409; + long i3410; + long i3411; + long i3412; + long i3413; + long i3414; + long i3415; + long i3416; + long i3417; + long i3418; + long i3419; + long i3420; + long i3421; + long i3422; + long i3423; + long i3424; + long i3425; + long i3426; + long i3427; + long i3428; + long i3429; + long i3430; + long i3431; + long i3432; + long i3433; + long i3434; + long i3435; + long i3436; + long i3437; + long i3438; + long i3439; + long i3440; + long i3441; + long i3442; + long i3443; + long i3444; + long i3445; + long i3446; + long i3447; + long i3448; + long i3449; + long i3450; + long i3451; + long i3452; + long i3453; + long i3454; + long i3455; + long i3456; + long i3457; + long i3458; + long i3459; + long i3460; + long i3461; + long i3462; + long i3463; + long i3464; + long i3465; + long i3466; + long i3467; + long i3468; + long i3469; + long i3470; + long i3471; + long i3472; + long i3473; + long i3474; + long i3475; + long i3476; + long i3477; + long i3478; + long i3479; + long i3480; + long i3481; + long i3482; + long i3483; + long i3484; + long i3485; + long i3486; + long i3487; + long i3488; + long i3489; + long i3490; + long i3491; + long i3492; + long i3493; + long i3494; + long i3495; + long i3496; + long i3497; + long i3498; + long i3499; + long i3500; + long i3501; + long i3502; + long i3503; + long i3504; + long i3505; + long i3506; + long i3507; + long i3508; + long i3509; + long i3510; + long i3511; + long i3512; + long i3513; + long i3514; + long i3515; + long i3516; + long i3517; + long i3518; + long i3519; + long i3520; + long i3521; + long i3522; + long i3523; + long i3524; + long i3525; + long i3526; + long i3527; + long i3528; + long i3529; + long i3530; + long i3531; + long i3532; + long i3533; + long i3534; + long i3535; + long i3536; + long i3537; + long i3538; + long i3539; + long i3540; + long i3541; + long i3542; + long i3543; + long i3544; + long i3545; + long i3546; + long i3547; + long i3548; + long i3549; + long i3550; + long i3551; + long i3552; + long i3553; + long i3554; + long i3555; + long i3556; + long i3557; + long i3558; + long i3559; + long i3560; + long i3561; + long i3562; + long i3563; + long i3564; + long i3565; + long i3566; + long i3567; + long i3568; + long i3569; + long i3570; + long i3571; + long i3572; + long i3573; + long i3574; + long i3575; + long i3576; + long i3577; + long i3578; + long i3579; + long i3580; + long i3581; + long i3582; + long i3583; + long i3584; + long i3585; + long i3586; + long i3587; + long i3588; + long i3589; + long i3590; + long i3591; + long i3592; + long i3593; + long i3594; + long i3595; + long i3596; + long i3597; + long i3598; + long i3599; + long i3600; + long i3601; + long i3602; + long i3603; + long i3604; + long i3605; + long i3606; + long i3607; + long i3608; + long i3609; + long i3610; + long i3611; + long i3612; + long i3613; + long i3614; + long i3615; + long i3616; + long i3617; + long i3618; + long i3619; + long i3620; + long i3621; + long i3622; + long i3623; + long i3624; + long i3625; + long i3626; + long i3627; + long i3628; + long i3629; + long i3630; + long i3631; + long i3632; + long i3633; + long i3634; + long i3635; + long i3636; + long i3637; + long i3638; + long i3639; + long i3640; + long i3641; + long i3642; + long i3643; + long i3644; + long i3645; + long i3646; + long i3647; + long i3648; + long i3649; + long i3650; + long i3651; + long i3652; + long i3653; + long i3654; + long i3655; + long i3656; + long i3657; + long i3658; + long i3659; + long i3660; + long i3661; + long i3662; + long i3663; + long i3664; + long i3665; + long i3666; + long i3667; + long i3668; + long i3669; + long i3670; + long i3671; + long i3672; + long i3673; + long i3674; + long i3675; + long i3676; + long i3677; + long i3678; + long i3679; + long i3680; + long i3681; + long i3682; + long i3683; + long i3684; + long i3685; + long i3686; + long i3687; + long i3688; + long i3689; + long i3690; + long i3691; + long i3692; + long i3693; + long i3694; + long i3695; + long i3696; + long i3697; + long i3698; + long i3699; + long i3700; + long i3701; + long i3702; + long i3703; + long i3704; + long i3705; + long i3706; + long i3707; + long i3708; + long i3709; + long i3710; + long i3711; + long i3712; + long i3713; + long i3714; + long i3715; + long i3716; + long i3717; + long i3718; + long i3719; + long i3720; + long i3721; + long i3722; + long i3723; + long i3724; + long i3725; + long i3726; + long i3727; + long i3728; + long i3729; + long i3730; + long i3731; + long i3732; + long i3733; + long i3734; + long i3735; + long i3736; + long i3737; + long i3738; + long i3739; + long i3740; + long i3741; + long i3742; + long i3743; + long i3744; + long i3745; + long i3746; + long i3747; + long i3748; + long i3749; + long i3750; + long i3751; + long i3752; + long i3753; + long i3754; + long i3755; + long i3756; + long i3757; + long i3758; + long i3759; + long i3760; + long i3761; + long i3762; + long i3763; + long i3764; + long i3765; + long i3766; + long i3767; + long i3768; + long i3769; + long i3770; + long i3771; + long i3772; + long i3773; + long i3774; + long i3775; + long i3776; + long i3777; + long i3778; + long i3779; + long i3780; + long i3781; + long i3782; + long i3783; + long i3784; + long i3785; + long i3786; + long i3787; + long i3788; + long i3789; + long i3790; + long i3791; + long i3792; + long i3793; + long i3794; + long i3795; + long i3796; + long i3797; + long i3798; + long i3799; + long i3800; + long i3801; + long i3802; + long i3803; + long i3804; + long i3805; + long i3806; + long i3807; + long i3808; + long i3809; + long i3810; + long i3811; + long i3812; + long i3813; + long i3814; + long i3815; + long i3816; + long i3817; + long i3818; + long i3819; + long i3820; + long i3821; + long i3822; + long i3823; + long i3824; + long i3825; + long i3826; + long i3827; + long i3828; + long i3829; + long i3830; + long i3831; + long i3832; + long i3833; + long i3834; + long i3835; + long i3836; + long i3837; + long i3838; + long i3839; + long i3840; + long i3841; + long i3842; + long i3843; + long i3844; + long i3845; + long i3846; + long i3847; + long i3848; + long i3849; + long i3850; + long i3851; + long i3852; + long i3853; + long i3854; + long i3855; + long i3856; + long i3857; + long i3858; + long i3859; + long i3860; + long i3861; + long i3862; + long i3863; + long i3864; + long i3865; + long i3866; + long i3867; + long i3868; + long i3869; + long i3870; + long i3871; + long i3872; + long i3873; + long i3874; + long i3875; + long i3876; + long i3877; + long i3878; + long i3879; + long i3880; + long i3881; + long i3882; + long i3883; + long i3884; + long i3885; + long i3886; + long i3887; + long i3888; + long i3889; + long i3890; + long i3891; + long i3892; + long i3893; + long i3894; + long i3895; + long i3896; + long i3897; + long i3898; + long i3899; + long i3900; + long i3901; + long i3902; + long i3903; + long i3904; + long i3905; + long i3906; + long i3907; + long i3908; + long i3909; + long i3910; + long i3911; + long i3912; + long i3913; + long i3914; + long i3915; + long i3916; + long i3917; + long i3918; + long i3919; + long i3920; + long i3921; + long i3922; + long i3923; + long i3924; + long i3925; + long i3926; + long i3927; + long i3928; + long i3929; + long i3930; + long i3931; + long i3932; + long i3933; + long i3934; + long i3935; + long i3936; + long i3937; + long i3938; + long i3939; + long i3940; + long i3941; + long i3942; + long i3943; + long i3944; + long i3945; + long i3946; + long i3947; + long i3948; + long i3949; + long i3950; + long i3951; + long i3952; + long i3953; + long i3954; + long i3955; + long i3956; + long i3957; + long i3958; + long i3959; + long i3960; + long i3961; + long i3962; + long i3963; + long i3964; + long i3965; + long i3966; + long i3967; + long i3968; + long i3969; + long i3970; + long i3971; + long i3972; + long i3973; + long i3974; + long i3975; + long i3976; + long i3977; + long i3978; + long i3979; + long i3980; + long i3981; + long i3982; + long i3983; + long i3984; + long i3985; + long i3986; + long i3987; + long i3988; + long i3989; + long i3990; + long i3991; + long i3992; + long i3993; + long i3994; + long i3995; + long i3996; + long i3997; + long i3998; + long i3999; + long i4000; + long i4001; + long i4002; + long i4003; + long i4004; + long i4005; + long i4006; + long i4007; + long i4008; + long i4009; + long i4010; + long i4011; + long i4012; + long i4013; + long i4014; + long i4015; + long i4016; + long i4017; + long i4018; + long i4019; + long i4020; + long i4021; + long i4022; + long i4023; + long i4024; + long i4025; + long i4026; + long i4027; + long i4028; + long i4029; + long i4030; + long i4031; + long i4032; + long i4033; + long i4034; + long i4035; + long i4036; + long i4037; + long i4038; + long i4039; + long i4040; + long i4041; + long i4042; + long i4043; + long i4044; + long i4045; + long i4046; + long i4047; + long i4048; + long i4049; + long i4050; + long i4051; + long i4052; + long i4053; + long i4054; + long i4055; + long i4056; + long i4057; + long i4058; + long i4059; + long i4060; + long i4061; + long i4062; + long i4063; + long i4064; + long i4065; + long i4066; + long i4067; + long i4068; + long i4069; + long i4070; + long i4071; + long i4072; + long i4073; + long i4074; + long i4075; + long i4076; + long i4077; + long i4078; + long i4079; + long i4080; + long i4081; + long i4082; + long i4083; + long i4084; + long i4085; + long i4086; + long i4087; + long i4088; + long i4089; + long i4090; + long i4091; + long i4092; + long i4093; + long i4094; + long i4095; + long i4096; + long i4097; + long i4098; + long i4099; + long i4100; + long i4101; + long i4102; + long i4103; + long i4104; + long i4105; + long i4106; + long i4107; + long i4108; + long i4109; + long i4110; + long i4111; + long i4112; + long i4113; + long i4114; + long i4115; + long i4116; + long i4117; + long i4118; + long i4119; + long i4120; + long i4121; + long i4122; + long i4123; + long i4124; + long i4125; + long i4126; + long i4127; + long i4128; + long i4129; + long i4130; + long i4131; + long i4132; + long i4133; + long i4134; + long i4135; + long i4136; + long i4137; + long i4138; + long i4139; + long i4140; + long i4141; + long i4142; + long i4143; + long i4144; + long i4145; + long i4146; + long i4147; + long i4148; + long i4149; + long i4150; + long i4151; + long i4152; + long i4153; + long i4154; + long i4155; + long i4156; + long i4157; + long i4158; + long i4159; + long i4160; + long i4161; + long i4162; + long i4163; + long i4164; + long i4165; + long i4166; + long i4167; + long i4168; + long i4169; + long i4170; + long i4171; + long i4172; + long i4173; + long i4174; + long i4175; + long i4176; + long i4177; + long i4178; + long i4179; + long i4180; + long i4181; + long i4182; + long i4183; + long i4184; + long i4185; + long i4186; + long i4187; + long i4188; + long i4189; + long i4190; + long i4191; + long i4192; + long i4193; + long i4194; + long i4195; + long i4196; + long i4197; + long i4198; + long i4199; + long i4200; + long i4201; + long i4202; + long i4203; + long i4204; + long i4205; + long i4206; + long i4207; + long i4208; + long i4209; + long i4210; + long i4211; + long i4212; + long i4213; + long i4214; + long i4215; + long i4216; + long i4217; + long i4218; + long i4219; + long i4220; + long i4221; + long i4222; + long i4223; + long i4224; + long i4225; + long i4226; + long i4227; + long i4228; + long i4229; + long i4230; + long i4231; + long i4232; + long i4233; + long i4234; + long i4235; + long i4236; + long i4237; + long i4238; + long i4239; + long i4240; + long i4241; + long i4242; + long i4243; + long i4244; + long i4245; + long i4246; + long i4247; + long i4248; + long i4249; + long i4250; + long i4251; + long i4252; + long i4253; + long i4254; + long i4255; + long i4256; + long i4257; + long i4258; + long i4259; + long i4260; + long i4261; + long i4262; + long i4263; + long i4264; + long i4265; + long i4266; + long i4267; + long i4268; + long i4269; + long i4270; + long i4271; + long i4272; + long i4273; + long i4274; + long i4275; + long i4276; + long i4277; + long i4278; + long i4279; + long i4280; + long i4281; + long i4282; + long i4283; + long i4284; + long i4285; + long i4286; + long i4287; + long i4288; + long i4289; + long i4290; + long i4291; + long i4292; + long i4293; + long i4294; + long i4295; + long i4296; + long i4297; + long i4298; + long i4299; + long i4300; + long i4301; + long i4302; + long i4303; + long i4304; + long i4305; + long i4306; + long i4307; + long i4308; + long i4309; + long i4310; + long i4311; + long i4312; + long i4313; + long i4314; + long i4315; + long i4316; + long i4317; + long i4318; + long i4319; + long i4320; + long i4321; + long i4322; + long i4323; + long i4324; + long i4325; + long i4326; + long i4327; + long i4328; + long i4329; + long i4330; + long i4331; + long i4332; + long i4333; + long i4334; + long i4335; + long i4336; + long i4337; + long i4338; + long i4339; + long i4340; + long i4341; + long i4342; + long i4343; + long i4344; + long i4345; + long i4346; + long i4347; + long i4348; + long i4349; + long i4350; + long i4351; + long i4352; + long i4353; + long i4354; + long i4355; + long i4356; + long i4357; + long i4358; + long i4359; + long i4360; + long i4361; + long i4362; + long i4363; + long i4364; + long i4365; + long i4366; + long i4367; + long i4368; + long i4369; + long i4370; + long i4371; + long i4372; + long i4373; + long i4374; + long i4375; + long i4376; + long i4377; + long i4378; + long i4379; + long i4380; + long i4381; + long i4382; + long i4383; + long i4384; + long i4385; + long i4386; + long i4387; + long i4388; + long i4389; + long i4390; + long i4391; + long i4392; + long i4393; + long i4394; + long i4395; + long i4396; + long i4397; + long i4398; + long i4399; + long i4400; + long i4401; + long i4402; + long i4403; + long i4404; + long i4405; + long i4406; + long i4407; + long i4408; + long i4409; + long i4410; + long i4411; + long i4412; + long i4413; + long i4414; + long i4415; + long i4416; + long i4417; + long i4418; + long i4419; + long i4420; + long i4421; + long i4422; + long i4423; + long i4424; + long i4425; + long i4426; + long i4427; + long i4428; + long i4429; + long i4430; + long i4431; + long i4432; + long i4433; + long i4434; + long i4435; + long i4436; + long i4437; + long i4438; + long i4439; + long i4440; + long i4441; + long i4442; + long i4443; + long i4444; + long i4445; + long i4446; + long i4447; + long i4448; + long i4449; + long i4450; + long i4451; + long i4452; + long i4453; + long i4454; + long i4455; + long i4456; + long i4457; + long i4458; + long i4459; + long i4460; + long i4461; + long i4462; + long i4463; + long i4464; + long i4465; + long i4466; + long i4467; + long i4468; + long i4469; + long i4470; + long i4471; + long i4472; + long i4473; + long i4474; + long i4475; + long i4476; + long i4477; + long i4478; + long i4479; + long i4480; + long i4481; + long i4482; + long i4483; + long i4484; + long i4485; + long i4486; + long i4487; + long i4488; + long i4489; + long i4490; + long i4491; + long i4492; + long i4493; + long i4494; + long i4495; + long i4496; + long i4497; + long i4498; + long i4499; + long i4500; + long i4501; + long i4502; + long i4503; + long i4504; + long i4505; + long i4506; + long i4507; + long i4508; + long i4509; + long i4510; + long i4511; + long i4512; + long i4513; + long i4514; + long i4515; + long i4516; + long i4517; + long i4518; + long i4519; + long i4520; + long i4521; + long i4522; + long i4523; + long i4524; + long i4525; + long i4526; + long i4527; + long i4528; + long i4529; + long i4530; + long i4531; + long i4532; + long i4533; + long i4534; + long i4535; + long i4536; + long i4537; + long i4538; + long i4539; + long i4540; + long i4541; + long i4542; + long i4543; + long i4544; + long i4545; + long i4546; + long i4547; + long i4548; + long i4549; + long i4550; + long i4551; + long i4552; + long i4553; + long i4554; + long i4555; + long i4556; + long i4557; + long i4558; + long i4559; + long i4560; + long i4561; + long i4562; + long i4563; + long i4564; + long i4565; + long i4566; + long i4567; + long i4568; + long i4569; + long i4570; + long i4571; + long i4572; + long i4573; + long i4574; + long i4575; + long i4576; + long i4577; + long i4578; + long i4579; + long i4580; + long i4581; + long i4582; + long i4583; + long i4584; + long i4585; + long i4586; + long i4587; + long i4588; + long i4589; + long i4590; + long i4591; + long i4592; + long i4593; + long i4594; + long i4595; + long i4596; + long i4597; + long i4598; + long i4599; + long i4600; + long i4601; + long i4602; + long i4603; + long i4604; + long i4605; + long i4606; + long i4607; + long i4608; + long i4609; + long i4610; + long i4611; + long i4612; + long i4613; + long i4614; + long i4615; + long i4616; + long i4617; + long i4618; + long i4619; + long i4620; + long i4621; + long i4622; + long i4623; + long i4624; + long i4625; + long i4626; + long i4627; + long i4628; + long i4629; + long i4630; + long i4631; + long i4632; + long i4633; + long i4634; + long i4635; + long i4636; + long i4637; + long i4638; + long i4639; + long i4640; + long i4641; + long i4642; + long i4643; + long i4644; + long i4645; + long i4646; + long i4647; + long i4648; + long i4649; + long i4650; + long i4651; + long i4652; + long i4653; + long i4654; + long i4655; + long i4656; + long i4657; + long i4658; + long i4659; + long i4660; + long i4661; + long i4662; + long i4663; + long i4664; + long i4665; + long i4666; + long i4667; + long i4668; + long i4669; + long i4670; + long i4671; + long i4672; + long i4673; + long i4674; + long i4675; + long i4676; + long i4677; + long i4678; + long i4679; + long i4680; + long i4681; + long i4682; + long i4683; + long i4684; + long i4685; + long i4686; + long i4687; + long i4688; + long i4689; + long i4690; + long i4691; + long i4692; + long i4693; + long i4694; + long i4695; + long i4696; + long i4697; + long i4698; + long i4699; + long i4700; + long i4701; + long i4702; + long i4703; + long i4704; + long i4705; + long i4706; + long i4707; + long i4708; + long i4709; + long i4710; + long i4711; + long i4712; + long i4713; + long i4714; + long i4715; + long i4716; + long i4717; + long i4718; + long i4719; + long i4720; + long i4721; + long i4722; + long i4723; + long i4724; + long i4725; + long i4726; + long i4727; + long i4728; + long i4729; + long i4730; + long i4731; + long i4732; + long i4733; + long i4734; + long i4735; + long i4736; + long i4737; + long i4738; + long i4739; + long i4740; + long i4741; + long i4742; + long i4743; + long i4744; + long i4745; + long i4746; + long i4747; + long i4748; + long i4749; + long i4750; + long i4751; + long i4752; + long i4753; + long i4754; + long i4755; + long i4756; + long i4757; + long i4758; + long i4759; + long i4760; + long i4761; + long i4762; + long i4763; + long i4764; + long i4765; + long i4766; + long i4767; + long i4768; + long i4769; + long i4770; + long i4771; + long i4772; + long i4773; + long i4774; + long i4775; + long i4776; + long i4777; + long i4778; + long i4779; + long i4780; + long i4781; + long i4782; + long i4783; + long i4784; + long i4785; + long i4786; + long i4787; + long i4788; + long i4789; + long i4790; + long i4791; + long i4792; + long i4793; + long i4794; + long i4795; + long i4796; + long i4797; + long i4798; + long i4799; + long i4800; + long i4801; + long i4802; + long i4803; + long i4804; + long i4805; + long i4806; + long i4807; + long i4808; + long i4809; + long i4810; + long i4811; + long i4812; + long i4813; + long i4814; + long i4815; + long i4816; + long i4817; + long i4818; + long i4819; + long i4820; + long i4821; + long i4822; + long i4823; + long i4824; + long i4825; + long i4826; + long i4827; + long i4828; + long i4829; + long i4830; + long i4831; + long i4832; + long i4833; + long i4834; + long i4835; + long i4836; + long i4837; + long i4838; + long i4839; + long i4840; + long i4841; + long i4842; + long i4843; + long i4844; + long i4845; + long i4846; + long i4847; + long i4848; + long i4849; + long i4850; + long i4851; + long i4852; + long i4853; + long i4854; + long i4855; + long i4856; + long i4857; + long i4858; + long i4859; + long i4860; + long i4861; + long i4862; + long i4863; + long i4864; + long i4865; + long i4866; + long i4867; + long i4868; + long i4869; + long i4870; + long i4871; + long i4872; + long i4873; + long i4874; + long i4875; + long i4876; + long i4877; + long i4878; + long i4879; + long i4880; + long i4881; + long i4882; + long i4883; + long i4884; + long i4885; + long i4886; + long i4887; + long i4888; + long i4889; + long i4890; + long i4891; + long i4892; + long i4893; + long i4894; + long i4895; + long i4896; + long i4897; + long i4898; + long i4899; + long i4900; + long i4901; + long i4902; + long i4903; + long i4904; + long i4905; + long i4906; + long i4907; + long i4908; + long i4909; + long i4910; + long i4911; + long i4912; + long i4913; + long i4914; + long i4915; + long i4916; + long i4917; + long i4918; + long i4919; + long i4920; + long i4921; + long i4922; + long i4923; + long i4924; + long i4925; + long i4926; + long i4927; + long i4928; + long i4929; + long i4930; + long i4931; + long i4932; + long i4933; + long i4934; + long i4935; + long i4936; + long i4937; + long i4938; + long i4939; + long i4940; + long i4941; + long i4942; + long i4943; + long i4944; + long i4945; + long i4946; + long i4947; + long i4948; + long i4949; + long i4950; + long i4951; + long i4952; + long i4953; + long i4954; + long i4955; + long i4956; + long i4957; + long i4958; + long i4959; + long i4960; + long i4961; + long i4962; + long i4963; + long i4964; + long i4965; + long i4966; + long i4967; + long i4968; + long i4969; + long i4970; + long i4971; + long i4972; + long i4973; + long i4974; + long i4975; + long i4976; + long i4977; + long i4978; + long i4979; + long i4980; + long i4981; + long i4982; + long i4983; + long i4984; + long i4985; + long i4986; + long i4987; + long i4988; + long i4989; + long i4990; + long i4991; + long i4992; + long i4993; + long i4994; + long i4995; + long i4996; + long i4997; + long i4998; + long i4999; + long i5000; + long i5001; + long i5002; + long i5003; + long i5004; + long i5005; + long i5006; + long i5007; + long i5008; + long i5009; + long i5010; + long i5011; + long i5012; + long i5013; + long i5014; + long i5015; + long i5016; + long i5017; + long i5018; + long i5019; + long i5020; + long i5021; + long i5022; + long i5023; + long i5024; + long i5025; + long i5026; + long i5027; + long i5028; + long i5029; + long i5030; + long i5031; + long i5032; + long i5033; + long i5034; + long i5035; + long i5036; + long i5037; + long i5038; + long i5039; + long i5040; + long i5041; + long i5042; + long i5043; + long i5044; + long i5045; + long i5046; + long i5047; + long i5048; + long i5049; + long i5050; + long i5051; + long i5052; + long i5053; + long i5054; + long i5055; + long i5056; + long i5057; + long i5058; + long i5059; + long i5060; + long i5061; + long i5062; + long i5063; + long i5064; + long i5065; + long i5066; + long i5067; + long i5068; + long i5069; + long i5070; + long i5071; + long i5072; + long i5073; + long i5074; + long i5075; + long i5076; + long i5077; + long i5078; + long i5079; + long i5080; + long i5081; + long i5082; + long i5083; + long i5084; + long i5085; + long i5086; + long i5087; + long i5088; + long i5089; + long i5090; + long i5091; + long i5092; + long i5093; + long i5094; + long i5095; + long i5096; + long i5097; + long i5098; + long i5099; + long i5100; + long i5101; + long i5102; + long i5103; + long i5104; + long i5105; + long i5106; + long i5107; + long i5108; + long i5109; + long i5110; + long i5111; + long i5112; + long i5113; + long i5114; + long i5115; + long i5116; + long i5117; + long i5118; + long i5119; + long i5120; + long i5121; + long i5122; + long i5123; + long i5124; + long i5125; + long i5126; + long i5127; + long i5128; + long i5129; + long i5130; + long i5131; + long i5132; + long i5133; + long i5134; + long i5135; + long i5136; + long i5137; + long i5138; + long i5139; + long i5140; + long i5141; + long i5142; + long i5143; + long i5144; + long i5145; + long i5146; + long i5147; + long i5148; + long i5149; + long i5150; + long i5151; + long i5152; + long i5153; + long i5154; + long i5155; + long i5156; + long i5157; + long i5158; + long i5159; + long i5160; + long i5161; + long i5162; + long i5163; + long i5164; + long i5165; + long i5166; + long i5167; + long i5168; + long i5169; + long i5170; + long i5171; + long i5172; + long i5173; + long i5174; + long i5175; + long i5176; + long i5177; + long i5178; + long i5179; + long i5180; + long i5181; + long i5182; + long i5183; + long i5184; + long i5185; + long i5186; + long i5187; + long i5188; + long i5189; + long i5190; + long i5191; + long i5192; + long i5193; + long i5194; + long i5195; + long i5196; + long i5197; + long i5198; + long i5199; + long i5200; + long i5201; + long i5202; + long i5203; + long i5204; + long i5205; + long i5206; + long i5207; + long i5208; + long i5209; + long i5210; + long i5211; + long i5212; + long i5213; + long i5214; + long i5215; + long i5216; + long i5217; + long i5218; + long i5219; + long i5220; + long i5221; + long i5222; + long i5223; + long i5224; + long i5225; + long i5226; + long i5227; + long i5228; + long i5229; + long i5230; + long i5231; + long i5232; + long i5233; + long i5234; + long i5235; + long i5236; + long i5237; + long i5238; + long i5239; + long i5240; + long i5241; + long i5242; + long i5243; + long i5244; + long i5245; + long i5246; + long i5247; + long i5248; + long i5249; + long i5250; + long i5251; + long i5252; + long i5253; + long i5254; + long i5255; + long i5256; + long i5257; + long i5258; + long i5259; + long i5260; + long i5261; + long i5262; + long i5263; + long i5264; + long i5265; + long i5266; + long i5267; + long i5268; + long i5269; + long i5270; + long i5271; + long i5272; + long i5273; + long i5274; + long i5275; + long i5276; + long i5277; + long i5278; + long i5279; + long i5280; + long i5281; + long i5282; + long i5283; + long i5284; + long i5285; + long i5286; + long i5287; + long i5288; + long i5289; + long i5290; + long i5291; + long i5292; + long i5293; + long i5294; + long i5295; + long i5296; + long i5297; + long i5298; + long i5299; + long i5300; + long i5301; + long i5302; + long i5303; + long i5304; + long i5305; + long i5306; + long i5307; + long i5308; + long i5309; + long i5310; + long i5311; + long i5312; + long i5313; + long i5314; + long i5315; + long i5316; + long i5317; + long i5318; + long i5319; + long i5320; + long i5321; + long i5322; + long i5323; + long i5324; + long i5325; + long i5326; + long i5327; + long i5328; + long i5329; + long i5330; + long i5331; + long i5332; + long i5333; + long i5334; + long i5335; + long i5336; + long i5337; + long i5338; + long i5339; + long i5340; + long i5341; + long i5342; + long i5343; + long i5344; + long i5345; + long i5346; + long i5347; + long i5348; + long i5349; + long i5350; + long i5351; + long i5352; + long i5353; + long i5354; + long i5355; + long i5356; + long i5357; + long i5358; + long i5359; + long i5360; + long i5361; + long i5362; + long i5363; + long i5364; + long i5365; + long i5366; + long i5367; + long i5368; + long i5369; + long i5370; + long i5371; + long i5372; + long i5373; + long i5374; + long i5375; + long i5376; + long i5377; + long i5378; + long i5379; + long i5380; + long i5381; + long i5382; + long i5383; + long i5384; + long i5385; + long i5386; + long i5387; + long i5388; + long i5389; + long i5390; + long i5391; + long i5392; + long i5393; + long i5394; + long i5395; + long i5396; + long i5397; + long i5398; + long i5399; + long i5400; + long i5401; + long i5402; + long i5403; + long i5404; + long i5405; + long i5406; + long i5407; + long i5408; + long i5409; + long i5410; + long i5411; + long i5412; + long i5413; + long i5414; + long i5415; + long i5416; + long i5417; + long i5418; + long i5419; + long i5420; + long i5421; + long i5422; + long i5423; + long i5424; + long i5425; + long i5426; + long i5427; + long i5428; + long i5429; + long i5430; + long i5431; + long i5432; + long i5433; + long i5434; + long i5435; + long i5436; + long i5437; + long i5438; + long i5439; + long i5440; + long i5441; + long i5442; + long i5443; + long i5444; + long i5445; + long i5446; + long i5447; + long i5448; + long i5449; + long i5450; + long i5451; + long i5452; + long i5453; + long i5454; + long i5455; + long i5456; + long i5457; + long i5458; + long i5459; + long i5460; + long i5461; + long i5462; + long i5463; + long i5464; + long i5465; + long i5466; + long i5467; + long i5468; + long i5469; + long i5470; + long i5471; + long i5472; + long i5473; + long i5474; + long i5475; + long i5476; + long i5477; + long i5478; + long i5479; + long i5480; + long i5481; + long i5482; + long i5483; + long i5484; + long i5485; + long i5486; + long i5487; + long i5488; + long i5489; + long i5490; + long i5491; + long i5492; + long i5493; + long i5494; + long i5495; + long i5496; + long i5497; + long i5498; + long i5499; + long i5500; + long i5501; + long i5502; + long i5503; + long i5504; + long i5505; + long i5506; + long i5507; + long i5508; + long i5509; + long i5510; + long i5511; + long i5512; + long i5513; + long i5514; + long i5515; + long i5516; + long i5517; + long i5518; + long i5519; + long i5520; + long i5521; + long i5522; + long i5523; + long i5524; + long i5525; + long i5526; + long i5527; + long i5528; + long i5529; + long i5530; + long i5531; + long i5532; + long i5533; + long i5534; + long i5535; + long i5536; + long i5537; + long i5538; + long i5539; + long i5540; + long i5541; + long i5542; + long i5543; + long i5544; + long i5545; + long i5546; + long i5547; + long i5548; + long i5549; + long i5550; + long i5551; + long i5552; + long i5553; + long i5554; + long i5555; + long i5556; + long i5557; + long i5558; + long i5559; + long i5560; + long i5561; + long i5562; + long i5563; + long i5564; + long i5565; + long i5566; + long i5567; + long i5568; + long i5569; + long i5570; + long i5571; + long i5572; + long i5573; + long i5574; + long i5575; + long i5576; + long i5577; + long i5578; + long i5579; + long i5580; + long i5581; + long i5582; + long i5583; + long i5584; + long i5585; + long i5586; + long i5587; + long i5588; + long i5589; + long i5590; + long i5591; + long i5592; + long i5593; + long i5594; + long i5595; + long i5596; + long i5597; + long i5598; + long i5599; + long i5600; + long i5601; + long i5602; + long i5603; + long i5604; + long i5605; + long i5606; + long i5607; + long i5608; + long i5609; + long i5610; + long i5611; + long i5612; + long i5613; + long i5614; + long i5615; + long i5616; + long i5617; + long i5618; + long i5619; + long i5620; + long i5621; + long i5622; + long i5623; + long i5624; + long i5625; + long i5626; + long i5627; + long i5628; + long i5629; + long i5630; + long i5631; + long i5632; + long i5633; + long i5634; + long i5635; + long i5636; + long i5637; + long i5638; + long i5639; + long i5640; + long i5641; + long i5642; + long i5643; + long i5644; + long i5645; + long i5646; + long i5647; + long i5648; + long i5649; + long i5650; + long i5651; + long i5652; + long i5653; + long i5654; + long i5655; + long i5656; + long i5657; + long i5658; + long i5659; + long i5660; + long i5661; + long i5662; + long i5663; + long i5664; + long i5665; + long i5666; + long i5667; + long i5668; + long i5669; + long i5670; + long i5671; + long i5672; + long i5673; + long i5674; + long i5675; + long i5676; + long i5677; + long i5678; + long i5679; + long i5680; + long i5681; + long i5682; + long i5683; + long i5684; + long i5685; + long i5686; + long i5687; + long i5688; + long i5689; + long i5690; + long i5691; + long i5692; + long i5693; + long i5694; + long i5695; + long i5696; + long i5697; + long i5698; + long i5699; + long i5700; + long i5701; + long i5702; + long i5703; + long i5704; + long i5705; + long i5706; + long i5707; + long i5708; + long i5709; + long i5710; + long i5711; + long i5712; + long i5713; + long i5714; + long i5715; + long i5716; + long i5717; + long i5718; + long i5719; + long i5720; + long i5721; + long i5722; + long i5723; + long i5724; + long i5725; + long i5726; + long i5727; + long i5728; + long i5729; + long i5730; + long i5731; + long i5732; + long i5733; + long i5734; + long i5735; + long i5736; + long i5737; + long i5738; + long i5739; + long i5740; + long i5741; + long i5742; + long i5743; + long i5744; + long i5745; + long i5746; + long i5747; + long i5748; + long i5749; + long i5750; + long i5751; + long i5752; + long i5753; + long i5754; + long i5755; + long i5756; + long i5757; + long i5758; + long i5759; + long i5760; + long i5761; + long i5762; + long i5763; + long i5764; + long i5765; + long i5766; + long i5767; + long i5768; + long i5769; + long i5770; + long i5771; + long i5772; + long i5773; + long i5774; + long i5775; + long i5776; + long i5777; + long i5778; + long i5779; + long i5780; + long i5781; + long i5782; + long i5783; + long i5784; + long i5785; + long i5786; + long i5787; + long i5788; + long i5789; + long i5790; + long i5791; + long i5792; + long i5793; + long i5794; + long i5795; + long i5796; + long i5797; + long i5798; + long i5799; + long i5800; + long i5801; + long i5802; + long i5803; + long i5804; + long i5805; + long i5806; + long i5807; + long i5808; + long i5809; + long i5810; + long i5811; + long i5812; + long i5813; + long i5814; + long i5815; + long i5816; + long i5817; + long i5818; + long i5819; + long i5820; + long i5821; + long i5822; + long i5823; + long i5824; + long i5825; + long i5826; + long i5827; + long i5828; + long i5829; + long i5830; + long i5831; + long i5832; + long i5833; + long i5834; + long i5835; + long i5836; + long i5837; + long i5838; + long i5839; + long i5840; + long i5841; + long i5842; + long i5843; + long i5844; + long i5845; + long i5846; + long i5847; + long i5848; + long i5849; + long i5850; + long i5851; + long i5852; + long i5853; + long i5854; + long i5855; + long i5856; + long i5857; + long i5858; + long i5859; + long i5860; + long i5861; + long i5862; + long i5863; + long i5864; + long i5865; + long i5866; + long i5867; + long i5868; + long i5869; + long i5870; + long i5871; + long i5872; + long i5873; + long i5874; + long i5875; + long i5876; + long i5877; + long i5878; + long i5879; + long i5880; + long i5881; + long i5882; + long i5883; + long i5884; + long i5885; + long i5886; + long i5887; + long i5888; + long i5889; + long i5890; + long i5891; + long i5892; + long i5893; + long i5894; + long i5895; + long i5896; + long i5897; + long i5898; + long i5899; + long i5900; + long i5901; + long i5902; + long i5903; + long i5904; + long i5905; + long i5906; + long i5907; + long i5908; + long i5909; + long i5910; + long i5911; + long i5912; + long i5913; + long i5914; + long i5915; + long i5916; + long i5917; + long i5918; + long i5919; + long i5920; + long i5921; + long i5922; + long i5923; + long i5924; + long i5925; + long i5926; + long i5927; + long i5928; + long i5929; + long i5930; + long i5931; + long i5932; + long i5933; + long i5934; + long i5935; + long i5936; + long i5937; + long i5938; + long i5939; + long i5940; + long i5941; + long i5942; + long i5943; + long i5944; + long i5945; + long i5946; + long i5947; + long i5948; + long i5949; + long i5950; + long i5951; + long i5952; + long i5953; + long i5954; + long i5955; + long i5956; + long i5957; + long i5958; + long i5959; + long i5960; + long i5961; + long i5962; + long i5963; + long i5964; + long i5965; + long i5966; + long i5967; + long i5968; + long i5969; + long i5970; + long i5971; + long i5972; + long i5973; + long i5974; + long i5975; + long i5976; + long i5977; + long i5978; + long i5979; + long i5980; + long i5981; + long i5982; + long i5983; + long i5984; + long i5985; + long i5986; + long i5987; + long i5988; + long i5989; + long i5990; + long i5991; + long i5992; + long i5993; + long i5994; + long i5995; + long i5996; + long i5997; + long i5998; + long i5999; + long i6000; + long i6001; + long i6002; + long i6003; + long i6004; + long i6005; + long i6006; + long i6007; + long i6008; + long i6009; + long i6010; + long i6011; + long i6012; + long i6013; + long i6014; + long i6015; + long i6016; + long i6017; + long i6018; + long i6019; + long i6020; + long i6021; + long i6022; + long i6023; + long i6024; + long i6025; + long i6026; + long i6027; + long i6028; + long i6029; + long i6030; + long i6031; + long i6032; + long i6033; + long i6034; + long i6035; + long i6036; + long i6037; + long i6038; + long i6039; + long i6040; + long i6041; + long i6042; + long i6043; + long i6044; + long i6045; + long i6046; + long i6047; + long i6048; + long i6049; + long i6050; + long i6051; + long i6052; + long i6053; + long i6054; + long i6055; + long i6056; + long i6057; + long i6058; + long i6059; + long i6060; + long i6061; + long i6062; + long i6063; + long i6064; + long i6065; + long i6066; + long i6067; + long i6068; + long i6069; + long i6070; + long i6071; + long i6072; + long i6073; + long i6074; + long i6075; + long i6076; + long i6077; + long i6078; + long i6079; + long i6080; + long i6081; + long i6082; + long i6083; + long i6084; + long i6085; + long i6086; + long i6087; + long i6088; + long i6089; + long i6090; + long i6091; + long i6092; + long i6093; + long i6094; + long i6095; + long i6096; + long i6097; + long i6098; + long i6099; + long i6100; + long i6101; + long i6102; + long i6103; + long i6104; + long i6105; + long i6106; + long i6107; + long i6108; + long i6109; + long i6110; + long i6111; + long i6112; + long i6113; + long i6114; + long i6115; + long i6116; + long i6117; + long i6118; + long i6119; + long i6120; + long i6121; + long i6122; + long i6123; + long i6124; + long i6125; + long i6126; + long i6127; + long i6128; + long i6129; + long i6130; + long i6131; + long i6132; + long i6133; + long i6134; + long i6135; + long i6136; + long i6137; + long i6138; + long i6139; + long i6140; + long i6141; + long i6142; + long i6143; + long i6144; + long i6145; + long i6146; + long i6147; + long i6148; + long i6149; + long i6150; + long i6151; + long i6152; + long i6153; + long i6154; + long i6155; + long i6156; + long i6157; + long i6158; + long i6159; + long i6160; + long i6161; + long i6162; + long i6163; + long i6164; + long i6165; + long i6166; + long i6167; + long i6168; + long i6169; + long i6170; + long i6171; + long i6172; + long i6173; + long i6174; + long i6175; + long i6176; + long i6177; + long i6178; + long i6179; + long i6180; + long i6181; + long i6182; + long i6183; + long i6184; + long i6185; + long i6186; + long i6187; + long i6188; + long i6189; + long i6190; + long i6191; + long i6192; + long i6193; + long i6194; + long i6195; + long i6196; + long i6197; + long i6198; + long i6199; + long i6200; + long i6201; + long i6202; + long i6203; + long i6204; + long i6205; + long i6206; + long i6207; + long i6208; + long i6209; + long i6210; + long i6211; + long i6212; + long i6213; + long i6214; + long i6215; + long i6216; + long i6217; + long i6218; + long i6219; + long i6220; + long i6221; + long i6222; + long i6223; + long i6224; + long i6225; + long i6226; + long i6227; + long i6228; + long i6229; + long i6230; + long i6231; + long i6232; + long i6233; + long i6234; + long i6235; + long i6236; + long i6237; + long i6238; + long i6239; + long i6240; + long i6241; + long i6242; + long i6243; + long i6244; + long i6245; + long i6246; + long i6247; + long i6248; + long i6249; + long i6250; + long i6251; + long i6252; + long i6253; + long i6254; + long i6255; + long i6256; + long i6257; + long i6258; + long i6259; + long i6260; + long i6261; + long i6262; + long i6263; + long i6264; + long i6265; + long i6266; + long i6267; + long i6268; + long i6269; + long i6270; + long i6271; + long i6272; + long i6273; + long i6274; + long i6275; + long i6276; + long i6277; + long i6278; + long i6279; + long i6280; + long i6281; + long i6282; + long i6283; + long i6284; + long i6285; + long i6286; + long i6287; + long i6288; + long i6289; + long i6290; + long i6291; + long i6292; + long i6293; + long i6294; + long i6295; + long i6296; + long i6297; + long i6298; + long i6299; + long i6300; + long i6301; + long i6302; + long i6303; + long i6304; + long i6305; + long i6306; + long i6307; + long i6308; + long i6309; + long i6310; + long i6311; + long i6312; + long i6313; + long i6314; + long i6315; + long i6316; + long i6317; + long i6318; + long i6319; + long i6320; + long i6321; + long i6322; + long i6323; + long i6324; + long i6325; + long i6326; + long i6327; + long i6328; + long i6329; + long i6330; + long i6331; + long i6332; + long i6333; + long i6334; + long i6335; + long i6336; + long i6337; + long i6338; + long i6339; + long i6340; + long i6341; + long i6342; + long i6343; + long i6344; + long i6345; + long i6346; + long i6347; + long i6348; + long i6349; + long i6350; + long i6351; + long i6352; + long i6353; + long i6354; + long i6355; + long i6356; + long i6357; + long i6358; + long i6359; + long i6360; + long i6361; + long i6362; + long i6363; + long i6364; + long i6365; + long i6366; + long i6367; + long i6368; + long i6369; + long i6370; + long i6371; + long i6372; + long i6373; + long i6374; + long i6375; + long i6376; + long i6377; + long i6378; + long i6379; + long i6380; + long i6381; + long i6382; + long i6383; + long i6384; + long i6385; + long i6386; + long i6387; + long i6388; + long i6389; + long i6390; + long i6391; + long i6392; + long i6393; + long i6394; + long i6395; + long i6396; + long i6397; + long i6398; + long i6399; + long i6400; + long i6401; + long i6402; + long i6403; + long i6404; + long i6405; + long i6406; + long i6407; + long i6408; + long i6409; + long i6410; + long i6411; + long i6412; + long i6413; + long i6414; + long i6415; + long i6416; + long i6417; + long i6418; + long i6419; + long i6420; + long i6421; + long i6422; + long i6423; + long i6424; + long i6425; + long i6426; + long i6427; + long i6428; + long i6429; + long i6430; + long i6431; + long i6432; + long i6433; + long i6434; + long i6435; + long i6436; + long i6437; + long i6438; + long i6439; + long i6440; + long i6441; + long i6442; + long i6443; + long i6444; + long i6445; + long i6446; + long i6447; + long i6448; + long i6449; + long i6450; + long i6451; + long i6452; + long i6453; + long i6454; + long i6455; + long i6456; + long i6457; + long i6458; + long i6459; + long i6460; + long i6461; + long i6462; + long i6463; + long i6464; + long i6465; + long i6466; + long i6467; + long i6468; + long i6469; + long i6470; + long i6471; + long i6472; + long i6473; + long i6474; + long i6475; + long i6476; + long i6477; + long i6478; + long i6479; + long i6480; + long i6481; + long i6482; + long i6483; + long i6484; + long i6485; + long i6486; + long i6487; + long i6488; + long i6489; + long i6490; + long i6491; + long i6492; + long i6493; + long i6494; + long i6495; + long i6496; + long i6497; + long i6498; + long i6499; + long i6500; + long i6501; + long i6502; + long i6503; + long i6504; + long i6505; + long i6506; + long i6507; + long i6508; + long i6509; + long i6510; + long i6511; + long i6512; + long i6513; + long i6514; + long i6515; + long i6516; + long i6517; + long i6518; + long i6519; + long i6520; + long i6521; + long i6522; + long i6523; + long i6524; + long i6525; + long i6526; + long i6527; + long i6528; + long i6529; + long i6530; + long i6531; + long i6532; + long i6533; + long i6534; + long i6535; + long i6536; + long i6537; + long i6538; + long i6539; + long i6540; + long i6541; + long i6542; + long i6543; + long i6544; + long i6545; + long i6546; + long i6547; + long i6548; + long i6549; + long i6550; + long i6551; + long i6552; + long i6553; + long i6554; + long i6555; + long i6556; + long i6557; + long i6558; + long i6559; + long i6560; + long i6561; + long i6562; + long i6563; + long i6564; + long i6565; + long i6566; + long i6567; + long i6568; + long i6569; + long i6570; + long i6571; + long i6572; + long i6573; + long i6574; + long i6575; + long i6576; + long i6577; + long i6578; + long i6579; + long i6580; + long i6581; + long i6582; + long i6583; + long i6584; + long i6585; + long i6586; + long i6587; + long i6588; + long i6589; + long i6590; + long i6591; + long i6592; + long i6593; + long i6594; + long i6595; + long i6596; + long i6597; + long i6598; + long i6599; + long i6600; + long i6601; + long i6602; + long i6603; + long i6604; + long i6605; + long i6606; + long i6607; + long i6608; + long i6609; + long i6610; + long i6611; + long i6612; + long i6613; + long i6614; + long i6615; + long i6616; + long i6617; + long i6618; + long i6619; + long i6620; + long i6621; + long i6622; + long i6623; + long i6624; + long i6625; + long i6626; + long i6627; + long i6628; + long i6629; + long i6630; + long i6631; + long i6632; + long i6633; + long i6634; + long i6635; + long i6636; + long i6637; + long i6638; + long i6639; + long i6640; + long i6641; + long i6642; + long i6643; + long i6644; + long i6645; + long i6646; + long i6647; + long i6648; + long i6649; + long i6650; + long i6651; + long i6652; + long i6653; + long i6654; + long i6655; + long i6656; + long i6657; + long i6658; + long i6659; + long i6660; + long i6661; + long i6662; + long i6663; + long i6664; + long i6665; + long i6666; + long i6667; + long i6668; + long i6669; + long i6670; + long i6671; + long i6672; + long i6673; + long i6674; + long i6675; + long i6676; + long i6677; + long i6678; + long i6679; + long i6680; + long i6681; + long i6682; + long i6683; + long i6684; + long i6685; + long i6686; + long i6687; + long i6688; + long i6689; + long i6690; + long i6691; + long i6692; + long i6693; + long i6694; + long i6695; + long i6696; + long i6697; + long i6698; + long i6699; + long i6700; + long i6701; + long i6702; + long i6703; + long i6704; + long i6705; + long i6706; + long i6707; + long i6708; + long i6709; + long i6710; + long i6711; + long i6712; + long i6713; + long i6714; + long i6715; + long i6716; + long i6717; + long i6718; + long i6719; + long i6720; + long i6721; + long i6722; + long i6723; + long i6724; + long i6725; + long i6726; + long i6727; + long i6728; + long i6729; + long i6730; + long i6731; + long i6732; + long i6733; + long i6734; + long i6735; + long i6736; + long i6737; + long i6738; + long i6739; + long i6740; + long i6741; + long i6742; + long i6743; + long i6744; + long i6745; + long i6746; + long i6747; + long i6748; + long i6749; + long i6750; + long i6751; + long i6752; + long i6753; + long i6754; + long i6755; + long i6756; + long i6757; + long i6758; + long i6759; + long i6760; + long i6761; + long i6762; + long i6763; + long i6764; + long i6765; + long i6766; + long i6767; + long i6768; + long i6769; + long i6770; + long i6771; + long i6772; + long i6773; + long i6774; + long i6775; + long i6776; + long i6777; + long i6778; + long i6779; + long i6780; + long i6781; + long i6782; + long i6783; + long i6784; + long i6785; + long i6786; + long i6787; + long i6788; + long i6789; + long i6790; + long i6791; + long i6792; + long i6793; + long i6794; + long i6795; + long i6796; + long i6797; + long i6798; + long i6799; + long i6800; + long i6801; + long i6802; + long i6803; + long i6804; + long i6805; + long i6806; + long i6807; + long i6808; + long i6809; + long i6810; + long i6811; + long i6812; + long i6813; + long i6814; + long i6815; + long i6816; + long i6817; + long i6818; + long i6819; + long i6820; + long i6821; + long i6822; + long i6823; + long i6824; + long i6825; + long i6826; + long i6827; + long i6828; + long i6829; + long i6830; + long i6831; + long i6832; + long i6833; + long i6834; + long i6835; + long i6836; + long i6837; + long i6838; + long i6839; + long i6840; + long i6841; + long i6842; + long i6843; + long i6844; + long i6845; + long i6846; + long i6847; + long i6848; + long i6849; + long i6850; + long i6851; + long i6852; + long i6853; + long i6854; + long i6855; + long i6856; + long i6857; + long i6858; + long i6859; + long i6860; + long i6861; + long i6862; + long i6863; + long i6864; + long i6865; + long i6866; + long i6867; + long i6868; + long i6869; + long i6870; + long i6871; + long i6872; + long i6873; + long i6874; + long i6875; + long i6876; + long i6877; + long i6878; + long i6879; + long i6880; + long i6881; + long i6882; + long i6883; + long i6884; + long i6885; + long i6886; + long i6887; + long i6888; + long i6889; + long i6890; + long i6891; + long i6892; + long i6893; + long i6894; + long i6895; + long i6896; + long i6897; + long i6898; + long i6899; + long i6900; + long i6901; + long i6902; + long i6903; + long i6904; + long i6905; + long i6906; + long i6907; + long i6908; + long i6909; + long i6910; + long i6911; + long i6912; + long i6913; + long i6914; + long i6915; + long i6916; + long i6917; + long i6918; + long i6919; + long i6920; + long i6921; + long i6922; + long i6923; + long i6924; + long i6925; + long i6926; + long i6927; + long i6928; + long i6929; + long i6930; + long i6931; + long i6932; + long i6933; + long i6934; + long i6935; + long i6936; + long i6937; + long i6938; + long i6939; + long i6940; + long i6941; + long i6942; + long i6943; + long i6944; + long i6945; + long i6946; + long i6947; + long i6948; + long i6949; + long i6950; + long i6951; + long i6952; + long i6953; + long i6954; + long i6955; + long i6956; + long i6957; + long i6958; + long i6959; + long i6960; + long i6961; + long i6962; + long i6963; + long i6964; + long i6965; + long i6966; + long i6967; + long i6968; + long i6969; + long i6970; + long i6971; + long i6972; + long i6973; + long i6974; + long i6975; + long i6976; + long i6977; + long i6978; + long i6979; + long i6980; + long i6981; + long i6982; + long i6983; + long i6984; + long i6985; + long i6986; + long i6987; + long i6988; + long i6989; + long i6990; + long i6991; + long i6992; + long i6993; + long i6994; + long i6995; + long i6996; + long i6997; + long i6998; + long i6999; + long i7000; + long i7001; + long i7002; + long i7003; + long i7004; + long i7005; + long i7006; + long i7007; + long i7008; + long i7009; + long i7010; + long i7011; + long i7012; + long i7013; + long i7014; + long i7015; + long i7016; + long i7017; + long i7018; + long i7019; + long i7020; + long i7021; + long i7022; + long i7023; + long i7024; + long i7025; + long i7026; + long i7027; + long i7028; + long i7029; + long i7030; + long i7031; + long i7032; + long i7033; + long i7034; + long i7035; + long i7036; + long i7037; + long i7038; + long i7039; + long i7040; + long i7041; + long i7042; + long i7043; + long i7044; + long i7045; + long i7046; + long i7047; + long i7048; + long i7049; + long i7050; + long i7051; + long i7052; + long i7053; + long i7054; + long i7055; + long i7056; + long i7057; + long i7058; + long i7059; + long i7060; + long i7061; + long i7062; + long i7063; + long i7064; + long i7065; + long i7066; + long i7067; + long i7068; + long i7069; + long i7070; + long i7071; + long i7072; + long i7073; + long i7074; + long i7075; + long i7076; + long i7077; + long i7078; + long i7079; + long i7080; + long i7081; + long i7082; + long i7083; + long i7084; + long i7085; + long i7086; + long i7087; + long i7088; + long i7089; + long i7090; + long i7091; + long i7092; + long i7093; + long i7094; + long i7095; + long i7096; + long i7097; + long i7098; + long i7099; + long i7100; + long i7101; + long i7102; + long i7103; + long i7104; + long i7105; + long i7106; + long i7107; + long i7108; + long i7109; + long i7110; + long i7111; + long i7112; + long i7113; + long i7114; + long i7115; + long i7116; + long i7117; + long i7118; + long i7119; + long i7120; + long i7121; + long i7122; + long i7123; + long i7124; + long i7125; + long i7126; + long i7127; + long i7128; + long i7129; + long i7130; + long i7131; + long i7132; + long i7133; + long i7134; + long i7135; + long i7136; + long i7137; + long i7138; + long i7139; + long i7140; + long i7141; + long i7142; + long i7143; + long i7144; + long i7145; + long i7146; + long i7147; + long i7148; + long i7149; + long i7150; + long i7151; + long i7152; + long i7153; + long i7154; + long i7155; + long i7156; + long i7157; + long i7158; + long i7159; + long i7160; + long i7161; + long i7162; + long i7163; + long i7164; + long i7165; + long i7166; + long i7167; + long i7168; + long i7169; + long i7170; + long i7171; + long i7172; + long i7173; + long i7174; + long i7175; + long i7176; + long i7177; + long i7178; + long i7179; + long i7180; + long i7181; + long i7182; + long i7183; + long i7184; + long i7185; + long i7186; + long i7187; + long i7188; + long i7189; + long i7190; + long i7191; + long i7192; + long i7193; + long i7194; + long i7195; + long i7196; + long i7197; + long i7198; + long i7199; + long i7200; + long i7201; + long i7202; + long i7203; + long i7204; + long i7205; + long i7206; + long i7207; + long i7208; + long i7209; + long i7210; + long i7211; + long i7212; + long i7213; + long i7214; + long i7215; + long i7216; + long i7217; + long i7218; + long i7219; + long i7220; + long i7221; + long i7222; + long i7223; + long i7224; + long i7225; + long i7226; + long i7227; + long i7228; + long i7229; + long i7230; + long i7231; + long i7232; + long i7233; + long i7234; + long i7235; + long i7236; + long i7237; + long i7238; + long i7239; + long i7240; + long i7241; + long i7242; + long i7243; + long i7244; + long i7245; + long i7246; + long i7247; + long i7248; + long i7249; + long i7250; + long i7251; + long i7252; + long i7253; + long i7254; + long i7255; + long i7256; + long i7257; + long i7258; + long i7259; + long i7260; + long i7261; + long i7262; + long i7263; + long i7264; + long i7265; + long i7266; + long i7267; + long i7268; + long i7269; + long i7270; + long i7271; + long i7272; + long i7273; + long i7274; + long i7275; + long i7276; + long i7277; + long i7278; + long i7279; + long i7280; + long i7281; + long i7282; + long i7283; + long i7284; + long i7285; + long i7286; + long i7287; + long i7288; + long i7289; + long i7290; + long i7291; + long i7292; + long i7293; + long i7294; + long i7295; + long i7296; + long i7297; + long i7298; + long i7299; + long i7300; + long i7301; + long i7302; + long i7303; + long i7304; + long i7305; + long i7306; + long i7307; + long i7308; + long i7309; + long i7310; + long i7311; + long i7312; + long i7313; + long i7314; + long i7315; + long i7316; + long i7317; + long i7318; + long i7319; + long i7320; + long i7321; + long i7322; + long i7323; + long i7324; + long i7325; + long i7326; + long i7327; + long i7328; + long i7329; + long i7330; + long i7331; + long i7332; + long i7333; + long i7334; + long i7335; + long i7336; + long i7337; + long i7338; + long i7339; + long i7340; + long i7341; + long i7342; + long i7343; + long i7344; + long i7345; + long i7346; + long i7347; + long i7348; + long i7349; + long i7350; + long i7351; + long i7352; + long i7353; + long i7354; + long i7355; + long i7356; + long i7357; + long i7358; + long i7359; + long i7360; + long i7361; + long i7362; + long i7363; + long i7364; + long i7365; + long i7366; + long i7367; + long i7368; + long i7369; + long i7370; + long i7371; + long i7372; + long i7373; + long i7374; + long i7375; + long i7376; + long i7377; + long i7378; + long i7379; + long i7380; + long i7381; + long i7382; + long i7383; + long i7384; + long i7385; + long i7386; + long i7387; + long i7388; + long i7389; + long i7390; + long i7391; + long i7392; + long i7393; + long i7394; + long i7395; + long i7396; + long i7397; + long i7398; + long i7399; + long i7400; + long i7401; + long i7402; + long i7403; + long i7404; + long i7405; + long i7406; + long i7407; + long i7408; + long i7409; + long i7410; + long i7411; + long i7412; + long i7413; + long i7414; + long i7415; + long i7416; + long i7417; + long i7418; + long i7419; + long i7420; + long i7421; + long i7422; + long i7423; + long i7424; + long i7425; + long i7426; + long i7427; + long i7428; + long i7429; + long i7430; + long i7431; + long i7432; + long i7433; + long i7434; + long i7435; + long i7436; + long i7437; + long i7438; + long i7439; + long i7440; + long i7441; + long i7442; + long i7443; + long i7444; + long i7445; + long i7446; + long i7447; + long i7448; + long i7449; + long i7450; + long i7451; + long i7452; + long i7453; + long i7454; + long i7455; + long i7456; + long i7457; + long i7458; + long i7459; + long i7460; + long i7461; + long i7462; + long i7463; + long i7464; + long i7465; + long i7466; + long i7467; + long i7468; + long i7469; + long i7470; + long i7471; + long i7472; + long i7473; + long i7474; + long i7475; + long i7476; + long i7477; + long i7478; + long i7479; + long i7480; + long i7481; + long i7482; + long i7483; + long i7484; + long i7485; + long i7486; + long i7487; + long i7488; + long i7489; + long i7490; + long i7491; + long i7492; + long i7493; + long i7494; + long i7495; + long i7496; + long i7497; + long i7498; + long i7499; + long i7500; + long i7501; + long i7502; + long i7503; + long i7504; + long i7505; + long i7506; + long i7507; + long i7508; + long i7509; + long i7510; + long i7511; + long i7512; + long i7513; + long i7514; + long i7515; + long i7516; + long i7517; + long i7518; + long i7519; + long i7520; + long i7521; + long i7522; + long i7523; + long i7524; + long i7525; + long i7526; + long i7527; + long i7528; + long i7529; + long i7530; + long i7531; + long i7532; + long i7533; + long i7534; + long i7535; + long i7536; + long i7537; + long i7538; + long i7539; + long i7540; + long i7541; + long i7542; + long i7543; + long i7544; + long i7545; + long i7546; + long i7547; + long i7548; + long i7549; + long i7550; + long i7551; + long i7552; + long i7553; + long i7554; + long i7555; + long i7556; + long i7557; + long i7558; + long i7559; + long i7560; + long i7561; + long i7562; + long i7563; + long i7564; + long i7565; + long i7566; + long i7567; + long i7568; + long i7569; + long i7570; + long i7571; + long i7572; + long i7573; + long i7574; + long i7575; + long i7576; + long i7577; + long i7578; + long i7579; + long i7580; + long i7581; + long i7582; + long i7583; + long i7584; + long i7585; + long i7586; + long i7587; + long i7588; + long i7589; + long i7590; + long i7591; + long i7592; + long i7593; + long i7594; + long i7595; + long i7596; + long i7597; + long i7598; + long i7599; + long i7600; + long i7601; + long i7602; + long i7603; + long i7604; + long i7605; + long i7606; + long i7607; + long i7608; + long i7609; + long i7610; + long i7611; + long i7612; + long i7613; + long i7614; + long i7615; + long i7616; + long i7617; + long i7618; + long i7619; + long i7620; + long i7621; + long i7622; + long i7623; + long i7624; + long i7625; + long i7626; + long i7627; + long i7628; + long i7629; + long i7630; + long i7631; + long i7632; + long i7633; + long i7634; + long i7635; + long i7636; + long i7637; + long i7638; + long i7639; + long i7640; + long i7641; + long i7642; + long i7643; + long i7644; + long i7645; + long i7646; + long i7647; + long i7648; + long i7649; + long i7650; + long i7651; + long i7652; + long i7653; + long i7654; + long i7655; + long i7656; + long i7657; + long i7658; + long i7659; + long i7660; + long i7661; + long i7662; + long i7663; + long i7664; + long i7665; + long i7666; + long i7667; + long i7668; + long i7669; + long i7670; + long i7671; + long i7672; + long i7673; + long i7674; + long i7675; + long i7676; + long i7677; + long i7678; + long i7679; + long i7680; + long i7681; + long i7682; + long i7683; + long i7684; + long i7685; + long i7686; + long i7687; + long i7688; + long i7689; + long i7690; + long i7691; + long i7692; + long i7693; + long i7694; + long i7695; + long i7696; + long i7697; + long i7698; + long i7699; + long i7700; + long i7701; + long i7702; + long i7703; + long i7704; + long i7705; + long i7706; + long i7707; + long i7708; + long i7709; + long i7710; + long i7711; + long i7712; + long i7713; + long i7714; + long i7715; + long i7716; + long i7717; + long i7718; + long i7719; + long i7720; + long i7721; + long i7722; + long i7723; + long i7724; + long i7725; + long i7726; + long i7727; + long i7728; + long i7729; + long i7730; + long i7731; + long i7732; + long i7733; + long i7734; + long i7735; + long i7736; + long i7737; + long i7738; + long i7739; + long i7740; + long i7741; + long i7742; + long i7743; + long i7744; + long i7745; + long i7746; + long i7747; + long i7748; + long i7749; + long i7750; + long i7751; + long i7752; + long i7753; + long i7754; + long i7755; + long i7756; + long i7757; + long i7758; + long i7759; + long i7760; + long i7761; + long i7762; + long i7763; + long i7764; + long i7765; + long i7766; + long i7767; + long i7768; + long i7769; + long i7770; + long i7771; + long i7772; + long i7773; + long i7774; + long i7775; + long i7776; + long i7777; + long i7778; + long i7779; + long i7780; + long i7781; + long i7782; + long i7783; + long i7784; + long i7785; + long i7786; + long i7787; + long i7788; + long i7789; + long i7790; + long i7791; + long i7792; + long i7793; + long i7794; + long i7795; + long i7796; + long i7797; + long i7798; + long i7799; + long i7800; + long i7801; + long i7802; + long i7803; + long i7804; + long i7805; + long i7806; + long i7807; + long i7808; + long i7809; + long i7810; + long i7811; + long i7812; + long i7813; + long i7814; + long i7815; + long i7816; + long i7817; + long i7818; + long i7819; + long i7820; + long i7821; + long i7822; + long i7823; + long i7824; + long i7825; + long i7826; + long i7827; + long i7828; + long i7829; + long i7830; + long i7831; + long i7832; + long i7833; + long i7834; + long i7835; + long i7836; + long i7837; + long i7838; + long i7839; + long i7840; + long i7841; + long i7842; + long i7843; + long i7844; + long i7845; + long i7846; + long i7847; + long i7848; + long i7849; + long i7850; + long i7851; + long i7852; + long i7853; + long i7854; + long i7855; + long i7856; + long i7857; + long i7858; + long i7859; + long i7860; + long i7861; + long i7862; + long i7863; + long i7864; + long i7865; + long i7866; + long i7867; + long i7868; + long i7869; + long i7870; + long i7871; + long i7872; + long i7873; + long i7874; + long i7875; + long i7876; + long i7877; + long i7878; + long i7879; + long i7880; + long i7881; + long i7882; + long i7883; + long i7884; + long i7885; + long i7886; + long i7887; + long i7888; + long i7889; + long i7890; + long i7891; + long i7892; + long i7893; + long i7894; + long i7895; + long i7896; + long i7897; + long i7898; + long i7899; + long i7900; + long i7901; + long i7902; + long i7903; + long i7904; + long i7905; + long i7906; + long i7907; + long i7908; + long i7909; + long i7910; + long i7911; + long i7912; + long i7913; + long i7914; + long i7915; + long i7916; + long i7917; + long i7918; + long i7919; + long i7920; + long i7921; + long i7922; + long i7923; + long i7924; + long i7925; + long i7926; + long i7927; + long i7928; + long i7929; + long i7930; + long i7931; + long i7932; + long i7933; + long i7934; + long i7935; + long i7936; + long i7937; + long i7938; + long i7939; + long i7940; + long i7941; + long i7942; + long i7943; + long i7944; + long i7945; + long i7946; + long i7947; + long i7948; + long i7949; + long i7950; + long i7951; + long i7952; + long i7953; + long i7954; + long i7955; + long i7956; + long i7957; + long i7958; + long i7959; + long i7960; + long i7961; + long i7962; + long i7963; + long i7964; + long i7965; + long i7966; + long i7967; + long i7968; + long i7969; + long i7970; + long i7971; + long i7972; + long i7973; + long i7974; + long i7975; + long i7976; + long i7977; + long i7978; + long i7979; + long i7980; + long i7981; + long i7982; + long i7983; + long i7984; + long i7985; + long i7986; + long i7987; + long i7988; + long i7989; + long i7990; + long i7991; + long i7992; + long i7993; + long i7994; + long i7995; + long i7996; + long i7997; + long i7998; + long i7999; + long i8000; + long i8001; + long i8002; + long i8003; + long i8004; + long i8005; + long i8006; + long i8007; + long i8008; + long i8009; + long i8010; + long i8011; + long i8012; + long i8013; + long i8014; + long i8015; + long i8016; + long i8017; + long i8018; + long i8019; + long i8020; + long i8021; + long i8022; + long i8023; + long i8024; + long i8025; + long i8026; + long i8027; + long i8028; + long i8029; + long i8030; + long i8031; + long i8032; + long i8033; + long i8034; + long i8035; + long i8036; + long i8037; + long i8038; + long i8039; + long i8040; + long i8041; + long i8042; + long i8043; + long i8044; + long i8045; + long i8046; + long i8047; + long i8048; + long i8049; + long i8050; + long i8051; + long i8052; + long i8053; + long i8054; + long i8055; + long i8056; + long i8057; + long i8058; + long i8059; + long i8060; + long i8061; + long i8062; + long i8063; + long i8064; + long i8065; + long i8066; + long i8067; + long i8068; + long i8069; + long i8070; + long i8071; + long i8072; + long i8073; + long i8074; + long i8075; + long i8076; + long i8077; + long i8078; + long i8079; + long i8080; + long i8081; + long i8082; + long i8083; + long i8084; + long i8085; + long i8086; + long i8087; + long i8088; + long i8089; + long i8090; + long i8091; + long i8092; + long i8093; + long i8094; + long i8095; + long i8096; + long i8097; + long i8098; + long i8099; + long i8100; + long i8101; + long i8102; + long i8103; + long i8104; + long i8105; + long i8106; + long i8107; + long i8108; + long i8109; + long i8110; + long i8111; + long i8112; + long i8113; + long i8114; + long i8115; + long i8116; + long i8117; + long i8118; + long i8119; + long i8120; + long i8121; + long i8122; + long i8123; + long i8124; + long i8125; + long i8126; + long i8127; + long i8128; + long i8129; + long i8130; + long i8131; + long i8132; + long i8133; + long i8134; + long i8135; + long i8136; + long i8137; + long i8138; + long i8139; + long i8140; + long i8141; + long i8142; + long i8143; + long i8144; + long i8145; + long i8146; + long i8147; + long i8148; + long i8149; + long i8150; + long i8151; + long i8152; + long i8153; + long i8154; + long i8155; + long i8156; + long i8157; + long i8158; + long i8159; + long i8160; + long i8161; + long i8162; + long i8163; + long i8164; + long i8165; + long i8166; + long i8167; + long i8168; + long i8169; + long i8170; + long i8171; + long i8172; + long i8173; + long i8174; + long i8175; + long i8176; + long i8177; + long i8178; + long i8179; + long i8180; + long i8181; + long i8182; + long i8183; + long i8184; + long i8185; + long i8186; + long i8187; + long i8188; + long i8189; + } + static class Class131072 extends BaseClass { + long i0; + long i1; + long i2; + long i3; + long i4; + long i5; + long i6; + long i7; + long i8; + long i9; + long i10; + long i11; + long i12; + long i13; + long i14; + long i15; + long i16; + long i17; + long i18; + long i19; + long i20; + long i21; + long i22; + long i23; + long i24; + long i25; + long i26; + long i27; + long i28; + long i29; + long i30; + long i31; + long i32; + long i33; + long i34; + long i35; + long i36; + long i37; + long i38; + long i39; + long i40; + long i41; + long i42; + long i43; + long i44; + long i45; + long i46; + long i47; + long i48; + long i49; + long i50; + long i51; + long i52; + long i53; + long i54; + long i55; + long i56; + long i57; + long i58; + long i59; + long i60; + long i61; + long i62; + long i63; + long i64; + long i65; + long i66; + long i67; + long i68; + long i69; + long i70; + long i71; + long i72; + long i73; + long i74; + long i75; + long i76; + long i77; + long i78; + long i79; + long i80; + long i81; + long i82; + long i83; + long i84; + long i85; + long i86; + long i87; + long i88; + long i89; + long i90; + long i91; + long i92; + long i93; + long i94; + long i95; + long i96; + long i97; + long i98; + long i99; + long i100; + long i101; + long i102; + long i103; + long i104; + long i105; + long i106; + long i107; + long i108; + long i109; + long i110; + long i111; + long i112; + long i113; + long i114; + long i115; + long i116; + long i117; + long i118; + long i119; + long i120; + long i121; + long i122; + long i123; + long i124; + long i125; + long i126; + long i127; + long i128; + long i129; + long i130; + long i131; + long i132; + long i133; + long i134; + long i135; + long i136; + long i137; + long i138; + long i139; + long i140; + long i141; + long i142; + long i143; + long i144; + long i145; + long i146; + long i147; + long i148; + long i149; + long i150; + long i151; + long i152; + long i153; + long i154; + long i155; + long i156; + long i157; + long i158; + long i159; + long i160; + long i161; + long i162; + long i163; + long i164; + long i165; + long i166; + long i167; + long i168; + long i169; + long i170; + long i171; + long i172; + long i173; + long i174; + long i175; + long i176; + long i177; + long i178; + long i179; + long i180; + long i181; + long i182; + long i183; + long i184; + long i185; + long i186; + long i187; + long i188; + long i189; + long i190; + long i191; + long i192; + long i193; + long i194; + long i195; + long i196; + long i197; + long i198; + long i199; + long i200; + long i201; + long i202; + long i203; + long i204; + long i205; + long i206; + long i207; + long i208; + long i209; + long i210; + long i211; + long i212; + long i213; + long i214; + long i215; + long i216; + long i217; + long i218; + long i219; + long i220; + long i221; + long i222; + long i223; + long i224; + long i225; + long i226; + long i227; + long i228; + long i229; + long i230; + long i231; + long i232; + long i233; + long i234; + long i235; + long i236; + long i237; + long i238; + long i239; + long i240; + long i241; + long i242; + long i243; + long i244; + long i245; + long i246; + long i247; + long i248; + long i249; + long i250; + long i251; + long i252; + long i253; + long i254; + long i255; + long i256; + long i257; + long i258; + long i259; + long i260; + long i261; + long i262; + long i263; + long i264; + long i265; + long i266; + long i267; + long i268; + long i269; + long i270; + long i271; + long i272; + long i273; + long i274; + long i275; + long i276; + long i277; + long i278; + long i279; + long i280; + long i281; + long i282; + long i283; + long i284; + long i285; + long i286; + long i287; + long i288; + long i289; + long i290; + long i291; + long i292; + long i293; + long i294; + long i295; + long i296; + long i297; + long i298; + long i299; + long i300; + long i301; + long i302; + long i303; + long i304; + long i305; + long i306; + long i307; + long i308; + long i309; + long i310; + long i311; + long i312; + long i313; + long i314; + long i315; + long i316; + long i317; + long i318; + long i319; + long i320; + long i321; + long i322; + long i323; + long i324; + long i325; + long i326; + long i327; + long i328; + long i329; + long i330; + long i331; + long i332; + long i333; + long i334; + long i335; + long i336; + long i337; + long i338; + long i339; + long i340; + long i341; + long i342; + long i343; + long i344; + long i345; + long i346; + long i347; + long i348; + long i349; + long i350; + long i351; + long i352; + long i353; + long i354; + long i355; + long i356; + long i357; + long i358; + long i359; + long i360; + long i361; + long i362; + long i363; + long i364; + long i365; + long i366; + long i367; + long i368; + long i369; + long i370; + long i371; + long i372; + long i373; + long i374; + long i375; + long i376; + long i377; + long i378; + long i379; + long i380; + long i381; + long i382; + long i383; + long i384; + long i385; + long i386; + long i387; + long i388; + long i389; + long i390; + long i391; + long i392; + long i393; + long i394; + long i395; + long i396; + long i397; + long i398; + long i399; + long i400; + long i401; + long i402; + long i403; + long i404; + long i405; + long i406; + long i407; + long i408; + long i409; + long i410; + long i411; + long i412; + long i413; + long i414; + long i415; + long i416; + long i417; + long i418; + long i419; + long i420; + long i421; + long i422; + long i423; + long i424; + long i425; + long i426; + long i427; + long i428; + long i429; + long i430; + long i431; + long i432; + long i433; + long i434; + long i435; + long i436; + long i437; + long i438; + long i439; + long i440; + long i441; + long i442; + long i443; + long i444; + long i445; + long i446; + long i447; + long i448; + long i449; + long i450; + long i451; + long i452; + long i453; + long i454; + long i455; + long i456; + long i457; + long i458; + long i459; + long i460; + long i461; + long i462; + long i463; + long i464; + long i465; + long i466; + long i467; + long i468; + long i469; + long i470; + long i471; + long i472; + long i473; + long i474; + long i475; + long i476; + long i477; + long i478; + long i479; + long i480; + long i481; + long i482; + long i483; + long i484; + long i485; + long i486; + long i487; + long i488; + long i489; + long i490; + long i491; + long i492; + long i493; + long i494; + long i495; + long i496; + long i497; + long i498; + long i499; + long i500; + long i501; + long i502; + long i503; + long i504; + long i505; + long i506; + long i507; + long i508; + long i509; + long i510; + long i511; + long i512; + long i513; + long i514; + long i515; + long i516; + long i517; + long i518; + long i519; + long i520; + long i521; + long i522; + long i523; + long i524; + long i525; + long i526; + long i527; + long i528; + long i529; + long i530; + long i531; + long i532; + long i533; + long i534; + long i535; + long i536; + long i537; + long i538; + long i539; + long i540; + long i541; + long i542; + long i543; + long i544; + long i545; + long i546; + long i547; + long i548; + long i549; + long i550; + long i551; + long i552; + long i553; + long i554; + long i555; + long i556; + long i557; + long i558; + long i559; + long i560; + long i561; + long i562; + long i563; + long i564; + long i565; + long i566; + long i567; + long i568; + long i569; + long i570; + long i571; + long i572; + long i573; + long i574; + long i575; + long i576; + long i577; + long i578; + long i579; + long i580; + long i581; + long i582; + long i583; + long i584; + long i585; + long i586; + long i587; + long i588; + long i589; + long i590; + long i591; + long i592; + long i593; + long i594; + long i595; + long i596; + long i597; + long i598; + long i599; + long i600; + long i601; + long i602; + long i603; + long i604; + long i605; + long i606; + long i607; + long i608; + long i609; + long i610; + long i611; + long i612; + long i613; + long i614; + long i615; + long i616; + long i617; + long i618; + long i619; + long i620; + long i621; + long i622; + long i623; + long i624; + long i625; + long i626; + long i627; + long i628; + long i629; + long i630; + long i631; + long i632; + long i633; + long i634; + long i635; + long i636; + long i637; + long i638; + long i639; + long i640; + long i641; + long i642; + long i643; + long i644; + long i645; + long i646; + long i647; + long i648; + long i649; + long i650; + long i651; + long i652; + long i653; + long i654; + long i655; + long i656; + long i657; + long i658; + long i659; + long i660; + long i661; + long i662; + long i663; + long i664; + long i665; + long i666; + long i667; + long i668; + long i669; + long i670; + long i671; + long i672; + long i673; + long i674; + long i675; + long i676; + long i677; + long i678; + long i679; + long i680; + long i681; + long i682; + long i683; + long i684; + long i685; + long i686; + long i687; + long i688; + long i689; + long i690; + long i691; + long i692; + long i693; + long i694; + long i695; + long i696; + long i697; + long i698; + long i699; + long i700; + long i701; + long i702; + long i703; + long i704; + long i705; + long i706; + long i707; + long i708; + long i709; + long i710; + long i711; + long i712; + long i713; + long i714; + long i715; + long i716; + long i717; + long i718; + long i719; + long i720; + long i721; + long i722; + long i723; + long i724; + long i725; + long i726; + long i727; + long i728; + long i729; + long i730; + long i731; + long i732; + long i733; + long i734; + long i735; + long i736; + long i737; + long i738; + long i739; + long i740; + long i741; + long i742; + long i743; + long i744; + long i745; + long i746; + long i747; + long i748; + long i749; + long i750; + long i751; + long i752; + long i753; + long i754; + long i755; + long i756; + long i757; + long i758; + long i759; + long i760; + long i761; + long i762; + long i763; + long i764; + long i765; + long i766; + long i767; + long i768; + long i769; + long i770; + long i771; + long i772; + long i773; + long i774; + long i775; + long i776; + long i777; + long i778; + long i779; + long i780; + long i781; + long i782; + long i783; + long i784; + long i785; + long i786; + long i787; + long i788; + long i789; + long i790; + long i791; + long i792; + long i793; + long i794; + long i795; + long i796; + long i797; + long i798; + long i799; + long i800; + long i801; + long i802; + long i803; + long i804; + long i805; + long i806; + long i807; + long i808; + long i809; + long i810; + long i811; + long i812; + long i813; + long i814; + long i815; + long i816; + long i817; + long i818; + long i819; + long i820; + long i821; + long i822; + long i823; + long i824; + long i825; + long i826; + long i827; + long i828; + long i829; + long i830; + long i831; + long i832; + long i833; + long i834; + long i835; + long i836; + long i837; + long i838; + long i839; + long i840; + long i841; + long i842; + long i843; + long i844; + long i845; + long i846; + long i847; + long i848; + long i849; + long i850; + long i851; + long i852; + long i853; + long i854; + long i855; + long i856; + long i857; + long i858; + long i859; + long i860; + long i861; + long i862; + long i863; + long i864; + long i865; + long i866; + long i867; + long i868; + long i869; + long i870; + long i871; + long i872; + long i873; + long i874; + long i875; + long i876; + long i877; + long i878; + long i879; + long i880; + long i881; + long i882; + long i883; + long i884; + long i885; + long i886; + long i887; + long i888; + long i889; + long i890; + long i891; + long i892; + long i893; + long i894; + long i895; + long i896; + long i897; + long i898; + long i899; + long i900; + long i901; + long i902; + long i903; + long i904; + long i905; + long i906; + long i907; + long i908; + long i909; + long i910; + long i911; + long i912; + long i913; + long i914; + long i915; + long i916; + long i917; + long i918; + long i919; + long i920; + long i921; + long i922; + long i923; + long i924; + long i925; + long i926; + long i927; + long i928; + long i929; + long i930; + long i931; + long i932; + long i933; + long i934; + long i935; + long i936; + long i937; + long i938; + long i939; + long i940; + long i941; + long i942; + long i943; + long i944; + long i945; + long i946; + long i947; + long i948; + long i949; + long i950; + long i951; + long i952; + long i953; + long i954; + long i955; + long i956; + long i957; + long i958; + long i959; + long i960; + long i961; + long i962; + long i963; + long i964; + long i965; + long i966; + long i967; + long i968; + long i969; + long i970; + long i971; + long i972; + long i973; + long i974; + long i975; + long i976; + long i977; + long i978; + long i979; + long i980; + long i981; + long i982; + long i983; + long i984; + long i985; + long i986; + long i987; + long i988; + long i989; + long i990; + long i991; + long i992; + long i993; + long i994; + long i995; + long i996; + long i997; + long i998; + long i999; + long i1000; + long i1001; + long i1002; + long i1003; + long i1004; + long i1005; + long i1006; + long i1007; + long i1008; + long i1009; + long i1010; + long i1011; + long i1012; + long i1013; + long i1014; + long i1015; + long i1016; + long i1017; + long i1018; + long i1019; + long i1020; + long i1021; + long i1022; + long i1023; + long i1024; + long i1025; + long i1026; + long i1027; + long i1028; + long i1029; + long i1030; + long i1031; + long i1032; + long i1033; + long i1034; + long i1035; + long i1036; + long i1037; + long i1038; + long i1039; + long i1040; + long i1041; + long i1042; + long i1043; + long i1044; + long i1045; + long i1046; + long i1047; + long i1048; + long i1049; + long i1050; + long i1051; + long i1052; + long i1053; + long i1054; + long i1055; + long i1056; + long i1057; + long i1058; + long i1059; + long i1060; + long i1061; + long i1062; + long i1063; + long i1064; + long i1065; + long i1066; + long i1067; + long i1068; + long i1069; + long i1070; + long i1071; + long i1072; + long i1073; + long i1074; + long i1075; + long i1076; + long i1077; + long i1078; + long i1079; + long i1080; + long i1081; + long i1082; + long i1083; + long i1084; + long i1085; + long i1086; + long i1087; + long i1088; + long i1089; + long i1090; + long i1091; + long i1092; + long i1093; + long i1094; + long i1095; + long i1096; + long i1097; + long i1098; + long i1099; + long i1100; + long i1101; + long i1102; + long i1103; + long i1104; + long i1105; + long i1106; + long i1107; + long i1108; + long i1109; + long i1110; + long i1111; + long i1112; + long i1113; + long i1114; + long i1115; + long i1116; + long i1117; + long i1118; + long i1119; + long i1120; + long i1121; + long i1122; + long i1123; + long i1124; + long i1125; + long i1126; + long i1127; + long i1128; + long i1129; + long i1130; + long i1131; + long i1132; + long i1133; + long i1134; + long i1135; + long i1136; + long i1137; + long i1138; + long i1139; + long i1140; + long i1141; + long i1142; + long i1143; + long i1144; + long i1145; + long i1146; + long i1147; + long i1148; + long i1149; + long i1150; + long i1151; + long i1152; + long i1153; + long i1154; + long i1155; + long i1156; + long i1157; + long i1158; + long i1159; + long i1160; + long i1161; + long i1162; + long i1163; + long i1164; + long i1165; + long i1166; + long i1167; + long i1168; + long i1169; + long i1170; + long i1171; + long i1172; + long i1173; + long i1174; + long i1175; + long i1176; + long i1177; + long i1178; + long i1179; + long i1180; + long i1181; + long i1182; + long i1183; + long i1184; + long i1185; + long i1186; + long i1187; + long i1188; + long i1189; + long i1190; + long i1191; + long i1192; + long i1193; + long i1194; + long i1195; + long i1196; + long i1197; + long i1198; + long i1199; + long i1200; + long i1201; + long i1202; + long i1203; + long i1204; + long i1205; + long i1206; + long i1207; + long i1208; + long i1209; + long i1210; + long i1211; + long i1212; + long i1213; + long i1214; + long i1215; + long i1216; + long i1217; + long i1218; + long i1219; + long i1220; + long i1221; + long i1222; + long i1223; + long i1224; + long i1225; + long i1226; + long i1227; + long i1228; + long i1229; + long i1230; + long i1231; + long i1232; + long i1233; + long i1234; + long i1235; + long i1236; + long i1237; + long i1238; + long i1239; + long i1240; + long i1241; + long i1242; + long i1243; + long i1244; + long i1245; + long i1246; + long i1247; + long i1248; + long i1249; + long i1250; + long i1251; + long i1252; + long i1253; + long i1254; + long i1255; + long i1256; + long i1257; + long i1258; + long i1259; + long i1260; + long i1261; + long i1262; + long i1263; + long i1264; + long i1265; + long i1266; + long i1267; + long i1268; + long i1269; + long i1270; + long i1271; + long i1272; + long i1273; + long i1274; + long i1275; + long i1276; + long i1277; + long i1278; + long i1279; + long i1280; + long i1281; + long i1282; + long i1283; + long i1284; + long i1285; + long i1286; + long i1287; + long i1288; + long i1289; + long i1290; + long i1291; + long i1292; + long i1293; + long i1294; + long i1295; + long i1296; + long i1297; + long i1298; + long i1299; + long i1300; + long i1301; + long i1302; + long i1303; + long i1304; + long i1305; + long i1306; + long i1307; + long i1308; + long i1309; + long i1310; + long i1311; + long i1312; + long i1313; + long i1314; + long i1315; + long i1316; + long i1317; + long i1318; + long i1319; + long i1320; + long i1321; + long i1322; + long i1323; + long i1324; + long i1325; + long i1326; + long i1327; + long i1328; + long i1329; + long i1330; + long i1331; + long i1332; + long i1333; + long i1334; + long i1335; + long i1336; + long i1337; + long i1338; + long i1339; + long i1340; + long i1341; + long i1342; + long i1343; + long i1344; + long i1345; + long i1346; + long i1347; + long i1348; + long i1349; + long i1350; + long i1351; + long i1352; + long i1353; + long i1354; + long i1355; + long i1356; + long i1357; + long i1358; + long i1359; + long i1360; + long i1361; + long i1362; + long i1363; + long i1364; + long i1365; + long i1366; + long i1367; + long i1368; + long i1369; + long i1370; + long i1371; + long i1372; + long i1373; + long i1374; + long i1375; + long i1376; + long i1377; + long i1378; + long i1379; + long i1380; + long i1381; + long i1382; + long i1383; + long i1384; + long i1385; + long i1386; + long i1387; + long i1388; + long i1389; + long i1390; + long i1391; + long i1392; + long i1393; + long i1394; + long i1395; + long i1396; + long i1397; + long i1398; + long i1399; + long i1400; + long i1401; + long i1402; + long i1403; + long i1404; + long i1405; + long i1406; + long i1407; + long i1408; + long i1409; + long i1410; + long i1411; + long i1412; + long i1413; + long i1414; + long i1415; + long i1416; + long i1417; + long i1418; + long i1419; + long i1420; + long i1421; + long i1422; + long i1423; + long i1424; + long i1425; + long i1426; + long i1427; + long i1428; + long i1429; + long i1430; + long i1431; + long i1432; + long i1433; + long i1434; + long i1435; + long i1436; + long i1437; + long i1438; + long i1439; + long i1440; + long i1441; + long i1442; + long i1443; + long i1444; + long i1445; + long i1446; + long i1447; + long i1448; + long i1449; + long i1450; + long i1451; + long i1452; + long i1453; + long i1454; + long i1455; + long i1456; + long i1457; + long i1458; + long i1459; + long i1460; + long i1461; + long i1462; + long i1463; + long i1464; + long i1465; + long i1466; + long i1467; + long i1468; + long i1469; + long i1470; + long i1471; + long i1472; + long i1473; + long i1474; + long i1475; + long i1476; + long i1477; + long i1478; + long i1479; + long i1480; + long i1481; + long i1482; + long i1483; + long i1484; + long i1485; + long i1486; + long i1487; + long i1488; + long i1489; + long i1490; + long i1491; + long i1492; + long i1493; + long i1494; + long i1495; + long i1496; + long i1497; + long i1498; + long i1499; + long i1500; + long i1501; + long i1502; + long i1503; + long i1504; + long i1505; + long i1506; + long i1507; + long i1508; + long i1509; + long i1510; + long i1511; + long i1512; + long i1513; + long i1514; + long i1515; + long i1516; + long i1517; + long i1518; + long i1519; + long i1520; + long i1521; + long i1522; + long i1523; + long i1524; + long i1525; + long i1526; + long i1527; + long i1528; + long i1529; + long i1530; + long i1531; + long i1532; + long i1533; + long i1534; + long i1535; + long i1536; + long i1537; + long i1538; + long i1539; + long i1540; + long i1541; + long i1542; + long i1543; + long i1544; + long i1545; + long i1546; + long i1547; + long i1548; + long i1549; + long i1550; + long i1551; + long i1552; + long i1553; + long i1554; + long i1555; + long i1556; + long i1557; + long i1558; + long i1559; + long i1560; + long i1561; + long i1562; + long i1563; + long i1564; + long i1565; + long i1566; + long i1567; + long i1568; + long i1569; + long i1570; + long i1571; + long i1572; + long i1573; + long i1574; + long i1575; + long i1576; + long i1577; + long i1578; + long i1579; + long i1580; + long i1581; + long i1582; + long i1583; + long i1584; + long i1585; + long i1586; + long i1587; + long i1588; + long i1589; + long i1590; + long i1591; + long i1592; + long i1593; + long i1594; + long i1595; + long i1596; + long i1597; + long i1598; + long i1599; + long i1600; + long i1601; + long i1602; + long i1603; + long i1604; + long i1605; + long i1606; + long i1607; + long i1608; + long i1609; + long i1610; + long i1611; + long i1612; + long i1613; + long i1614; + long i1615; + long i1616; + long i1617; + long i1618; + long i1619; + long i1620; + long i1621; + long i1622; + long i1623; + long i1624; + long i1625; + long i1626; + long i1627; + long i1628; + long i1629; + long i1630; + long i1631; + long i1632; + long i1633; + long i1634; + long i1635; + long i1636; + long i1637; + long i1638; + long i1639; + long i1640; + long i1641; + long i1642; + long i1643; + long i1644; + long i1645; + long i1646; + long i1647; + long i1648; + long i1649; + long i1650; + long i1651; + long i1652; + long i1653; + long i1654; + long i1655; + long i1656; + long i1657; + long i1658; + long i1659; + long i1660; + long i1661; + long i1662; + long i1663; + long i1664; + long i1665; + long i1666; + long i1667; + long i1668; + long i1669; + long i1670; + long i1671; + long i1672; + long i1673; + long i1674; + long i1675; + long i1676; + long i1677; + long i1678; + long i1679; + long i1680; + long i1681; + long i1682; + long i1683; + long i1684; + long i1685; + long i1686; + long i1687; + long i1688; + long i1689; + long i1690; + long i1691; + long i1692; + long i1693; + long i1694; + long i1695; + long i1696; + long i1697; + long i1698; + long i1699; + long i1700; + long i1701; + long i1702; + long i1703; + long i1704; + long i1705; + long i1706; + long i1707; + long i1708; + long i1709; + long i1710; + long i1711; + long i1712; + long i1713; + long i1714; + long i1715; + long i1716; + long i1717; + long i1718; + long i1719; + long i1720; + long i1721; + long i1722; + long i1723; + long i1724; + long i1725; + long i1726; + long i1727; + long i1728; + long i1729; + long i1730; + long i1731; + long i1732; + long i1733; + long i1734; + long i1735; + long i1736; + long i1737; + long i1738; + long i1739; + long i1740; + long i1741; + long i1742; + long i1743; + long i1744; + long i1745; + long i1746; + long i1747; + long i1748; + long i1749; + long i1750; + long i1751; + long i1752; + long i1753; + long i1754; + long i1755; + long i1756; + long i1757; + long i1758; + long i1759; + long i1760; + long i1761; + long i1762; + long i1763; + long i1764; + long i1765; + long i1766; + long i1767; + long i1768; + long i1769; + long i1770; + long i1771; + long i1772; + long i1773; + long i1774; + long i1775; + long i1776; + long i1777; + long i1778; + long i1779; + long i1780; + long i1781; + long i1782; + long i1783; + long i1784; + long i1785; + long i1786; + long i1787; + long i1788; + long i1789; + long i1790; + long i1791; + long i1792; + long i1793; + long i1794; + long i1795; + long i1796; + long i1797; + long i1798; + long i1799; + long i1800; + long i1801; + long i1802; + long i1803; + long i1804; + long i1805; + long i1806; + long i1807; + long i1808; + long i1809; + long i1810; + long i1811; + long i1812; + long i1813; + long i1814; + long i1815; + long i1816; + long i1817; + long i1818; + long i1819; + long i1820; + long i1821; + long i1822; + long i1823; + long i1824; + long i1825; + long i1826; + long i1827; + long i1828; + long i1829; + long i1830; + long i1831; + long i1832; + long i1833; + long i1834; + long i1835; + long i1836; + long i1837; + long i1838; + long i1839; + long i1840; + long i1841; + long i1842; + long i1843; + long i1844; + long i1845; + long i1846; + long i1847; + long i1848; + long i1849; + long i1850; + long i1851; + long i1852; + long i1853; + long i1854; + long i1855; + long i1856; + long i1857; + long i1858; + long i1859; + long i1860; + long i1861; + long i1862; + long i1863; + long i1864; + long i1865; + long i1866; + long i1867; + long i1868; + long i1869; + long i1870; + long i1871; + long i1872; + long i1873; + long i1874; + long i1875; + long i1876; + long i1877; + long i1878; + long i1879; + long i1880; + long i1881; + long i1882; + long i1883; + long i1884; + long i1885; + long i1886; + long i1887; + long i1888; + long i1889; + long i1890; + long i1891; + long i1892; + long i1893; + long i1894; + long i1895; + long i1896; + long i1897; + long i1898; + long i1899; + long i1900; + long i1901; + long i1902; + long i1903; + long i1904; + long i1905; + long i1906; + long i1907; + long i1908; + long i1909; + long i1910; + long i1911; + long i1912; + long i1913; + long i1914; + long i1915; + long i1916; + long i1917; + long i1918; + long i1919; + long i1920; + long i1921; + long i1922; + long i1923; + long i1924; + long i1925; + long i1926; + long i1927; + long i1928; + long i1929; + long i1930; + long i1931; + long i1932; + long i1933; + long i1934; + long i1935; + long i1936; + long i1937; + long i1938; + long i1939; + long i1940; + long i1941; + long i1942; + long i1943; + long i1944; + long i1945; + long i1946; + long i1947; + long i1948; + long i1949; + long i1950; + long i1951; + long i1952; + long i1953; + long i1954; + long i1955; + long i1956; + long i1957; + long i1958; + long i1959; + long i1960; + long i1961; + long i1962; + long i1963; + long i1964; + long i1965; + long i1966; + long i1967; + long i1968; + long i1969; + long i1970; + long i1971; + long i1972; + long i1973; + long i1974; + long i1975; + long i1976; + long i1977; + long i1978; + long i1979; + long i1980; + long i1981; + long i1982; + long i1983; + long i1984; + long i1985; + long i1986; + long i1987; + long i1988; + long i1989; + long i1990; + long i1991; + long i1992; + long i1993; + long i1994; + long i1995; + long i1996; + long i1997; + long i1998; + long i1999; + long i2000; + long i2001; + long i2002; + long i2003; + long i2004; + long i2005; + long i2006; + long i2007; + long i2008; + long i2009; + long i2010; + long i2011; + long i2012; + long i2013; + long i2014; + long i2015; + long i2016; + long i2017; + long i2018; + long i2019; + long i2020; + long i2021; + long i2022; + long i2023; + long i2024; + long i2025; + long i2026; + long i2027; + long i2028; + long i2029; + long i2030; + long i2031; + long i2032; + long i2033; + long i2034; + long i2035; + long i2036; + long i2037; + long i2038; + long i2039; + long i2040; + long i2041; + long i2042; + long i2043; + long i2044; + long i2045; + long i2046; + long i2047; + long i2048; + long i2049; + long i2050; + long i2051; + long i2052; + long i2053; + long i2054; + long i2055; + long i2056; + long i2057; + long i2058; + long i2059; + long i2060; + long i2061; + long i2062; + long i2063; + long i2064; + long i2065; + long i2066; + long i2067; + long i2068; + long i2069; + long i2070; + long i2071; + long i2072; + long i2073; + long i2074; + long i2075; + long i2076; + long i2077; + long i2078; + long i2079; + long i2080; + long i2081; + long i2082; + long i2083; + long i2084; + long i2085; + long i2086; + long i2087; + long i2088; + long i2089; + long i2090; + long i2091; + long i2092; + long i2093; + long i2094; + long i2095; + long i2096; + long i2097; + long i2098; + long i2099; + long i2100; + long i2101; + long i2102; + long i2103; + long i2104; + long i2105; + long i2106; + long i2107; + long i2108; + long i2109; + long i2110; + long i2111; + long i2112; + long i2113; + long i2114; + long i2115; + long i2116; + long i2117; + long i2118; + long i2119; + long i2120; + long i2121; + long i2122; + long i2123; + long i2124; + long i2125; + long i2126; + long i2127; + long i2128; + long i2129; + long i2130; + long i2131; + long i2132; + long i2133; + long i2134; + long i2135; + long i2136; + long i2137; + long i2138; + long i2139; + long i2140; + long i2141; + long i2142; + long i2143; + long i2144; + long i2145; + long i2146; + long i2147; + long i2148; + long i2149; + long i2150; + long i2151; + long i2152; + long i2153; + long i2154; + long i2155; + long i2156; + long i2157; + long i2158; + long i2159; + long i2160; + long i2161; + long i2162; + long i2163; + long i2164; + long i2165; + long i2166; + long i2167; + long i2168; + long i2169; + long i2170; + long i2171; + long i2172; + long i2173; + long i2174; + long i2175; + long i2176; + long i2177; + long i2178; + long i2179; + long i2180; + long i2181; + long i2182; + long i2183; + long i2184; + long i2185; + long i2186; + long i2187; + long i2188; + long i2189; + long i2190; + long i2191; + long i2192; + long i2193; + long i2194; + long i2195; + long i2196; + long i2197; + long i2198; + long i2199; + long i2200; + long i2201; + long i2202; + long i2203; + long i2204; + long i2205; + long i2206; + long i2207; + long i2208; + long i2209; + long i2210; + long i2211; + long i2212; + long i2213; + long i2214; + long i2215; + long i2216; + long i2217; + long i2218; + long i2219; + long i2220; + long i2221; + long i2222; + long i2223; + long i2224; + long i2225; + long i2226; + long i2227; + long i2228; + long i2229; + long i2230; + long i2231; + long i2232; + long i2233; + long i2234; + long i2235; + long i2236; + long i2237; + long i2238; + long i2239; + long i2240; + long i2241; + long i2242; + long i2243; + long i2244; + long i2245; + long i2246; + long i2247; + long i2248; + long i2249; + long i2250; + long i2251; + long i2252; + long i2253; + long i2254; + long i2255; + long i2256; + long i2257; + long i2258; + long i2259; + long i2260; + long i2261; + long i2262; + long i2263; + long i2264; + long i2265; + long i2266; + long i2267; + long i2268; + long i2269; + long i2270; + long i2271; + long i2272; + long i2273; + long i2274; + long i2275; + long i2276; + long i2277; + long i2278; + long i2279; + long i2280; + long i2281; + long i2282; + long i2283; + long i2284; + long i2285; + long i2286; + long i2287; + long i2288; + long i2289; + long i2290; + long i2291; + long i2292; + long i2293; + long i2294; + long i2295; + long i2296; + long i2297; + long i2298; + long i2299; + long i2300; + long i2301; + long i2302; + long i2303; + long i2304; + long i2305; + long i2306; + long i2307; + long i2308; + long i2309; + long i2310; + long i2311; + long i2312; + long i2313; + long i2314; + long i2315; + long i2316; + long i2317; + long i2318; + long i2319; + long i2320; + long i2321; + long i2322; + long i2323; + long i2324; + long i2325; + long i2326; + long i2327; + long i2328; + long i2329; + long i2330; + long i2331; + long i2332; + long i2333; + long i2334; + long i2335; + long i2336; + long i2337; + long i2338; + long i2339; + long i2340; + long i2341; + long i2342; + long i2343; + long i2344; + long i2345; + long i2346; + long i2347; + long i2348; + long i2349; + long i2350; + long i2351; + long i2352; + long i2353; + long i2354; + long i2355; + long i2356; + long i2357; + long i2358; + long i2359; + long i2360; + long i2361; + long i2362; + long i2363; + long i2364; + long i2365; + long i2366; + long i2367; + long i2368; + long i2369; + long i2370; + long i2371; + long i2372; + long i2373; + long i2374; + long i2375; + long i2376; + long i2377; + long i2378; + long i2379; + long i2380; + long i2381; + long i2382; + long i2383; + long i2384; + long i2385; + long i2386; + long i2387; + long i2388; + long i2389; + long i2390; + long i2391; + long i2392; + long i2393; + long i2394; + long i2395; + long i2396; + long i2397; + long i2398; + long i2399; + long i2400; + long i2401; + long i2402; + long i2403; + long i2404; + long i2405; + long i2406; + long i2407; + long i2408; + long i2409; + long i2410; + long i2411; + long i2412; + long i2413; + long i2414; + long i2415; + long i2416; + long i2417; + long i2418; + long i2419; + long i2420; + long i2421; + long i2422; + long i2423; + long i2424; + long i2425; + long i2426; + long i2427; + long i2428; + long i2429; + long i2430; + long i2431; + long i2432; + long i2433; + long i2434; + long i2435; + long i2436; + long i2437; + long i2438; + long i2439; + long i2440; + long i2441; + long i2442; + long i2443; + long i2444; + long i2445; + long i2446; + long i2447; + long i2448; + long i2449; + long i2450; + long i2451; + long i2452; + long i2453; + long i2454; + long i2455; + long i2456; + long i2457; + long i2458; + long i2459; + long i2460; + long i2461; + long i2462; + long i2463; + long i2464; + long i2465; + long i2466; + long i2467; + long i2468; + long i2469; + long i2470; + long i2471; + long i2472; + long i2473; + long i2474; + long i2475; + long i2476; + long i2477; + long i2478; + long i2479; + long i2480; + long i2481; + long i2482; + long i2483; + long i2484; + long i2485; + long i2486; + long i2487; + long i2488; + long i2489; + long i2490; + long i2491; + long i2492; + long i2493; + long i2494; + long i2495; + long i2496; + long i2497; + long i2498; + long i2499; + long i2500; + long i2501; + long i2502; + long i2503; + long i2504; + long i2505; + long i2506; + long i2507; + long i2508; + long i2509; + long i2510; + long i2511; + long i2512; + long i2513; + long i2514; + long i2515; + long i2516; + long i2517; + long i2518; + long i2519; + long i2520; + long i2521; + long i2522; + long i2523; + long i2524; + long i2525; + long i2526; + long i2527; + long i2528; + long i2529; + long i2530; + long i2531; + long i2532; + long i2533; + long i2534; + long i2535; + long i2536; + long i2537; + long i2538; + long i2539; + long i2540; + long i2541; + long i2542; + long i2543; + long i2544; + long i2545; + long i2546; + long i2547; + long i2548; + long i2549; + long i2550; + long i2551; + long i2552; + long i2553; + long i2554; + long i2555; + long i2556; + long i2557; + long i2558; + long i2559; + long i2560; + long i2561; + long i2562; + long i2563; + long i2564; + long i2565; + long i2566; + long i2567; + long i2568; + long i2569; + long i2570; + long i2571; + long i2572; + long i2573; + long i2574; + long i2575; + long i2576; + long i2577; + long i2578; + long i2579; + long i2580; + long i2581; + long i2582; + long i2583; + long i2584; + long i2585; + long i2586; + long i2587; + long i2588; + long i2589; + long i2590; + long i2591; + long i2592; + long i2593; + long i2594; + long i2595; + long i2596; + long i2597; + long i2598; + long i2599; + long i2600; + long i2601; + long i2602; + long i2603; + long i2604; + long i2605; + long i2606; + long i2607; + long i2608; + long i2609; + long i2610; + long i2611; + long i2612; + long i2613; + long i2614; + long i2615; + long i2616; + long i2617; + long i2618; + long i2619; + long i2620; + long i2621; + long i2622; + long i2623; + long i2624; + long i2625; + long i2626; + long i2627; + long i2628; + long i2629; + long i2630; + long i2631; + long i2632; + long i2633; + long i2634; + long i2635; + long i2636; + long i2637; + long i2638; + long i2639; + long i2640; + long i2641; + long i2642; + long i2643; + long i2644; + long i2645; + long i2646; + long i2647; + long i2648; + long i2649; + long i2650; + long i2651; + long i2652; + long i2653; + long i2654; + long i2655; + long i2656; + long i2657; + long i2658; + long i2659; + long i2660; + long i2661; + long i2662; + long i2663; + long i2664; + long i2665; + long i2666; + long i2667; + long i2668; + long i2669; + long i2670; + long i2671; + long i2672; + long i2673; + long i2674; + long i2675; + long i2676; + long i2677; + long i2678; + long i2679; + long i2680; + long i2681; + long i2682; + long i2683; + long i2684; + long i2685; + long i2686; + long i2687; + long i2688; + long i2689; + long i2690; + long i2691; + long i2692; + long i2693; + long i2694; + long i2695; + long i2696; + long i2697; + long i2698; + long i2699; + long i2700; + long i2701; + long i2702; + long i2703; + long i2704; + long i2705; + long i2706; + long i2707; + long i2708; + long i2709; + long i2710; + long i2711; + long i2712; + long i2713; + long i2714; + long i2715; + long i2716; + long i2717; + long i2718; + long i2719; + long i2720; + long i2721; + long i2722; + long i2723; + long i2724; + long i2725; + long i2726; + long i2727; + long i2728; + long i2729; + long i2730; + long i2731; + long i2732; + long i2733; + long i2734; + long i2735; + long i2736; + long i2737; + long i2738; + long i2739; + long i2740; + long i2741; + long i2742; + long i2743; + long i2744; + long i2745; + long i2746; + long i2747; + long i2748; + long i2749; + long i2750; + long i2751; + long i2752; + long i2753; + long i2754; + long i2755; + long i2756; + long i2757; + long i2758; + long i2759; + long i2760; + long i2761; + long i2762; + long i2763; + long i2764; + long i2765; + long i2766; + long i2767; + long i2768; + long i2769; + long i2770; + long i2771; + long i2772; + long i2773; + long i2774; + long i2775; + long i2776; + long i2777; + long i2778; + long i2779; + long i2780; + long i2781; + long i2782; + long i2783; + long i2784; + long i2785; + long i2786; + long i2787; + long i2788; + long i2789; + long i2790; + long i2791; + long i2792; + long i2793; + long i2794; + long i2795; + long i2796; + long i2797; + long i2798; + long i2799; + long i2800; + long i2801; + long i2802; + long i2803; + long i2804; + long i2805; + long i2806; + long i2807; + long i2808; + long i2809; + long i2810; + long i2811; + long i2812; + long i2813; + long i2814; + long i2815; + long i2816; + long i2817; + long i2818; + long i2819; + long i2820; + long i2821; + long i2822; + long i2823; + long i2824; + long i2825; + long i2826; + long i2827; + long i2828; + long i2829; + long i2830; + long i2831; + long i2832; + long i2833; + long i2834; + long i2835; + long i2836; + long i2837; + long i2838; + long i2839; + long i2840; + long i2841; + long i2842; + long i2843; + long i2844; + long i2845; + long i2846; + long i2847; + long i2848; + long i2849; + long i2850; + long i2851; + long i2852; + long i2853; + long i2854; + long i2855; + long i2856; + long i2857; + long i2858; + long i2859; + long i2860; + long i2861; + long i2862; + long i2863; + long i2864; + long i2865; + long i2866; + long i2867; + long i2868; + long i2869; + long i2870; + long i2871; + long i2872; + long i2873; + long i2874; + long i2875; + long i2876; + long i2877; + long i2878; + long i2879; + long i2880; + long i2881; + long i2882; + long i2883; + long i2884; + long i2885; + long i2886; + long i2887; + long i2888; + long i2889; + long i2890; + long i2891; + long i2892; + long i2893; + long i2894; + long i2895; + long i2896; + long i2897; + long i2898; + long i2899; + long i2900; + long i2901; + long i2902; + long i2903; + long i2904; + long i2905; + long i2906; + long i2907; + long i2908; + long i2909; + long i2910; + long i2911; + long i2912; + long i2913; + long i2914; + long i2915; + long i2916; + long i2917; + long i2918; + long i2919; + long i2920; + long i2921; + long i2922; + long i2923; + long i2924; + long i2925; + long i2926; + long i2927; + long i2928; + long i2929; + long i2930; + long i2931; + long i2932; + long i2933; + long i2934; + long i2935; + long i2936; + long i2937; + long i2938; + long i2939; + long i2940; + long i2941; + long i2942; + long i2943; + long i2944; + long i2945; + long i2946; + long i2947; + long i2948; + long i2949; + long i2950; + long i2951; + long i2952; + long i2953; + long i2954; + long i2955; + long i2956; + long i2957; + long i2958; + long i2959; + long i2960; + long i2961; + long i2962; + long i2963; + long i2964; + long i2965; + long i2966; + long i2967; + long i2968; + long i2969; + long i2970; + long i2971; + long i2972; + long i2973; + long i2974; + long i2975; + long i2976; + long i2977; + long i2978; + long i2979; + long i2980; + long i2981; + long i2982; + long i2983; + long i2984; + long i2985; + long i2986; + long i2987; + long i2988; + long i2989; + long i2990; + long i2991; + long i2992; + long i2993; + long i2994; + long i2995; + long i2996; + long i2997; + long i2998; + long i2999; + long i3000; + long i3001; + long i3002; + long i3003; + long i3004; + long i3005; + long i3006; + long i3007; + long i3008; + long i3009; + long i3010; + long i3011; + long i3012; + long i3013; + long i3014; + long i3015; + long i3016; + long i3017; + long i3018; + long i3019; + long i3020; + long i3021; + long i3022; + long i3023; + long i3024; + long i3025; + long i3026; + long i3027; + long i3028; + long i3029; + long i3030; + long i3031; + long i3032; + long i3033; + long i3034; + long i3035; + long i3036; + long i3037; + long i3038; + long i3039; + long i3040; + long i3041; + long i3042; + long i3043; + long i3044; + long i3045; + long i3046; + long i3047; + long i3048; + long i3049; + long i3050; + long i3051; + long i3052; + long i3053; + long i3054; + long i3055; + long i3056; + long i3057; + long i3058; + long i3059; + long i3060; + long i3061; + long i3062; + long i3063; + long i3064; + long i3065; + long i3066; + long i3067; + long i3068; + long i3069; + long i3070; + long i3071; + long i3072; + long i3073; + long i3074; + long i3075; + long i3076; + long i3077; + long i3078; + long i3079; + long i3080; + long i3081; + long i3082; + long i3083; + long i3084; + long i3085; + long i3086; + long i3087; + long i3088; + long i3089; + long i3090; + long i3091; + long i3092; + long i3093; + long i3094; + long i3095; + long i3096; + long i3097; + long i3098; + long i3099; + long i3100; + long i3101; + long i3102; + long i3103; + long i3104; + long i3105; + long i3106; + long i3107; + long i3108; + long i3109; + long i3110; + long i3111; + long i3112; + long i3113; + long i3114; + long i3115; + long i3116; + long i3117; + long i3118; + long i3119; + long i3120; + long i3121; + long i3122; + long i3123; + long i3124; + long i3125; + long i3126; + long i3127; + long i3128; + long i3129; + long i3130; + long i3131; + long i3132; + long i3133; + long i3134; + long i3135; + long i3136; + long i3137; + long i3138; + long i3139; + long i3140; + long i3141; + long i3142; + long i3143; + long i3144; + long i3145; + long i3146; + long i3147; + long i3148; + long i3149; + long i3150; + long i3151; + long i3152; + long i3153; + long i3154; + long i3155; + long i3156; + long i3157; + long i3158; + long i3159; + long i3160; + long i3161; + long i3162; + long i3163; + long i3164; + long i3165; + long i3166; + long i3167; + long i3168; + long i3169; + long i3170; + long i3171; + long i3172; + long i3173; + long i3174; + long i3175; + long i3176; + long i3177; + long i3178; + long i3179; + long i3180; + long i3181; + long i3182; + long i3183; + long i3184; + long i3185; + long i3186; + long i3187; + long i3188; + long i3189; + long i3190; + long i3191; + long i3192; + long i3193; + long i3194; + long i3195; + long i3196; + long i3197; + long i3198; + long i3199; + long i3200; + long i3201; + long i3202; + long i3203; + long i3204; + long i3205; + long i3206; + long i3207; + long i3208; + long i3209; + long i3210; + long i3211; + long i3212; + long i3213; + long i3214; + long i3215; + long i3216; + long i3217; + long i3218; + long i3219; + long i3220; + long i3221; + long i3222; + long i3223; + long i3224; + long i3225; + long i3226; + long i3227; + long i3228; + long i3229; + long i3230; + long i3231; + long i3232; + long i3233; + long i3234; + long i3235; + long i3236; + long i3237; + long i3238; + long i3239; + long i3240; + long i3241; + long i3242; + long i3243; + long i3244; + long i3245; + long i3246; + long i3247; + long i3248; + long i3249; + long i3250; + long i3251; + long i3252; + long i3253; + long i3254; + long i3255; + long i3256; + long i3257; + long i3258; + long i3259; + long i3260; + long i3261; + long i3262; + long i3263; + long i3264; + long i3265; + long i3266; + long i3267; + long i3268; + long i3269; + long i3270; + long i3271; + long i3272; + long i3273; + long i3274; + long i3275; + long i3276; + long i3277; + long i3278; + long i3279; + long i3280; + long i3281; + long i3282; + long i3283; + long i3284; + long i3285; + long i3286; + long i3287; + long i3288; + long i3289; + long i3290; + long i3291; + long i3292; + long i3293; + long i3294; + long i3295; + long i3296; + long i3297; + long i3298; + long i3299; + long i3300; + long i3301; + long i3302; + long i3303; + long i3304; + long i3305; + long i3306; + long i3307; + long i3308; + long i3309; + long i3310; + long i3311; + long i3312; + long i3313; + long i3314; + long i3315; + long i3316; + long i3317; + long i3318; + long i3319; + long i3320; + long i3321; + long i3322; + long i3323; + long i3324; + long i3325; + long i3326; + long i3327; + long i3328; + long i3329; + long i3330; + long i3331; + long i3332; + long i3333; + long i3334; + long i3335; + long i3336; + long i3337; + long i3338; + long i3339; + long i3340; + long i3341; + long i3342; + long i3343; + long i3344; + long i3345; + long i3346; + long i3347; + long i3348; + long i3349; + long i3350; + long i3351; + long i3352; + long i3353; + long i3354; + long i3355; + long i3356; + long i3357; + long i3358; + long i3359; + long i3360; + long i3361; + long i3362; + long i3363; + long i3364; + long i3365; + long i3366; + long i3367; + long i3368; + long i3369; + long i3370; + long i3371; + long i3372; + long i3373; + long i3374; + long i3375; + long i3376; + long i3377; + long i3378; + long i3379; + long i3380; + long i3381; + long i3382; + long i3383; + long i3384; + long i3385; + long i3386; + long i3387; + long i3388; + long i3389; + long i3390; + long i3391; + long i3392; + long i3393; + long i3394; + long i3395; + long i3396; + long i3397; + long i3398; + long i3399; + long i3400; + long i3401; + long i3402; + long i3403; + long i3404; + long i3405; + long i3406; + long i3407; + long i3408; + long i3409; + long i3410; + long i3411; + long i3412; + long i3413; + long i3414; + long i3415; + long i3416; + long i3417; + long i3418; + long i3419; + long i3420; + long i3421; + long i3422; + long i3423; + long i3424; + long i3425; + long i3426; + long i3427; + long i3428; + long i3429; + long i3430; + long i3431; + long i3432; + long i3433; + long i3434; + long i3435; + long i3436; + long i3437; + long i3438; + long i3439; + long i3440; + long i3441; + long i3442; + long i3443; + long i3444; + long i3445; + long i3446; + long i3447; + long i3448; + long i3449; + long i3450; + long i3451; + long i3452; + long i3453; + long i3454; + long i3455; + long i3456; + long i3457; + long i3458; + long i3459; + long i3460; + long i3461; + long i3462; + long i3463; + long i3464; + long i3465; + long i3466; + long i3467; + long i3468; + long i3469; + long i3470; + long i3471; + long i3472; + long i3473; + long i3474; + long i3475; + long i3476; + long i3477; + long i3478; + long i3479; + long i3480; + long i3481; + long i3482; + long i3483; + long i3484; + long i3485; + long i3486; + long i3487; + long i3488; + long i3489; + long i3490; + long i3491; + long i3492; + long i3493; + long i3494; + long i3495; + long i3496; + long i3497; + long i3498; + long i3499; + long i3500; + long i3501; + long i3502; + long i3503; + long i3504; + long i3505; + long i3506; + long i3507; + long i3508; + long i3509; + long i3510; + long i3511; + long i3512; + long i3513; + long i3514; + long i3515; + long i3516; + long i3517; + long i3518; + long i3519; + long i3520; + long i3521; + long i3522; + long i3523; + long i3524; + long i3525; + long i3526; + long i3527; + long i3528; + long i3529; + long i3530; + long i3531; + long i3532; + long i3533; + long i3534; + long i3535; + long i3536; + long i3537; + long i3538; + long i3539; + long i3540; + long i3541; + long i3542; + long i3543; + long i3544; + long i3545; + long i3546; + long i3547; + long i3548; + long i3549; + long i3550; + long i3551; + long i3552; + long i3553; + long i3554; + long i3555; + long i3556; + long i3557; + long i3558; + long i3559; + long i3560; + long i3561; + long i3562; + long i3563; + long i3564; + long i3565; + long i3566; + long i3567; + long i3568; + long i3569; + long i3570; + long i3571; + long i3572; + long i3573; + long i3574; + long i3575; + long i3576; + long i3577; + long i3578; + long i3579; + long i3580; + long i3581; + long i3582; + long i3583; + long i3584; + long i3585; + long i3586; + long i3587; + long i3588; + long i3589; + long i3590; + long i3591; + long i3592; + long i3593; + long i3594; + long i3595; + long i3596; + long i3597; + long i3598; + long i3599; + long i3600; + long i3601; + long i3602; + long i3603; + long i3604; + long i3605; + long i3606; + long i3607; + long i3608; + long i3609; + long i3610; + long i3611; + long i3612; + long i3613; + long i3614; + long i3615; + long i3616; + long i3617; + long i3618; + long i3619; + long i3620; + long i3621; + long i3622; + long i3623; + long i3624; + long i3625; + long i3626; + long i3627; + long i3628; + long i3629; + long i3630; + long i3631; + long i3632; + long i3633; + long i3634; + long i3635; + long i3636; + long i3637; + long i3638; + long i3639; + long i3640; + long i3641; + long i3642; + long i3643; + long i3644; + long i3645; + long i3646; + long i3647; + long i3648; + long i3649; + long i3650; + long i3651; + long i3652; + long i3653; + long i3654; + long i3655; + long i3656; + long i3657; + long i3658; + long i3659; + long i3660; + long i3661; + long i3662; + long i3663; + long i3664; + long i3665; + long i3666; + long i3667; + long i3668; + long i3669; + long i3670; + long i3671; + long i3672; + long i3673; + long i3674; + long i3675; + long i3676; + long i3677; + long i3678; + long i3679; + long i3680; + long i3681; + long i3682; + long i3683; + long i3684; + long i3685; + long i3686; + long i3687; + long i3688; + long i3689; + long i3690; + long i3691; + long i3692; + long i3693; + long i3694; + long i3695; + long i3696; + long i3697; + long i3698; + long i3699; + long i3700; + long i3701; + long i3702; + long i3703; + long i3704; + long i3705; + long i3706; + long i3707; + long i3708; + long i3709; + long i3710; + long i3711; + long i3712; + long i3713; + long i3714; + long i3715; + long i3716; + long i3717; + long i3718; + long i3719; + long i3720; + long i3721; + long i3722; + long i3723; + long i3724; + long i3725; + long i3726; + long i3727; + long i3728; + long i3729; + long i3730; + long i3731; + long i3732; + long i3733; + long i3734; + long i3735; + long i3736; + long i3737; + long i3738; + long i3739; + long i3740; + long i3741; + long i3742; + long i3743; + long i3744; + long i3745; + long i3746; + long i3747; + long i3748; + long i3749; + long i3750; + long i3751; + long i3752; + long i3753; + long i3754; + long i3755; + long i3756; + long i3757; + long i3758; + long i3759; + long i3760; + long i3761; + long i3762; + long i3763; + long i3764; + long i3765; + long i3766; + long i3767; + long i3768; + long i3769; + long i3770; + long i3771; + long i3772; + long i3773; + long i3774; + long i3775; + long i3776; + long i3777; + long i3778; + long i3779; + long i3780; + long i3781; + long i3782; + long i3783; + long i3784; + long i3785; + long i3786; + long i3787; + long i3788; + long i3789; + long i3790; + long i3791; + long i3792; + long i3793; + long i3794; + long i3795; + long i3796; + long i3797; + long i3798; + long i3799; + long i3800; + long i3801; + long i3802; + long i3803; + long i3804; + long i3805; + long i3806; + long i3807; + long i3808; + long i3809; + long i3810; + long i3811; + long i3812; + long i3813; + long i3814; + long i3815; + long i3816; + long i3817; + long i3818; + long i3819; + long i3820; + long i3821; + long i3822; + long i3823; + long i3824; + long i3825; + long i3826; + long i3827; + long i3828; + long i3829; + long i3830; + long i3831; + long i3832; + long i3833; + long i3834; + long i3835; + long i3836; + long i3837; + long i3838; + long i3839; + long i3840; + long i3841; + long i3842; + long i3843; + long i3844; + long i3845; + long i3846; + long i3847; + long i3848; + long i3849; + long i3850; + long i3851; + long i3852; + long i3853; + long i3854; + long i3855; + long i3856; + long i3857; + long i3858; + long i3859; + long i3860; + long i3861; + long i3862; + long i3863; + long i3864; + long i3865; + long i3866; + long i3867; + long i3868; + long i3869; + long i3870; + long i3871; + long i3872; + long i3873; + long i3874; + long i3875; + long i3876; + long i3877; + long i3878; + long i3879; + long i3880; + long i3881; + long i3882; + long i3883; + long i3884; + long i3885; + long i3886; + long i3887; + long i3888; + long i3889; + long i3890; + long i3891; + long i3892; + long i3893; + long i3894; + long i3895; + long i3896; + long i3897; + long i3898; + long i3899; + long i3900; + long i3901; + long i3902; + long i3903; + long i3904; + long i3905; + long i3906; + long i3907; + long i3908; + long i3909; + long i3910; + long i3911; + long i3912; + long i3913; + long i3914; + long i3915; + long i3916; + long i3917; + long i3918; + long i3919; + long i3920; + long i3921; + long i3922; + long i3923; + long i3924; + long i3925; + long i3926; + long i3927; + long i3928; + long i3929; + long i3930; + long i3931; + long i3932; + long i3933; + long i3934; + long i3935; + long i3936; + long i3937; + long i3938; + long i3939; + long i3940; + long i3941; + long i3942; + long i3943; + long i3944; + long i3945; + long i3946; + long i3947; + long i3948; + long i3949; + long i3950; + long i3951; + long i3952; + long i3953; + long i3954; + long i3955; + long i3956; + long i3957; + long i3958; + long i3959; + long i3960; + long i3961; + long i3962; + long i3963; + long i3964; + long i3965; + long i3966; + long i3967; + long i3968; + long i3969; + long i3970; + long i3971; + long i3972; + long i3973; + long i3974; + long i3975; + long i3976; + long i3977; + long i3978; + long i3979; + long i3980; + long i3981; + long i3982; + long i3983; + long i3984; + long i3985; + long i3986; + long i3987; + long i3988; + long i3989; + long i3990; + long i3991; + long i3992; + long i3993; + long i3994; + long i3995; + long i3996; + long i3997; + long i3998; + long i3999; + long i4000; + long i4001; + long i4002; + long i4003; + long i4004; + long i4005; + long i4006; + long i4007; + long i4008; + long i4009; + long i4010; + long i4011; + long i4012; + long i4013; + long i4014; + long i4015; + long i4016; + long i4017; + long i4018; + long i4019; + long i4020; + long i4021; + long i4022; + long i4023; + long i4024; + long i4025; + long i4026; + long i4027; + long i4028; + long i4029; + long i4030; + long i4031; + long i4032; + long i4033; + long i4034; + long i4035; + long i4036; + long i4037; + long i4038; + long i4039; + long i4040; + long i4041; + long i4042; + long i4043; + long i4044; + long i4045; + long i4046; + long i4047; + long i4048; + long i4049; + long i4050; + long i4051; + long i4052; + long i4053; + long i4054; + long i4055; + long i4056; + long i4057; + long i4058; + long i4059; + long i4060; + long i4061; + long i4062; + long i4063; + long i4064; + long i4065; + long i4066; + long i4067; + long i4068; + long i4069; + long i4070; + long i4071; + long i4072; + long i4073; + long i4074; + long i4075; + long i4076; + long i4077; + long i4078; + long i4079; + long i4080; + long i4081; + long i4082; + long i4083; + long i4084; + long i4085; + long i4086; + long i4087; + long i4088; + long i4089; + long i4090; + long i4091; + long i4092; + long i4093; + long i4094; + long i4095; + long i4096; + long i4097; + long i4098; + long i4099; + long i4100; + long i4101; + long i4102; + long i4103; + long i4104; + long i4105; + long i4106; + long i4107; + long i4108; + long i4109; + long i4110; + long i4111; + long i4112; + long i4113; + long i4114; + long i4115; + long i4116; + long i4117; + long i4118; + long i4119; + long i4120; + long i4121; + long i4122; + long i4123; + long i4124; + long i4125; + long i4126; + long i4127; + long i4128; + long i4129; + long i4130; + long i4131; + long i4132; + long i4133; + long i4134; + long i4135; + long i4136; + long i4137; + long i4138; + long i4139; + long i4140; + long i4141; + long i4142; + long i4143; + long i4144; + long i4145; + long i4146; + long i4147; + long i4148; + long i4149; + long i4150; + long i4151; + long i4152; + long i4153; + long i4154; + long i4155; + long i4156; + long i4157; + long i4158; + long i4159; + long i4160; + long i4161; + long i4162; + long i4163; + long i4164; + long i4165; + long i4166; + long i4167; + long i4168; + long i4169; + long i4170; + long i4171; + long i4172; + long i4173; + long i4174; + long i4175; + long i4176; + long i4177; + long i4178; + long i4179; + long i4180; + long i4181; + long i4182; + long i4183; + long i4184; + long i4185; + long i4186; + long i4187; + long i4188; + long i4189; + long i4190; + long i4191; + long i4192; + long i4193; + long i4194; + long i4195; + long i4196; + long i4197; + long i4198; + long i4199; + long i4200; + long i4201; + long i4202; + long i4203; + long i4204; + long i4205; + long i4206; + long i4207; + long i4208; + long i4209; + long i4210; + long i4211; + long i4212; + long i4213; + long i4214; + long i4215; + long i4216; + long i4217; + long i4218; + long i4219; + long i4220; + long i4221; + long i4222; + long i4223; + long i4224; + long i4225; + long i4226; + long i4227; + long i4228; + long i4229; + long i4230; + long i4231; + long i4232; + long i4233; + long i4234; + long i4235; + long i4236; + long i4237; + long i4238; + long i4239; + long i4240; + long i4241; + long i4242; + long i4243; + long i4244; + long i4245; + long i4246; + long i4247; + long i4248; + long i4249; + long i4250; + long i4251; + long i4252; + long i4253; + long i4254; + long i4255; + long i4256; + long i4257; + long i4258; + long i4259; + long i4260; + long i4261; + long i4262; + long i4263; + long i4264; + long i4265; + long i4266; + long i4267; + long i4268; + long i4269; + long i4270; + long i4271; + long i4272; + long i4273; + long i4274; + long i4275; + long i4276; + long i4277; + long i4278; + long i4279; + long i4280; + long i4281; + long i4282; + long i4283; + long i4284; + long i4285; + long i4286; + long i4287; + long i4288; + long i4289; + long i4290; + long i4291; + long i4292; + long i4293; + long i4294; + long i4295; + long i4296; + long i4297; + long i4298; + long i4299; + long i4300; + long i4301; + long i4302; + long i4303; + long i4304; + long i4305; + long i4306; + long i4307; + long i4308; + long i4309; + long i4310; + long i4311; + long i4312; + long i4313; + long i4314; + long i4315; + long i4316; + long i4317; + long i4318; + long i4319; + long i4320; + long i4321; + long i4322; + long i4323; + long i4324; + long i4325; + long i4326; + long i4327; + long i4328; + long i4329; + long i4330; + long i4331; + long i4332; + long i4333; + long i4334; + long i4335; + long i4336; + long i4337; + long i4338; + long i4339; + long i4340; + long i4341; + long i4342; + long i4343; + long i4344; + long i4345; + long i4346; + long i4347; + long i4348; + long i4349; + long i4350; + long i4351; + long i4352; + long i4353; + long i4354; + long i4355; + long i4356; + long i4357; + long i4358; + long i4359; + long i4360; + long i4361; + long i4362; + long i4363; + long i4364; + long i4365; + long i4366; + long i4367; + long i4368; + long i4369; + long i4370; + long i4371; + long i4372; + long i4373; + long i4374; + long i4375; + long i4376; + long i4377; + long i4378; + long i4379; + long i4380; + long i4381; + long i4382; + long i4383; + long i4384; + long i4385; + long i4386; + long i4387; + long i4388; + long i4389; + long i4390; + long i4391; + long i4392; + long i4393; + long i4394; + long i4395; + long i4396; + long i4397; + long i4398; + long i4399; + long i4400; + long i4401; + long i4402; + long i4403; + long i4404; + long i4405; + long i4406; + long i4407; + long i4408; + long i4409; + long i4410; + long i4411; + long i4412; + long i4413; + long i4414; + long i4415; + long i4416; + long i4417; + long i4418; + long i4419; + long i4420; + long i4421; + long i4422; + long i4423; + long i4424; + long i4425; + long i4426; + long i4427; + long i4428; + long i4429; + long i4430; + long i4431; + long i4432; + long i4433; + long i4434; + long i4435; + long i4436; + long i4437; + long i4438; + long i4439; + long i4440; + long i4441; + long i4442; + long i4443; + long i4444; + long i4445; + long i4446; + long i4447; + long i4448; + long i4449; + long i4450; + long i4451; + long i4452; + long i4453; + long i4454; + long i4455; + long i4456; + long i4457; + long i4458; + long i4459; + long i4460; + long i4461; + long i4462; + long i4463; + long i4464; + long i4465; + long i4466; + long i4467; + long i4468; + long i4469; + long i4470; + long i4471; + long i4472; + long i4473; + long i4474; + long i4475; + long i4476; + long i4477; + long i4478; + long i4479; + long i4480; + long i4481; + long i4482; + long i4483; + long i4484; + long i4485; + long i4486; + long i4487; + long i4488; + long i4489; + long i4490; + long i4491; + long i4492; + long i4493; + long i4494; + long i4495; + long i4496; + long i4497; + long i4498; + long i4499; + long i4500; + long i4501; + long i4502; + long i4503; + long i4504; + long i4505; + long i4506; + long i4507; + long i4508; + long i4509; + long i4510; + long i4511; + long i4512; + long i4513; + long i4514; + long i4515; + long i4516; + long i4517; + long i4518; + long i4519; + long i4520; + long i4521; + long i4522; + long i4523; + long i4524; + long i4525; + long i4526; + long i4527; + long i4528; + long i4529; + long i4530; + long i4531; + long i4532; + long i4533; + long i4534; + long i4535; + long i4536; + long i4537; + long i4538; + long i4539; + long i4540; + long i4541; + long i4542; + long i4543; + long i4544; + long i4545; + long i4546; + long i4547; + long i4548; + long i4549; + long i4550; + long i4551; + long i4552; + long i4553; + long i4554; + long i4555; + long i4556; + long i4557; + long i4558; + long i4559; + long i4560; + long i4561; + long i4562; + long i4563; + long i4564; + long i4565; + long i4566; + long i4567; + long i4568; + long i4569; + long i4570; + long i4571; + long i4572; + long i4573; + long i4574; + long i4575; + long i4576; + long i4577; + long i4578; + long i4579; + long i4580; + long i4581; + long i4582; + long i4583; + long i4584; + long i4585; + long i4586; + long i4587; + long i4588; + long i4589; + long i4590; + long i4591; + long i4592; + long i4593; + long i4594; + long i4595; + long i4596; + long i4597; + long i4598; + long i4599; + long i4600; + long i4601; + long i4602; + long i4603; + long i4604; + long i4605; + long i4606; + long i4607; + long i4608; + long i4609; + long i4610; + long i4611; + long i4612; + long i4613; + long i4614; + long i4615; + long i4616; + long i4617; + long i4618; + long i4619; + long i4620; + long i4621; + long i4622; + long i4623; + long i4624; + long i4625; + long i4626; + long i4627; + long i4628; + long i4629; + long i4630; + long i4631; + long i4632; + long i4633; + long i4634; + long i4635; + long i4636; + long i4637; + long i4638; + long i4639; + long i4640; + long i4641; + long i4642; + long i4643; + long i4644; + long i4645; + long i4646; + long i4647; + long i4648; + long i4649; + long i4650; + long i4651; + long i4652; + long i4653; + long i4654; + long i4655; + long i4656; + long i4657; + long i4658; + long i4659; + long i4660; + long i4661; + long i4662; + long i4663; + long i4664; + long i4665; + long i4666; + long i4667; + long i4668; + long i4669; + long i4670; + long i4671; + long i4672; + long i4673; + long i4674; + long i4675; + long i4676; + long i4677; + long i4678; + long i4679; + long i4680; + long i4681; + long i4682; + long i4683; + long i4684; + long i4685; + long i4686; + long i4687; + long i4688; + long i4689; + long i4690; + long i4691; + long i4692; + long i4693; + long i4694; + long i4695; + long i4696; + long i4697; + long i4698; + long i4699; + long i4700; + long i4701; + long i4702; + long i4703; + long i4704; + long i4705; + long i4706; + long i4707; + long i4708; + long i4709; + long i4710; + long i4711; + long i4712; + long i4713; + long i4714; + long i4715; + long i4716; + long i4717; + long i4718; + long i4719; + long i4720; + long i4721; + long i4722; + long i4723; + long i4724; + long i4725; + long i4726; + long i4727; + long i4728; + long i4729; + long i4730; + long i4731; + long i4732; + long i4733; + long i4734; + long i4735; + long i4736; + long i4737; + long i4738; + long i4739; + long i4740; + long i4741; + long i4742; + long i4743; + long i4744; + long i4745; + long i4746; + long i4747; + long i4748; + long i4749; + long i4750; + long i4751; + long i4752; + long i4753; + long i4754; + long i4755; + long i4756; + long i4757; + long i4758; + long i4759; + long i4760; + long i4761; + long i4762; + long i4763; + long i4764; + long i4765; + long i4766; + long i4767; + long i4768; + long i4769; + long i4770; + long i4771; + long i4772; + long i4773; + long i4774; + long i4775; + long i4776; + long i4777; + long i4778; + long i4779; + long i4780; + long i4781; + long i4782; + long i4783; + long i4784; + long i4785; + long i4786; + long i4787; + long i4788; + long i4789; + long i4790; + long i4791; + long i4792; + long i4793; + long i4794; + long i4795; + long i4796; + long i4797; + long i4798; + long i4799; + long i4800; + long i4801; + long i4802; + long i4803; + long i4804; + long i4805; + long i4806; + long i4807; + long i4808; + long i4809; + long i4810; + long i4811; + long i4812; + long i4813; + long i4814; + long i4815; + long i4816; + long i4817; + long i4818; + long i4819; + long i4820; + long i4821; + long i4822; + long i4823; + long i4824; + long i4825; + long i4826; + long i4827; + long i4828; + long i4829; + long i4830; + long i4831; + long i4832; + long i4833; + long i4834; + long i4835; + long i4836; + long i4837; + long i4838; + long i4839; + long i4840; + long i4841; + long i4842; + long i4843; + long i4844; + long i4845; + long i4846; + long i4847; + long i4848; + long i4849; + long i4850; + long i4851; + long i4852; + long i4853; + long i4854; + long i4855; + long i4856; + long i4857; + long i4858; + long i4859; + long i4860; + long i4861; + long i4862; + long i4863; + long i4864; + long i4865; + long i4866; + long i4867; + long i4868; + long i4869; + long i4870; + long i4871; + long i4872; + long i4873; + long i4874; + long i4875; + long i4876; + long i4877; + long i4878; + long i4879; + long i4880; + long i4881; + long i4882; + long i4883; + long i4884; + long i4885; + long i4886; + long i4887; + long i4888; + long i4889; + long i4890; + long i4891; + long i4892; + long i4893; + long i4894; + long i4895; + long i4896; + long i4897; + long i4898; + long i4899; + long i4900; + long i4901; + long i4902; + long i4903; + long i4904; + long i4905; + long i4906; + long i4907; + long i4908; + long i4909; + long i4910; + long i4911; + long i4912; + long i4913; + long i4914; + long i4915; + long i4916; + long i4917; + long i4918; + long i4919; + long i4920; + long i4921; + long i4922; + long i4923; + long i4924; + long i4925; + long i4926; + long i4927; + long i4928; + long i4929; + long i4930; + long i4931; + long i4932; + long i4933; + long i4934; + long i4935; + long i4936; + long i4937; + long i4938; + long i4939; + long i4940; + long i4941; + long i4942; + long i4943; + long i4944; + long i4945; + long i4946; + long i4947; + long i4948; + long i4949; + long i4950; + long i4951; + long i4952; + long i4953; + long i4954; + long i4955; + long i4956; + long i4957; + long i4958; + long i4959; + long i4960; + long i4961; + long i4962; + long i4963; + long i4964; + long i4965; + long i4966; + long i4967; + long i4968; + long i4969; + long i4970; + long i4971; + long i4972; + long i4973; + long i4974; + long i4975; + long i4976; + long i4977; + long i4978; + long i4979; + long i4980; + long i4981; + long i4982; + long i4983; + long i4984; + long i4985; + long i4986; + long i4987; + long i4988; + long i4989; + long i4990; + long i4991; + long i4992; + long i4993; + long i4994; + long i4995; + long i4996; + long i4997; + long i4998; + long i4999; + long i5000; + long i5001; + long i5002; + long i5003; + long i5004; + long i5005; + long i5006; + long i5007; + long i5008; + long i5009; + long i5010; + long i5011; + long i5012; + long i5013; + long i5014; + long i5015; + long i5016; + long i5017; + long i5018; + long i5019; + long i5020; + long i5021; + long i5022; + long i5023; + long i5024; + long i5025; + long i5026; + long i5027; + long i5028; + long i5029; + long i5030; + long i5031; + long i5032; + long i5033; + long i5034; + long i5035; + long i5036; + long i5037; + long i5038; + long i5039; + long i5040; + long i5041; + long i5042; + long i5043; + long i5044; + long i5045; + long i5046; + long i5047; + long i5048; + long i5049; + long i5050; + long i5051; + long i5052; + long i5053; + long i5054; + long i5055; + long i5056; + long i5057; + long i5058; + long i5059; + long i5060; + long i5061; + long i5062; + long i5063; + long i5064; + long i5065; + long i5066; + long i5067; + long i5068; + long i5069; + long i5070; + long i5071; + long i5072; + long i5073; + long i5074; + long i5075; + long i5076; + long i5077; + long i5078; + long i5079; + long i5080; + long i5081; + long i5082; + long i5083; + long i5084; + long i5085; + long i5086; + long i5087; + long i5088; + long i5089; + long i5090; + long i5091; + long i5092; + long i5093; + long i5094; + long i5095; + long i5096; + long i5097; + long i5098; + long i5099; + long i5100; + long i5101; + long i5102; + long i5103; + long i5104; + long i5105; + long i5106; + long i5107; + long i5108; + long i5109; + long i5110; + long i5111; + long i5112; + long i5113; + long i5114; + long i5115; + long i5116; + long i5117; + long i5118; + long i5119; + long i5120; + long i5121; + long i5122; + long i5123; + long i5124; + long i5125; + long i5126; + long i5127; + long i5128; + long i5129; + long i5130; + long i5131; + long i5132; + long i5133; + long i5134; + long i5135; + long i5136; + long i5137; + long i5138; + long i5139; + long i5140; + long i5141; + long i5142; + long i5143; + long i5144; + long i5145; + long i5146; + long i5147; + long i5148; + long i5149; + long i5150; + long i5151; + long i5152; + long i5153; + long i5154; + long i5155; + long i5156; + long i5157; + long i5158; + long i5159; + long i5160; + long i5161; + long i5162; + long i5163; + long i5164; + long i5165; + long i5166; + long i5167; + long i5168; + long i5169; + long i5170; + long i5171; + long i5172; + long i5173; + long i5174; + long i5175; + long i5176; + long i5177; + long i5178; + long i5179; + long i5180; + long i5181; + long i5182; + long i5183; + long i5184; + long i5185; + long i5186; + long i5187; + long i5188; + long i5189; + long i5190; + long i5191; + long i5192; + long i5193; + long i5194; + long i5195; + long i5196; + long i5197; + long i5198; + long i5199; + long i5200; + long i5201; + long i5202; + long i5203; + long i5204; + long i5205; + long i5206; + long i5207; + long i5208; + long i5209; + long i5210; + long i5211; + long i5212; + long i5213; + long i5214; + long i5215; + long i5216; + long i5217; + long i5218; + long i5219; + long i5220; + long i5221; + long i5222; + long i5223; + long i5224; + long i5225; + long i5226; + long i5227; + long i5228; + long i5229; + long i5230; + long i5231; + long i5232; + long i5233; + long i5234; + long i5235; + long i5236; + long i5237; + long i5238; + long i5239; + long i5240; + long i5241; + long i5242; + long i5243; + long i5244; + long i5245; + long i5246; + long i5247; + long i5248; + long i5249; + long i5250; + long i5251; + long i5252; + long i5253; + long i5254; + long i5255; + long i5256; + long i5257; + long i5258; + long i5259; + long i5260; + long i5261; + long i5262; + long i5263; + long i5264; + long i5265; + long i5266; + long i5267; + long i5268; + long i5269; + long i5270; + long i5271; + long i5272; + long i5273; + long i5274; + long i5275; + long i5276; + long i5277; + long i5278; + long i5279; + long i5280; + long i5281; + long i5282; + long i5283; + long i5284; + long i5285; + long i5286; + long i5287; + long i5288; + long i5289; + long i5290; + long i5291; + long i5292; + long i5293; + long i5294; + long i5295; + long i5296; + long i5297; + long i5298; + long i5299; + long i5300; + long i5301; + long i5302; + long i5303; + long i5304; + long i5305; + long i5306; + long i5307; + long i5308; + long i5309; + long i5310; + long i5311; + long i5312; + long i5313; + long i5314; + long i5315; + long i5316; + long i5317; + long i5318; + long i5319; + long i5320; + long i5321; + long i5322; + long i5323; + long i5324; + long i5325; + long i5326; + long i5327; + long i5328; + long i5329; + long i5330; + long i5331; + long i5332; + long i5333; + long i5334; + long i5335; + long i5336; + long i5337; + long i5338; + long i5339; + long i5340; + long i5341; + long i5342; + long i5343; + long i5344; + long i5345; + long i5346; + long i5347; + long i5348; + long i5349; + long i5350; + long i5351; + long i5352; + long i5353; + long i5354; + long i5355; + long i5356; + long i5357; + long i5358; + long i5359; + long i5360; + long i5361; + long i5362; + long i5363; + long i5364; + long i5365; + long i5366; + long i5367; + long i5368; + long i5369; + long i5370; + long i5371; + long i5372; + long i5373; + long i5374; + long i5375; + long i5376; + long i5377; + long i5378; + long i5379; + long i5380; + long i5381; + long i5382; + long i5383; + long i5384; + long i5385; + long i5386; + long i5387; + long i5388; + long i5389; + long i5390; + long i5391; + long i5392; + long i5393; + long i5394; + long i5395; + long i5396; + long i5397; + long i5398; + long i5399; + long i5400; + long i5401; + long i5402; + long i5403; + long i5404; + long i5405; + long i5406; + long i5407; + long i5408; + long i5409; + long i5410; + long i5411; + long i5412; + long i5413; + long i5414; + long i5415; + long i5416; + long i5417; + long i5418; + long i5419; + long i5420; + long i5421; + long i5422; + long i5423; + long i5424; + long i5425; + long i5426; + long i5427; + long i5428; + long i5429; + long i5430; + long i5431; + long i5432; + long i5433; + long i5434; + long i5435; + long i5436; + long i5437; + long i5438; + long i5439; + long i5440; + long i5441; + long i5442; + long i5443; + long i5444; + long i5445; + long i5446; + long i5447; + long i5448; + long i5449; + long i5450; + long i5451; + long i5452; + long i5453; + long i5454; + long i5455; + long i5456; + long i5457; + long i5458; + long i5459; + long i5460; + long i5461; + long i5462; + long i5463; + long i5464; + long i5465; + long i5466; + long i5467; + long i5468; + long i5469; + long i5470; + long i5471; + long i5472; + long i5473; + long i5474; + long i5475; + long i5476; + long i5477; + long i5478; + long i5479; + long i5480; + long i5481; + long i5482; + long i5483; + long i5484; + long i5485; + long i5486; + long i5487; + long i5488; + long i5489; + long i5490; + long i5491; + long i5492; + long i5493; + long i5494; + long i5495; + long i5496; + long i5497; + long i5498; + long i5499; + long i5500; + long i5501; + long i5502; + long i5503; + long i5504; + long i5505; + long i5506; + long i5507; + long i5508; + long i5509; + long i5510; + long i5511; + long i5512; + long i5513; + long i5514; + long i5515; + long i5516; + long i5517; + long i5518; + long i5519; + long i5520; + long i5521; + long i5522; + long i5523; + long i5524; + long i5525; + long i5526; + long i5527; + long i5528; + long i5529; + long i5530; + long i5531; + long i5532; + long i5533; + long i5534; + long i5535; + long i5536; + long i5537; + long i5538; + long i5539; + long i5540; + long i5541; + long i5542; + long i5543; + long i5544; + long i5545; + long i5546; + long i5547; + long i5548; + long i5549; + long i5550; + long i5551; + long i5552; + long i5553; + long i5554; + long i5555; + long i5556; + long i5557; + long i5558; + long i5559; + long i5560; + long i5561; + long i5562; + long i5563; + long i5564; + long i5565; + long i5566; + long i5567; + long i5568; + long i5569; + long i5570; + long i5571; + long i5572; + long i5573; + long i5574; + long i5575; + long i5576; + long i5577; + long i5578; + long i5579; + long i5580; + long i5581; + long i5582; + long i5583; + long i5584; + long i5585; + long i5586; + long i5587; + long i5588; + long i5589; + long i5590; + long i5591; + long i5592; + long i5593; + long i5594; + long i5595; + long i5596; + long i5597; + long i5598; + long i5599; + long i5600; + long i5601; + long i5602; + long i5603; + long i5604; + long i5605; + long i5606; + long i5607; + long i5608; + long i5609; + long i5610; + long i5611; + long i5612; + long i5613; + long i5614; + long i5615; + long i5616; + long i5617; + long i5618; + long i5619; + long i5620; + long i5621; + long i5622; + long i5623; + long i5624; + long i5625; + long i5626; + long i5627; + long i5628; + long i5629; + long i5630; + long i5631; + long i5632; + long i5633; + long i5634; + long i5635; + long i5636; + long i5637; + long i5638; + long i5639; + long i5640; + long i5641; + long i5642; + long i5643; + long i5644; + long i5645; + long i5646; + long i5647; + long i5648; + long i5649; + long i5650; + long i5651; + long i5652; + long i5653; + long i5654; + long i5655; + long i5656; + long i5657; + long i5658; + long i5659; + long i5660; + long i5661; + long i5662; + long i5663; + long i5664; + long i5665; + long i5666; + long i5667; + long i5668; + long i5669; + long i5670; + long i5671; + long i5672; + long i5673; + long i5674; + long i5675; + long i5676; + long i5677; + long i5678; + long i5679; + long i5680; + long i5681; + long i5682; + long i5683; + long i5684; + long i5685; + long i5686; + long i5687; + long i5688; + long i5689; + long i5690; + long i5691; + long i5692; + long i5693; + long i5694; + long i5695; + long i5696; + long i5697; + long i5698; + long i5699; + long i5700; + long i5701; + long i5702; + long i5703; + long i5704; + long i5705; + long i5706; + long i5707; + long i5708; + long i5709; + long i5710; + long i5711; + long i5712; + long i5713; + long i5714; + long i5715; + long i5716; + long i5717; + long i5718; + long i5719; + long i5720; + long i5721; + long i5722; + long i5723; + long i5724; + long i5725; + long i5726; + long i5727; + long i5728; + long i5729; + long i5730; + long i5731; + long i5732; + long i5733; + long i5734; + long i5735; + long i5736; + long i5737; + long i5738; + long i5739; + long i5740; + long i5741; + long i5742; + long i5743; + long i5744; + long i5745; + long i5746; + long i5747; + long i5748; + long i5749; + long i5750; + long i5751; + long i5752; + long i5753; + long i5754; + long i5755; + long i5756; + long i5757; + long i5758; + long i5759; + long i5760; + long i5761; + long i5762; + long i5763; + long i5764; + long i5765; + long i5766; + long i5767; + long i5768; + long i5769; + long i5770; + long i5771; + long i5772; + long i5773; + long i5774; + long i5775; + long i5776; + long i5777; + long i5778; + long i5779; + long i5780; + long i5781; + long i5782; + long i5783; + long i5784; + long i5785; + long i5786; + long i5787; + long i5788; + long i5789; + long i5790; + long i5791; + long i5792; + long i5793; + long i5794; + long i5795; + long i5796; + long i5797; + long i5798; + long i5799; + long i5800; + long i5801; + long i5802; + long i5803; + long i5804; + long i5805; + long i5806; + long i5807; + long i5808; + long i5809; + long i5810; + long i5811; + long i5812; + long i5813; + long i5814; + long i5815; + long i5816; + long i5817; + long i5818; + long i5819; + long i5820; + long i5821; + long i5822; + long i5823; + long i5824; + long i5825; + long i5826; + long i5827; + long i5828; + long i5829; + long i5830; + long i5831; + long i5832; + long i5833; + long i5834; + long i5835; + long i5836; + long i5837; + long i5838; + long i5839; + long i5840; + long i5841; + long i5842; + long i5843; + long i5844; + long i5845; + long i5846; + long i5847; + long i5848; + long i5849; + long i5850; + long i5851; + long i5852; + long i5853; + long i5854; + long i5855; + long i5856; + long i5857; + long i5858; + long i5859; + long i5860; + long i5861; + long i5862; + long i5863; + long i5864; + long i5865; + long i5866; + long i5867; + long i5868; + long i5869; + long i5870; + long i5871; + long i5872; + long i5873; + long i5874; + long i5875; + long i5876; + long i5877; + long i5878; + long i5879; + long i5880; + long i5881; + long i5882; + long i5883; + long i5884; + long i5885; + long i5886; + long i5887; + long i5888; + long i5889; + long i5890; + long i5891; + long i5892; + long i5893; + long i5894; + long i5895; + long i5896; + long i5897; + long i5898; + long i5899; + long i5900; + long i5901; + long i5902; + long i5903; + long i5904; + long i5905; + long i5906; + long i5907; + long i5908; + long i5909; + long i5910; + long i5911; + long i5912; + long i5913; + long i5914; + long i5915; + long i5916; + long i5917; + long i5918; + long i5919; + long i5920; + long i5921; + long i5922; + long i5923; + long i5924; + long i5925; + long i5926; + long i5927; + long i5928; + long i5929; + long i5930; + long i5931; + long i5932; + long i5933; + long i5934; + long i5935; + long i5936; + long i5937; + long i5938; + long i5939; + long i5940; + long i5941; + long i5942; + long i5943; + long i5944; + long i5945; + long i5946; + long i5947; + long i5948; + long i5949; + long i5950; + long i5951; + long i5952; + long i5953; + long i5954; + long i5955; + long i5956; + long i5957; + long i5958; + long i5959; + long i5960; + long i5961; + long i5962; + long i5963; + long i5964; + long i5965; + long i5966; + long i5967; + long i5968; + long i5969; + long i5970; + long i5971; + long i5972; + long i5973; + long i5974; + long i5975; + long i5976; + long i5977; + long i5978; + long i5979; + long i5980; + long i5981; + long i5982; + long i5983; + long i5984; + long i5985; + long i5986; + long i5987; + long i5988; + long i5989; + long i5990; + long i5991; + long i5992; + long i5993; + long i5994; + long i5995; + long i5996; + long i5997; + long i5998; + long i5999; + long i6000; + long i6001; + long i6002; + long i6003; + long i6004; + long i6005; + long i6006; + long i6007; + long i6008; + long i6009; + long i6010; + long i6011; + long i6012; + long i6013; + long i6014; + long i6015; + long i6016; + long i6017; + long i6018; + long i6019; + long i6020; + long i6021; + long i6022; + long i6023; + long i6024; + long i6025; + long i6026; + long i6027; + long i6028; + long i6029; + long i6030; + long i6031; + long i6032; + long i6033; + long i6034; + long i6035; + long i6036; + long i6037; + long i6038; + long i6039; + long i6040; + long i6041; + long i6042; + long i6043; + long i6044; + long i6045; + long i6046; + long i6047; + long i6048; + long i6049; + long i6050; + long i6051; + long i6052; + long i6053; + long i6054; + long i6055; + long i6056; + long i6057; + long i6058; + long i6059; + long i6060; + long i6061; + long i6062; + long i6063; + long i6064; + long i6065; + long i6066; + long i6067; + long i6068; + long i6069; + long i6070; + long i6071; + long i6072; + long i6073; + long i6074; + long i6075; + long i6076; + long i6077; + long i6078; + long i6079; + long i6080; + long i6081; + long i6082; + long i6083; + long i6084; + long i6085; + long i6086; + long i6087; + long i6088; + long i6089; + long i6090; + long i6091; + long i6092; + long i6093; + long i6094; + long i6095; + long i6096; + long i6097; + long i6098; + long i6099; + long i6100; + long i6101; + long i6102; + long i6103; + long i6104; + long i6105; + long i6106; + long i6107; + long i6108; + long i6109; + long i6110; + long i6111; + long i6112; + long i6113; + long i6114; + long i6115; + long i6116; + long i6117; + long i6118; + long i6119; + long i6120; + long i6121; + long i6122; + long i6123; + long i6124; + long i6125; + long i6126; + long i6127; + long i6128; + long i6129; + long i6130; + long i6131; + long i6132; + long i6133; + long i6134; + long i6135; + long i6136; + long i6137; + long i6138; + long i6139; + long i6140; + long i6141; + long i6142; + long i6143; + long i6144; + long i6145; + long i6146; + long i6147; + long i6148; + long i6149; + long i6150; + long i6151; + long i6152; + long i6153; + long i6154; + long i6155; + long i6156; + long i6157; + long i6158; + long i6159; + long i6160; + long i6161; + long i6162; + long i6163; + long i6164; + long i6165; + long i6166; + long i6167; + long i6168; + long i6169; + long i6170; + long i6171; + long i6172; + long i6173; + long i6174; + long i6175; + long i6176; + long i6177; + long i6178; + long i6179; + long i6180; + long i6181; + long i6182; + long i6183; + long i6184; + long i6185; + long i6186; + long i6187; + long i6188; + long i6189; + long i6190; + long i6191; + long i6192; + long i6193; + long i6194; + long i6195; + long i6196; + long i6197; + long i6198; + long i6199; + long i6200; + long i6201; + long i6202; + long i6203; + long i6204; + long i6205; + long i6206; + long i6207; + long i6208; + long i6209; + long i6210; + long i6211; + long i6212; + long i6213; + long i6214; + long i6215; + long i6216; + long i6217; + long i6218; + long i6219; + long i6220; + long i6221; + long i6222; + long i6223; + long i6224; + long i6225; + long i6226; + long i6227; + long i6228; + long i6229; + long i6230; + long i6231; + long i6232; + long i6233; + long i6234; + long i6235; + long i6236; + long i6237; + long i6238; + long i6239; + long i6240; + long i6241; + long i6242; + long i6243; + long i6244; + long i6245; + long i6246; + long i6247; + long i6248; + long i6249; + long i6250; + long i6251; + long i6252; + long i6253; + long i6254; + long i6255; + long i6256; + long i6257; + long i6258; + long i6259; + long i6260; + long i6261; + long i6262; + long i6263; + long i6264; + long i6265; + long i6266; + long i6267; + long i6268; + long i6269; + long i6270; + long i6271; + long i6272; + long i6273; + long i6274; + long i6275; + long i6276; + long i6277; + long i6278; + long i6279; + long i6280; + long i6281; + long i6282; + long i6283; + long i6284; + long i6285; + long i6286; + long i6287; + long i6288; + long i6289; + long i6290; + long i6291; + long i6292; + long i6293; + long i6294; + long i6295; + long i6296; + long i6297; + long i6298; + long i6299; + long i6300; + long i6301; + long i6302; + long i6303; + long i6304; + long i6305; + long i6306; + long i6307; + long i6308; + long i6309; + long i6310; + long i6311; + long i6312; + long i6313; + long i6314; + long i6315; + long i6316; + long i6317; + long i6318; + long i6319; + long i6320; + long i6321; + long i6322; + long i6323; + long i6324; + long i6325; + long i6326; + long i6327; + long i6328; + long i6329; + long i6330; + long i6331; + long i6332; + long i6333; + long i6334; + long i6335; + long i6336; + long i6337; + long i6338; + long i6339; + long i6340; + long i6341; + long i6342; + long i6343; + long i6344; + long i6345; + long i6346; + long i6347; + long i6348; + long i6349; + long i6350; + long i6351; + long i6352; + long i6353; + long i6354; + long i6355; + long i6356; + long i6357; + long i6358; + long i6359; + long i6360; + long i6361; + long i6362; + long i6363; + long i6364; + long i6365; + long i6366; + long i6367; + long i6368; + long i6369; + long i6370; + long i6371; + long i6372; + long i6373; + long i6374; + long i6375; + long i6376; + long i6377; + long i6378; + long i6379; + long i6380; + long i6381; + long i6382; + long i6383; + long i6384; + long i6385; + long i6386; + long i6387; + long i6388; + long i6389; + long i6390; + long i6391; + long i6392; + long i6393; + long i6394; + long i6395; + long i6396; + long i6397; + long i6398; + long i6399; + long i6400; + long i6401; + long i6402; + long i6403; + long i6404; + long i6405; + long i6406; + long i6407; + long i6408; + long i6409; + long i6410; + long i6411; + long i6412; + long i6413; + long i6414; + long i6415; + long i6416; + long i6417; + long i6418; + long i6419; + long i6420; + long i6421; + long i6422; + long i6423; + long i6424; + long i6425; + long i6426; + long i6427; + long i6428; + long i6429; + long i6430; + long i6431; + long i6432; + long i6433; + long i6434; + long i6435; + long i6436; + long i6437; + long i6438; + long i6439; + long i6440; + long i6441; + long i6442; + long i6443; + long i6444; + long i6445; + long i6446; + long i6447; + long i6448; + long i6449; + long i6450; + long i6451; + long i6452; + long i6453; + long i6454; + long i6455; + long i6456; + long i6457; + long i6458; + long i6459; + long i6460; + long i6461; + long i6462; + long i6463; + long i6464; + long i6465; + long i6466; + long i6467; + long i6468; + long i6469; + long i6470; + long i6471; + long i6472; + long i6473; + long i6474; + long i6475; + long i6476; + long i6477; + long i6478; + long i6479; + long i6480; + long i6481; + long i6482; + long i6483; + long i6484; + long i6485; + long i6486; + long i6487; + long i6488; + long i6489; + long i6490; + long i6491; + long i6492; + long i6493; + long i6494; + long i6495; + long i6496; + long i6497; + long i6498; + long i6499; + long i6500; + long i6501; + long i6502; + long i6503; + long i6504; + long i6505; + long i6506; + long i6507; + long i6508; + long i6509; + long i6510; + long i6511; + long i6512; + long i6513; + long i6514; + long i6515; + long i6516; + long i6517; + long i6518; + long i6519; + long i6520; + long i6521; + long i6522; + long i6523; + long i6524; + long i6525; + long i6526; + long i6527; + long i6528; + long i6529; + long i6530; + long i6531; + long i6532; + long i6533; + long i6534; + long i6535; + long i6536; + long i6537; + long i6538; + long i6539; + long i6540; + long i6541; + long i6542; + long i6543; + long i6544; + long i6545; + long i6546; + long i6547; + long i6548; + long i6549; + long i6550; + long i6551; + long i6552; + long i6553; + long i6554; + long i6555; + long i6556; + long i6557; + long i6558; + long i6559; + long i6560; + long i6561; + long i6562; + long i6563; + long i6564; + long i6565; + long i6566; + long i6567; + long i6568; + long i6569; + long i6570; + long i6571; + long i6572; + long i6573; + long i6574; + long i6575; + long i6576; + long i6577; + long i6578; + long i6579; + long i6580; + long i6581; + long i6582; + long i6583; + long i6584; + long i6585; + long i6586; + long i6587; + long i6588; + long i6589; + long i6590; + long i6591; + long i6592; + long i6593; + long i6594; + long i6595; + long i6596; + long i6597; + long i6598; + long i6599; + long i6600; + long i6601; + long i6602; + long i6603; + long i6604; + long i6605; + long i6606; + long i6607; + long i6608; + long i6609; + long i6610; + long i6611; + long i6612; + long i6613; + long i6614; + long i6615; + long i6616; + long i6617; + long i6618; + long i6619; + long i6620; + long i6621; + long i6622; + long i6623; + long i6624; + long i6625; + long i6626; + long i6627; + long i6628; + long i6629; + long i6630; + long i6631; + long i6632; + long i6633; + long i6634; + long i6635; + long i6636; + long i6637; + long i6638; + long i6639; + long i6640; + long i6641; + long i6642; + long i6643; + long i6644; + long i6645; + long i6646; + long i6647; + long i6648; + long i6649; + long i6650; + long i6651; + long i6652; + long i6653; + long i6654; + long i6655; + long i6656; + long i6657; + long i6658; + long i6659; + long i6660; + long i6661; + long i6662; + long i6663; + long i6664; + long i6665; + long i6666; + long i6667; + long i6668; + long i6669; + long i6670; + long i6671; + long i6672; + long i6673; + long i6674; + long i6675; + long i6676; + long i6677; + long i6678; + long i6679; + long i6680; + long i6681; + long i6682; + long i6683; + long i6684; + long i6685; + long i6686; + long i6687; + long i6688; + long i6689; + long i6690; + long i6691; + long i6692; + long i6693; + long i6694; + long i6695; + long i6696; + long i6697; + long i6698; + long i6699; + long i6700; + long i6701; + long i6702; + long i6703; + long i6704; + long i6705; + long i6706; + long i6707; + long i6708; + long i6709; + long i6710; + long i6711; + long i6712; + long i6713; + long i6714; + long i6715; + long i6716; + long i6717; + long i6718; + long i6719; + long i6720; + long i6721; + long i6722; + long i6723; + long i6724; + long i6725; + long i6726; + long i6727; + long i6728; + long i6729; + long i6730; + long i6731; + long i6732; + long i6733; + long i6734; + long i6735; + long i6736; + long i6737; + long i6738; + long i6739; + long i6740; + long i6741; + long i6742; + long i6743; + long i6744; + long i6745; + long i6746; + long i6747; + long i6748; + long i6749; + long i6750; + long i6751; + long i6752; + long i6753; + long i6754; + long i6755; + long i6756; + long i6757; + long i6758; + long i6759; + long i6760; + long i6761; + long i6762; + long i6763; + long i6764; + long i6765; + long i6766; + long i6767; + long i6768; + long i6769; + long i6770; + long i6771; + long i6772; + long i6773; + long i6774; + long i6775; + long i6776; + long i6777; + long i6778; + long i6779; + long i6780; + long i6781; + long i6782; + long i6783; + long i6784; + long i6785; + long i6786; + long i6787; + long i6788; + long i6789; + long i6790; + long i6791; + long i6792; + long i6793; + long i6794; + long i6795; + long i6796; + long i6797; + long i6798; + long i6799; + long i6800; + long i6801; + long i6802; + long i6803; + long i6804; + long i6805; + long i6806; + long i6807; + long i6808; + long i6809; + long i6810; + long i6811; + long i6812; + long i6813; + long i6814; + long i6815; + long i6816; + long i6817; + long i6818; + long i6819; + long i6820; + long i6821; + long i6822; + long i6823; + long i6824; + long i6825; + long i6826; + long i6827; + long i6828; + long i6829; + long i6830; + long i6831; + long i6832; + long i6833; + long i6834; + long i6835; + long i6836; + long i6837; + long i6838; + long i6839; + long i6840; + long i6841; + long i6842; + long i6843; + long i6844; + long i6845; + long i6846; + long i6847; + long i6848; + long i6849; + long i6850; + long i6851; + long i6852; + long i6853; + long i6854; + long i6855; + long i6856; + long i6857; + long i6858; + long i6859; + long i6860; + long i6861; + long i6862; + long i6863; + long i6864; + long i6865; + long i6866; + long i6867; + long i6868; + long i6869; + long i6870; + long i6871; + long i6872; + long i6873; + long i6874; + long i6875; + long i6876; + long i6877; + long i6878; + long i6879; + long i6880; + long i6881; + long i6882; + long i6883; + long i6884; + long i6885; + long i6886; + long i6887; + long i6888; + long i6889; + long i6890; + long i6891; + long i6892; + long i6893; + long i6894; + long i6895; + long i6896; + long i6897; + long i6898; + long i6899; + long i6900; + long i6901; + long i6902; + long i6903; + long i6904; + long i6905; + long i6906; + long i6907; + long i6908; + long i6909; + long i6910; + long i6911; + long i6912; + long i6913; + long i6914; + long i6915; + long i6916; + long i6917; + long i6918; + long i6919; + long i6920; + long i6921; + long i6922; + long i6923; + long i6924; + long i6925; + long i6926; + long i6927; + long i6928; + long i6929; + long i6930; + long i6931; + long i6932; + long i6933; + long i6934; + long i6935; + long i6936; + long i6937; + long i6938; + long i6939; + long i6940; + long i6941; + long i6942; + long i6943; + long i6944; + long i6945; + long i6946; + long i6947; + long i6948; + long i6949; + long i6950; + long i6951; + long i6952; + long i6953; + long i6954; + long i6955; + long i6956; + long i6957; + long i6958; + long i6959; + long i6960; + long i6961; + long i6962; + long i6963; + long i6964; + long i6965; + long i6966; + long i6967; + long i6968; + long i6969; + long i6970; + long i6971; + long i6972; + long i6973; + long i6974; + long i6975; + long i6976; + long i6977; + long i6978; + long i6979; + long i6980; + long i6981; + long i6982; + long i6983; + long i6984; + long i6985; + long i6986; + long i6987; + long i6988; + long i6989; + long i6990; + long i6991; + long i6992; + long i6993; + long i6994; + long i6995; + long i6996; + long i6997; + long i6998; + long i6999; + long i7000; + long i7001; + long i7002; + long i7003; + long i7004; + long i7005; + long i7006; + long i7007; + long i7008; + long i7009; + long i7010; + long i7011; + long i7012; + long i7013; + long i7014; + long i7015; + long i7016; + long i7017; + long i7018; + long i7019; + long i7020; + long i7021; + long i7022; + long i7023; + long i7024; + long i7025; + long i7026; + long i7027; + long i7028; + long i7029; + long i7030; + long i7031; + long i7032; + long i7033; + long i7034; + long i7035; + long i7036; + long i7037; + long i7038; + long i7039; + long i7040; + long i7041; + long i7042; + long i7043; + long i7044; + long i7045; + long i7046; + long i7047; + long i7048; + long i7049; + long i7050; + long i7051; + long i7052; + long i7053; + long i7054; + long i7055; + long i7056; + long i7057; + long i7058; + long i7059; + long i7060; + long i7061; + long i7062; + long i7063; + long i7064; + long i7065; + long i7066; + long i7067; + long i7068; + long i7069; + long i7070; + long i7071; + long i7072; + long i7073; + long i7074; + long i7075; + long i7076; + long i7077; + long i7078; + long i7079; + long i7080; + long i7081; + long i7082; + long i7083; + long i7084; + long i7085; + long i7086; + long i7087; + long i7088; + long i7089; + long i7090; + long i7091; + long i7092; + long i7093; + long i7094; + long i7095; + long i7096; + long i7097; + long i7098; + long i7099; + long i7100; + long i7101; + long i7102; + long i7103; + long i7104; + long i7105; + long i7106; + long i7107; + long i7108; + long i7109; + long i7110; + long i7111; + long i7112; + long i7113; + long i7114; + long i7115; + long i7116; + long i7117; + long i7118; + long i7119; + long i7120; + long i7121; + long i7122; + long i7123; + long i7124; + long i7125; + long i7126; + long i7127; + long i7128; + long i7129; + long i7130; + long i7131; + long i7132; + long i7133; + long i7134; + long i7135; + long i7136; + long i7137; + long i7138; + long i7139; + long i7140; + long i7141; + long i7142; + long i7143; + long i7144; + long i7145; + long i7146; + long i7147; + long i7148; + long i7149; + long i7150; + long i7151; + long i7152; + long i7153; + long i7154; + long i7155; + long i7156; + long i7157; + long i7158; + long i7159; + long i7160; + long i7161; + long i7162; + long i7163; + long i7164; + long i7165; + long i7166; + long i7167; + long i7168; + long i7169; + long i7170; + long i7171; + long i7172; + long i7173; + long i7174; + long i7175; + long i7176; + long i7177; + long i7178; + long i7179; + long i7180; + long i7181; + long i7182; + long i7183; + long i7184; + long i7185; + long i7186; + long i7187; + long i7188; + long i7189; + long i7190; + long i7191; + long i7192; + long i7193; + long i7194; + long i7195; + long i7196; + long i7197; + long i7198; + long i7199; + long i7200; + long i7201; + long i7202; + long i7203; + long i7204; + long i7205; + long i7206; + long i7207; + long i7208; + long i7209; + long i7210; + long i7211; + long i7212; + long i7213; + long i7214; + long i7215; + long i7216; + long i7217; + long i7218; + long i7219; + long i7220; + long i7221; + long i7222; + long i7223; + long i7224; + long i7225; + long i7226; + long i7227; + long i7228; + long i7229; + long i7230; + long i7231; + long i7232; + long i7233; + long i7234; + long i7235; + long i7236; + long i7237; + long i7238; + long i7239; + long i7240; + long i7241; + long i7242; + long i7243; + long i7244; + long i7245; + long i7246; + long i7247; + long i7248; + long i7249; + long i7250; + long i7251; + long i7252; + long i7253; + long i7254; + long i7255; + long i7256; + long i7257; + long i7258; + long i7259; + long i7260; + long i7261; + long i7262; + long i7263; + long i7264; + long i7265; + long i7266; + long i7267; + long i7268; + long i7269; + long i7270; + long i7271; + long i7272; + long i7273; + long i7274; + long i7275; + long i7276; + long i7277; + long i7278; + long i7279; + long i7280; + long i7281; + long i7282; + long i7283; + long i7284; + long i7285; + long i7286; + long i7287; + long i7288; + long i7289; + long i7290; + long i7291; + long i7292; + long i7293; + long i7294; + long i7295; + long i7296; + long i7297; + long i7298; + long i7299; + long i7300; + long i7301; + long i7302; + long i7303; + long i7304; + long i7305; + long i7306; + long i7307; + long i7308; + long i7309; + long i7310; + long i7311; + long i7312; + long i7313; + long i7314; + long i7315; + long i7316; + long i7317; + long i7318; + long i7319; + long i7320; + long i7321; + long i7322; + long i7323; + long i7324; + long i7325; + long i7326; + long i7327; + long i7328; + long i7329; + long i7330; + long i7331; + long i7332; + long i7333; + long i7334; + long i7335; + long i7336; + long i7337; + long i7338; + long i7339; + long i7340; + long i7341; + long i7342; + long i7343; + long i7344; + long i7345; + long i7346; + long i7347; + long i7348; + long i7349; + long i7350; + long i7351; + long i7352; + long i7353; + long i7354; + long i7355; + long i7356; + long i7357; + long i7358; + long i7359; + long i7360; + long i7361; + long i7362; + long i7363; + long i7364; + long i7365; + long i7366; + long i7367; + long i7368; + long i7369; + long i7370; + long i7371; + long i7372; + long i7373; + long i7374; + long i7375; + long i7376; + long i7377; + long i7378; + long i7379; + long i7380; + long i7381; + long i7382; + long i7383; + long i7384; + long i7385; + long i7386; + long i7387; + long i7388; + long i7389; + long i7390; + long i7391; + long i7392; + long i7393; + long i7394; + long i7395; + long i7396; + long i7397; + long i7398; + long i7399; + long i7400; + long i7401; + long i7402; + long i7403; + long i7404; + long i7405; + long i7406; + long i7407; + long i7408; + long i7409; + long i7410; + long i7411; + long i7412; + long i7413; + long i7414; + long i7415; + long i7416; + long i7417; + long i7418; + long i7419; + long i7420; + long i7421; + long i7422; + long i7423; + long i7424; + long i7425; + long i7426; + long i7427; + long i7428; + long i7429; + long i7430; + long i7431; + long i7432; + long i7433; + long i7434; + long i7435; + long i7436; + long i7437; + long i7438; + long i7439; + long i7440; + long i7441; + long i7442; + long i7443; + long i7444; + long i7445; + long i7446; + long i7447; + long i7448; + long i7449; + long i7450; + long i7451; + long i7452; + long i7453; + long i7454; + long i7455; + long i7456; + long i7457; + long i7458; + long i7459; + long i7460; + long i7461; + long i7462; + long i7463; + long i7464; + long i7465; + long i7466; + long i7467; + long i7468; + long i7469; + long i7470; + long i7471; + long i7472; + long i7473; + long i7474; + long i7475; + long i7476; + long i7477; + long i7478; + long i7479; + long i7480; + long i7481; + long i7482; + long i7483; + long i7484; + long i7485; + long i7486; + long i7487; + long i7488; + long i7489; + long i7490; + long i7491; + long i7492; + long i7493; + long i7494; + long i7495; + long i7496; + long i7497; + long i7498; + long i7499; + long i7500; + long i7501; + long i7502; + long i7503; + long i7504; + long i7505; + long i7506; + long i7507; + long i7508; + long i7509; + long i7510; + long i7511; + long i7512; + long i7513; + long i7514; + long i7515; + long i7516; + long i7517; + long i7518; + long i7519; + long i7520; + long i7521; + long i7522; + long i7523; + long i7524; + long i7525; + long i7526; + long i7527; + long i7528; + long i7529; + long i7530; + long i7531; + long i7532; + long i7533; + long i7534; + long i7535; + long i7536; + long i7537; + long i7538; + long i7539; + long i7540; + long i7541; + long i7542; + long i7543; + long i7544; + long i7545; + long i7546; + long i7547; + long i7548; + long i7549; + long i7550; + long i7551; + long i7552; + long i7553; + long i7554; + long i7555; + long i7556; + long i7557; + long i7558; + long i7559; + long i7560; + long i7561; + long i7562; + long i7563; + long i7564; + long i7565; + long i7566; + long i7567; + long i7568; + long i7569; + long i7570; + long i7571; + long i7572; + long i7573; + long i7574; + long i7575; + long i7576; + long i7577; + long i7578; + long i7579; + long i7580; + long i7581; + long i7582; + long i7583; + long i7584; + long i7585; + long i7586; + long i7587; + long i7588; + long i7589; + long i7590; + long i7591; + long i7592; + long i7593; + long i7594; + long i7595; + long i7596; + long i7597; + long i7598; + long i7599; + long i7600; + long i7601; + long i7602; + long i7603; + long i7604; + long i7605; + long i7606; + long i7607; + long i7608; + long i7609; + long i7610; + long i7611; + long i7612; + long i7613; + long i7614; + long i7615; + long i7616; + long i7617; + long i7618; + long i7619; + long i7620; + long i7621; + long i7622; + long i7623; + long i7624; + long i7625; + long i7626; + long i7627; + long i7628; + long i7629; + long i7630; + long i7631; + long i7632; + long i7633; + long i7634; + long i7635; + long i7636; + long i7637; + long i7638; + long i7639; + long i7640; + long i7641; + long i7642; + long i7643; + long i7644; + long i7645; + long i7646; + long i7647; + long i7648; + long i7649; + long i7650; + long i7651; + long i7652; + long i7653; + long i7654; + long i7655; + long i7656; + long i7657; + long i7658; + long i7659; + long i7660; + long i7661; + long i7662; + long i7663; + long i7664; + long i7665; + long i7666; + long i7667; + long i7668; + long i7669; + long i7670; + long i7671; + long i7672; + long i7673; + long i7674; + long i7675; + long i7676; + long i7677; + long i7678; + long i7679; + long i7680; + long i7681; + long i7682; + long i7683; + long i7684; + long i7685; + long i7686; + long i7687; + long i7688; + long i7689; + long i7690; + long i7691; + long i7692; + long i7693; + long i7694; + long i7695; + long i7696; + long i7697; + long i7698; + long i7699; + long i7700; + long i7701; + long i7702; + long i7703; + long i7704; + long i7705; + long i7706; + long i7707; + long i7708; + long i7709; + long i7710; + long i7711; + long i7712; + long i7713; + long i7714; + long i7715; + long i7716; + long i7717; + long i7718; + long i7719; + long i7720; + long i7721; + long i7722; + long i7723; + long i7724; + long i7725; + long i7726; + long i7727; + long i7728; + long i7729; + long i7730; + long i7731; + long i7732; + long i7733; + long i7734; + long i7735; + long i7736; + long i7737; + long i7738; + long i7739; + long i7740; + long i7741; + long i7742; + long i7743; + long i7744; + long i7745; + long i7746; + long i7747; + long i7748; + long i7749; + long i7750; + long i7751; + long i7752; + long i7753; + long i7754; + long i7755; + long i7756; + long i7757; + long i7758; + long i7759; + long i7760; + long i7761; + long i7762; + long i7763; + long i7764; + long i7765; + long i7766; + long i7767; + long i7768; + long i7769; + long i7770; + long i7771; + long i7772; + long i7773; + long i7774; + long i7775; + long i7776; + long i7777; + long i7778; + long i7779; + long i7780; + long i7781; + long i7782; + long i7783; + long i7784; + long i7785; + long i7786; + long i7787; + long i7788; + long i7789; + long i7790; + long i7791; + long i7792; + long i7793; + long i7794; + long i7795; + long i7796; + long i7797; + long i7798; + long i7799; + long i7800; + long i7801; + long i7802; + long i7803; + long i7804; + long i7805; + long i7806; + long i7807; + long i7808; + long i7809; + long i7810; + long i7811; + long i7812; + long i7813; + long i7814; + long i7815; + long i7816; + long i7817; + long i7818; + long i7819; + long i7820; + long i7821; + long i7822; + long i7823; + long i7824; + long i7825; + long i7826; + long i7827; + long i7828; + long i7829; + long i7830; + long i7831; + long i7832; + long i7833; + long i7834; + long i7835; + long i7836; + long i7837; + long i7838; + long i7839; + long i7840; + long i7841; + long i7842; + long i7843; + long i7844; + long i7845; + long i7846; + long i7847; + long i7848; + long i7849; + long i7850; + long i7851; + long i7852; + long i7853; + long i7854; + long i7855; + long i7856; + long i7857; + long i7858; + long i7859; + long i7860; + long i7861; + long i7862; + long i7863; + long i7864; + long i7865; + long i7866; + long i7867; + long i7868; + long i7869; + long i7870; + long i7871; + long i7872; + long i7873; + long i7874; + long i7875; + long i7876; + long i7877; + long i7878; + long i7879; + long i7880; + long i7881; + long i7882; + long i7883; + long i7884; + long i7885; + long i7886; + long i7887; + long i7888; + long i7889; + long i7890; + long i7891; + long i7892; + long i7893; + long i7894; + long i7895; + long i7896; + long i7897; + long i7898; + long i7899; + long i7900; + long i7901; + long i7902; + long i7903; + long i7904; + long i7905; + long i7906; + long i7907; + long i7908; + long i7909; + long i7910; + long i7911; + long i7912; + long i7913; + long i7914; + long i7915; + long i7916; + long i7917; + long i7918; + long i7919; + long i7920; + long i7921; + long i7922; + long i7923; + long i7924; + long i7925; + long i7926; + long i7927; + long i7928; + long i7929; + long i7930; + long i7931; + long i7932; + long i7933; + long i7934; + long i7935; + long i7936; + long i7937; + long i7938; + long i7939; + long i7940; + long i7941; + long i7942; + long i7943; + long i7944; + long i7945; + long i7946; + long i7947; + long i7948; + long i7949; + long i7950; + long i7951; + long i7952; + long i7953; + long i7954; + long i7955; + long i7956; + long i7957; + long i7958; + long i7959; + long i7960; + long i7961; + long i7962; + long i7963; + long i7964; + long i7965; + long i7966; + long i7967; + long i7968; + long i7969; + long i7970; + long i7971; + long i7972; + long i7973; + long i7974; + long i7975; + long i7976; + long i7977; + long i7978; + long i7979; + long i7980; + long i7981; + long i7982; + long i7983; + long i7984; + long i7985; + long i7986; + long i7987; + long i7988; + long i7989; + long i7990; + long i7991; + long i7992; + long i7993; + long i7994; + long i7995; + long i7996; + long i7997; + long i7998; + long i7999; + long i8000; + long i8001; + long i8002; + long i8003; + long i8004; + long i8005; + long i8006; + long i8007; + long i8008; + long i8009; + long i8010; + long i8011; + long i8012; + long i8013; + long i8014; + long i8015; + long i8016; + long i8017; + long i8018; + long i8019; + long i8020; + long i8021; + long i8022; + long i8023; + long i8024; + long i8025; + long i8026; + long i8027; + long i8028; + long i8029; + long i8030; + long i8031; + long i8032; + long i8033; + long i8034; + long i8035; + long i8036; + long i8037; + long i8038; + long i8039; + long i8040; + long i8041; + long i8042; + long i8043; + long i8044; + long i8045; + long i8046; + long i8047; + long i8048; + long i8049; + long i8050; + long i8051; + long i8052; + long i8053; + long i8054; + long i8055; + long i8056; + long i8057; + long i8058; + long i8059; + long i8060; + long i8061; + long i8062; + long i8063; + long i8064; + long i8065; + long i8066; + long i8067; + long i8068; + long i8069; + long i8070; + long i8071; + long i8072; + long i8073; + long i8074; + long i8075; + long i8076; + long i8077; + long i8078; + long i8079; + long i8080; + long i8081; + long i8082; + long i8083; + long i8084; + long i8085; + long i8086; + long i8087; + long i8088; + long i8089; + long i8090; + long i8091; + long i8092; + long i8093; + long i8094; + long i8095; + long i8096; + long i8097; + long i8098; + long i8099; + long i8100; + long i8101; + long i8102; + long i8103; + long i8104; + long i8105; + long i8106; + long i8107; + long i8108; + long i8109; + long i8110; + long i8111; + long i8112; + long i8113; + long i8114; + long i8115; + long i8116; + long i8117; + long i8118; + long i8119; + long i8120; + long i8121; + long i8122; + long i8123; + long i8124; + long i8125; + long i8126; + long i8127; + long i8128; + long i8129; + long i8130; + long i8131; + long i8132; + long i8133; + long i8134; + long i8135; + long i8136; + long i8137; + long i8138; + long i8139; + long i8140; + long i8141; + long i8142; + long i8143; + long i8144; + long i8145; + long i8146; + long i8147; + long i8148; + long i8149; + long i8150; + long i8151; + long i8152; + long i8153; + long i8154; + long i8155; + long i8156; + long i8157; + long i8158; + long i8159; + long i8160; + long i8161; + long i8162; + long i8163; + long i8164; + long i8165; + long i8166; + long i8167; + long i8168; + long i8169; + long i8170; + long i8171; + long i8172; + long i8173; + long i8174; + long i8175; + long i8176; + long i8177; + long i8178; + long i8179; + long i8180; + long i8181; + long i8182; + long i8183; + long i8184; + long i8185; + long i8186; + long i8187; + long i8188; + long i8189; + long i8190; + long i8191; + long i8192; + long i8193; + long i8194; + long i8195; + long i8196; + long i8197; + long i8198; + long i8199; + long i8200; + long i8201; + long i8202; + long i8203; + long i8204; + long i8205; + long i8206; + long i8207; + long i8208; + long i8209; + long i8210; + long i8211; + long i8212; + long i8213; + long i8214; + long i8215; + long i8216; + long i8217; + long i8218; + long i8219; + long i8220; + long i8221; + long i8222; + long i8223; + long i8224; + long i8225; + long i8226; + long i8227; + long i8228; + long i8229; + long i8230; + long i8231; + long i8232; + long i8233; + long i8234; + long i8235; + long i8236; + long i8237; + long i8238; + long i8239; + long i8240; + long i8241; + long i8242; + long i8243; + long i8244; + long i8245; + long i8246; + long i8247; + long i8248; + long i8249; + long i8250; + long i8251; + long i8252; + long i8253; + long i8254; + long i8255; + long i8256; + long i8257; + long i8258; + long i8259; + long i8260; + long i8261; + long i8262; + long i8263; + long i8264; + long i8265; + long i8266; + long i8267; + long i8268; + long i8269; + long i8270; + long i8271; + long i8272; + long i8273; + long i8274; + long i8275; + long i8276; + long i8277; + long i8278; + long i8279; + long i8280; + long i8281; + long i8282; + long i8283; + long i8284; + long i8285; + long i8286; + long i8287; + long i8288; + long i8289; + long i8290; + long i8291; + long i8292; + long i8293; + long i8294; + long i8295; + long i8296; + long i8297; + long i8298; + long i8299; + long i8300; + long i8301; + long i8302; + long i8303; + long i8304; + long i8305; + long i8306; + long i8307; + long i8308; + long i8309; + long i8310; + long i8311; + long i8312; + long i8313; + long i8314; + long i8315; + long i8316; + long i8317; + long i8318; + long i8319; + long i8320; + long i8321; + long i8322; + long i8323; + long i8324; + long i8325; + long i8326; + long i8327; + long i8328; + long i8329; + long i8330; + long i8331; + long i8332; + long i8333; + long i8334; + long i8335; + long i8336; + long i8337; + long i8338; + long i8339; + long i8340; + long i8341; + long i8342; + long i8343; + long i8344; + long i8345; + long i8346; + long i8347; + long i8348; + long i8349; + long i8350; + long i8351; + long i8352; + long i8353; + long i8354; + long i8355; + long i8356; + long i8357; + long i8358; + long i8359; + long i8360; + long i8361; + long i8362; + long i8363; + long i8364; + long i8365; + long i8366; + long i8367; + long i8368; + long i8369; + long i8370; + long i8371; + long i8372; + long i8373; + long i8374; + long i8375; + long i8376; + long i8377; + long i8378; + long i8379; + long i8380; + long i8381; + long i8382; + long i8383; + long i8384; + long i8385; + long i8386; + long i8387; + long i8388; + long i8389; + long i8390; + long i8391; + long i8392; + long i8393; + long i8394; + long i8395; + long i8396; + long i8397; + long i8398; + long i8399; + long i8400; + long i8401; + long i8402; + long i8403; + long i8404; + long i8405; + long i8406; + long i8407; + long i8408; + long i8409; + long i8410; + long i8411; + long i8412; + long i8413; + long i8414; + long i8415; + long i8416; + long i8417; + long i8418; + long i8419; + long i8420; + long i8421; + long i8422; + long i8423; + long i8424; + long i8425; + long i8426; + long i8427; + long i8428; + long i8429; + long i8430; + long i8431; + long i8432; + long i8433; + long i8434; + long i8435; + long i8436; + long i8437; + long i8438; + long i8439; + long i8440; + long i8441; + long i8442; + long i8443; + long i8444; + long i8445; + long i8446; + long i8447; + long i8448; + long i8449; + long i8450; + long i8451; + long i8452; + long i8453; + long i8454; + long i8455; + long i8456; + long i8457; + long i8458; + long i8459; + long i8460; + long i8461; + long i8462; + long i8463; + long i8464; + long i8465; + long i8466; + long i8467; + long i8468; + long i8469; + long i8470; + long i8471; + long i8472; + long i8473; + long i8474; + long i8475; + long i8476; + long i8477; + long i8478; + long i8479; + long i8480; + long i8481; + long i8482; + long i8483; + long i8484; + long i8485; + long i8486; + long i8487; + long i8488; + long i8489; + long i8490; + long i8491; + long i8492; + long i8493; + long i8494; + long i8495; + long i8496; + long i8497; + long i8498; + long i8499; + long i8500; + long i8501; + long i8502; + long i8503; + long i8504; + long i8505; + long i8506; + long i8507; + long i8508; + long i8509; + long i8510; + long i8511; + long i8512; + long i8513; + long i8514; + long i8515; + long i8516; + long i8517; + long i8518; + long i8519; + long i8520; + long i8521; + long i8522; + long i8523; + long i8524; + long i8525; + long i8526; + long i8527; + long i8528; + long i8529; + long i8530; + long i8531; + long i8532; + long i8533; + long i8534; + long i8535; + long i8536; + long i8537; + long i8538; + long i8539; + long i8540; + long i8541; + long i8542; + long i8543; + long i8544; + long i8545; + long i8546; + long i8547; + long i8548; + long i8549; + long i8550; + long i8551; + long i8552; + long i8553; + long i8554; + long i8555; + long i8556; + long i8557; + long i8558; + long i8559; + long i8560; + long i8561; + long i8562; + long i8563; + long i8564; + long i8565; + long i8566; + long i8567; + long i8568; + long i8569; + long i8570; + long i8571; + long i8572; + long i8573; + long i8574; + long i8575; + long i8576; + long i8577; + long i8578; + long i8579; + long i8580; + long i8581; + long i8582; + long i8583; + long i8584; + long i8585; + long i8586; + long i8587; + long i8588; + long i8589; + long i8590; + long i8591; + long i8592; + long i8593; + long i8594; + long i8595; + long i8596; + long i8597; + long i8598; + long i8599; + long i8600; + long i8601; + long i8602; + long i8603; + long i8604; + long i8605; + long i8606; + long i8607; + long i8608; + long i8609; + long i8610; + long i8611; + long i8612; + long i8613; + long i8614; + long i8615; + long i8616; + long i8617; + long i8618; + long i8619; + long i8620; + long i8621; + long i8622; + long i8623; + long i8624; + long i8625; + long i8626; + long i8627; + long i8628; + long i8629; + long i8630; + long i8631; + long i8632; + long i8633; + long i8634; + long i8635; + long i8636; + long i8637; + long i8638; + long i8639; + long i8640; + long i8641; + long i8642; + long i8643; + long i8644; + long i8645; + long i8646; + long i8647; + long i8648; + long i8649; + long i8650; + long i8651; + long i8652; + long i8653; + long i8654; + long i8655; + long i8656; + long i8657; + long i8658; + long i8659; + long i8660; + long i8661; + long i8662; + long i8663; + long i8664; + long i8665; + long i8666; + long i8667; + long i8668; + long i8669; + long i8670; + long i8671; + long i8672; + long i8673; + long i8674; + long i8675; + long i8676; + long i8677; + long i8678; + long i8679; + long i8680; + long i8681; + long i8682; + long i8683; + long i8684; + long i8685; + long i8686; + long i8687; + long i8688; + long i8689; + long i8690; + long i8691; + long i8692; + long i8693; + long i8694; + long i8695; + long i8696; + long i8697; + long i8698; + long i8699; + long i8700; + long i8701; + long i8702; + long i8703; + long i8704; + long i8705; + long i8706; + long i8707; + long i8708; + long i8709; + long i8710; + long i8711; + long i8712; + long i8713; + long i8714; + long i8715; + long i8716; + long i8717; + long i8718; + long i8719; + long i8720; + long i8721; + long i8722; + long i8723; + long i8724; + long i8725; + long i8726; + long i8727; + long i8728; + long i8729; + long i8730; + long i8731; + long i8732; + long i8733; + long i8734; + long i8735; + long i8736; + long i8737; + long i8738; + long i8739; + long i8740; + long i8741; + long i8742; + long i8743; + long i8744; + long i8745; + long i8746; + long i8747; + long i8748; + long i8749; + long i8750; + long i8751; + long i8752; + long i8753; + long i8754; + long i8755; + long i8756; + long i8757; + long i8758; + long i8759; + long i8760; + long i8761; + long i8762; + long i8763; + long i8764; + long i8765; + long i8766; + long i8767; + long i8768; + long i8769; + long i8770; + long i8771; + long i8772; + long i8773; + long i8774; + long i8775; + long i8776; + long i8777; + long i8778; + long i8779; + long i8780; + long i8781; + long i8782; + long i8783; + long i8784; + long i8785; + long i8786; + long i8787; + long i8788; + long i8789; + long i8790; + long i8791; + long i8792; + long i8793; + long i8794; + long i8795; + long i8796; + long i8797; + long i8798; + long i8799; + long i8800; + long i8801; + long i8802; + long i8803; + long i8804; + long i8805; + long i8806; + long i8807; + long i8808; + long i8809; + long i8810; + long i8811; + long i8812; + long i8813; + long i8814; + long i8815; + long i8816; + long i8817; + long i8818; + long i8819; + long i8820; + long i8821; + long i8822; + long i8823; + long i8824; + long i8825; + long i8826; + long i8827; + long i8828; + long i8829; + long i8830; + long i8831; + long i8832; + long i8833; + long i8834; + long i8835; + long i8836; + long i8837; + long i8838; + long i8839; + long i8840; + long i8841; + long i8842; + long i8843; + long i8844; + long i8845; + long i8846; + long i8847; + long i8848; + long i8849; + long i8850; + long i8851; + long i8852; + long i8853; + long i8854; + long i8855; + long i8856; + long i8857; + long i8858; + long i8859; + long i8860; + long i8861; + long i8862; + long i8863; + long i8864; + long i8865; + long i8866; + long i8867; + long i8868; + long i8869; + long i8870; + long i8871; + long i8872; + long i8873; + long i8874; + long i8875; + long i8876; + long i8877; + long i8878; + long i8879; + long i8880; + long i8881; + long i8882; + long i8883; + long i8884; + long i8885; + long i8886; + long i8887; + long i8888; + long i8889; + long i8890; + long i8891; + long i8892; + long i8893; + long i8894; + long i8895; + long i8896; + long i8897; + long i8898; + long i8899; + long i8900; + long i8901; + long i8902; + long i8903; + long i8904; + long i8905; + long i8906; + long i8907; + long i8908; + long i8909; + long i8910; + long i8911; + long i8912; + long i8913; + long i8914; + long i8915; + long i8916; + long i8917; + long i8918; + long i8919; + long i8920; + long i8921; + long i8922; + long i8923; + long i8924; + long i8925; + long i8926; + long i8927; + long i8928; + long i8929; + long i8930; + long i8931; + long i8932; + long i8933; + long i8934; + long i8935; + long i8936; + long i8937; + long i8938; + long i8939; + long i8940; + long i8941; + long i8942; + long i8943; + long i8944; + long i8945; + long i8946; + long i8947; + long i8948; + long i8949; + long i8950; + long i8951; + long i8952; + long i8953; + long i8954; + long i8955; + long i8956; + long i8957; + long i8958; + long i8959; + long i8960; + long i8961; + long i8962; + long i8963; + long i8964; + long i8965; + long i8966; + long i8967; + long i8968; + long i8969; + long i8970; + long i8971; + long i8972; + long i8973; + long i8974; + long i8975; + long i8976; + long i8977; + long i8978; + long i8979; + long i8980; + long i8981; + long i8982; + long i8983; + long i8984; + long i8985; + long i8986; + long i8987; + long i8988; + long i8989; + long i8990; + long i8991; + long i8992; + long i8993; + long i8994; + long i8995; + long i8996; + long i8997; + long i8998; + long i8999; + long i9000; + long i9001; + long i9002; + long i9003; + long i9004; + long i9005; + long i9006; + long i9007; + long i9008; + long i9009; + long i9010; + long i9011; + long i9012; + long i9013; + long i9014; + long i9015; + long i9016; + long i9017; + long i9018; + long i9019; + long i9020; + long i9021; + long i9022; + long i9023; + long i9024; + long i9025; + long i9026; + long i9027; + long i9028; + long i9029; + long i9030; + long i9031; + long i9032; + long i9033; + long i9034; + long i9035; + long i9036; + long i9037; + long i9038; + long i9039; + long i9040; + long i9041; + long i9042; + long i9043; + long i9044; + long i9045; + long i9046; + long i9047; + long i9048; + long i9049; + long i9050; + long i9051; + long i9052; + long i9053; + long i9054; + long i9055; + long i9056; + long i9057; + long i9058; + long i9059; + long i9060; + long i9061; + long i9062; + long i9063; + long i9064; + long i9065; + long i9066; + long i9067; + long i9068; + long i9069; + long i9070; + long i9071; + long i9072; + long i9073; + long i9074; + long i9075; + long i9076; + long i9077; + long i9078; + long i9079; + long i9080; + long i9081; + long i9082; + long i9083; + long i9084; + long i9085; + long i9086; + long i9087; + long i9088; + long i9089; + long i9090; + long i9091; + long i9092; + long i9093; + long i9094; + long i9095; + long i9096; + long i9097; + long i9098; + long i9099; + long i9100; + long i9101; + long i9102; + long i9103; + long i9104; + long i9105; + long i9106; + long i9107; + long i9108; + long i9109; + long i9110; + long i9111; + long i9112; + long i9113; + long i9114; + long i9115; + long i9116; + long i9117; + long i9118; + long i9119; + long i9120; + long i9121; + long i9122; + long i9123; + long i9124; + long i9125; + long i9126; + long i9127; + long i9128; + long i9129; + long i9130; + long i9131; + long i9132; + long i9133; + long i9134; + long i9135; + long i9136; + long i9137; + long i9138; + long i9139; + long i9140; + long i9141; + long i9142; + long i9143; + long i9144; + long i9145; + long i9146; + long i9147; + long i9148; + long i9149; + long i9150; + long i9151; + long i9152; + long i9153; + long i9154; + long i9155; + long i9156; + long i9157; + long i9158; + long i9159; + long i9160; + long i9161; + long i9162; + long i9163; + long i9164; + long i9165; + long i9166; + long i9167; + long i9168; + long i9169; + long i9170; + long i9171; + long i9172; + long i9173; + long i9174; + long i9175; + long i9176; + long i9177; + long i9178; + long i9179; + long i9180; + long i9181; + long i9182; + long i9183; + long i9184; + long i9185; + long i9186; + long i9187; + long i9188; + long i9189; + long i9190; + long i9191; + long i9192; + long i9193; + long i9194; + long i9195; + long i9196; + long i9197; + long i9198; + long i9199; + long i9200; + long i9201; + long i9202; + long i9203; + long i9204; + long i9205; + long i9206; + long i9207; + long i9208; + long i9209; + long i9210; + long i9211; + long i9212; + long i9213; + long i9214; + long i9215; + long i9216; + long i9217; + long i9218; + long i9219; + long i9220; + long i9221; + long i9222; + long i9223; + long i9224; + long i9225; + long i9226; + long i9227; + long i9228; + long i9229; + long i9230; + long i9231; + long i9232; + long i9233; + long i9234; + long i9235; + long i9236; + long i9237; + long i9238; + long i9239; + long i9240; + long i9241; + long i9242; + long i9243; + long i9244; + long i9245; + long i9246; + long i9247; + long i9248; + long i9249; + long i9250; + long i9251; + long i9252; + long i9253; + long i9254; + long i9255; + long i9256; + long i9257; + long i9258; + long i9259; + long i9260; + long i9261; + long i9262; + long i9263; + long i9264; + long i9265; + long i9266; + long i9267; + long i9268; + long i9269; + long i9270; + long i9271; + long i9272; + long i9273; + long i9274; + long i9275; + long i9276; + long i9277; + long i9278; + long i9279; + long i9280; + long i9281; + long i9282; + long i9283; + long i9284; + long i9285; + long i9286; + long i9287; + long i9288; + long i9289; + long i9290; + long i9291; + long i9292; + long i9293; + long i9294; + long i9295; + long i9296; + long i9297; + long i9298; + long i9299; + long i9300; + long i9301; + long i9302; + long i9303; + long i9304; + long i9305; + long i9306; + long i9307; + long i9308; + long i9309; + long i9310; + long i9311; + long i9312; + long i9313; + long i9314; + long i9315; + long i9316; + long i9317; + long i9318; + long i9319; + long i9320; + long i9321; + long i9322; + long i9323; + long i9324; + long i9325; + long i9326; + long i9327; + long i9328; + long i9329; + long i9330; + long i9331; + long i9332; + long i9333; + long i9334; + long i9335; + long i9336; + long i9337; + long i9338; + long i9339; + long i9340; + long i9341; + long i9342; + long i9343; + long i9344; + long i9345; + long i9346; + long i9347; + long i9348; + long i9349; + long i9350; + long i9351; + long i9352; + long i9353; + long i9354; + long i9355; + long i9356; + long i9357; + long i9358; + long i9359; + long i9360; + long i9361; + long i9362; + long i9363; + long i9364; + long i9365; + long i9366; + long i9367; + long i9368; + long i9369; + long i9370; + long i9371; + long i9372; + long i9373; + long i9374; + long i9375; + long i9376; + long i9377; + long i9378; + long i9379; + long i9380; + long i9381; + long i9382; + long i9383; + long i9384; + long i9385; + long i9386; + long i9387; + long i9388; + long i9389; + long i9390; + long i9391; + long i9392; + long i9393; + long i9394; + long i9395; + long i9396; + long i9397; + long i9398; + long i9399; + long i9400; + long i9401; + long i9402; + long i9403; + long i9404; + long i9405; + long i9406; + long i9407; + long i9408; + long i9409; + long i9410; + long i9411; + long i9412; + long i9413; + long i9414; + long i9415; + long i9416; + long i9417; + long i9418; + long i9419; + long i9420; + long i9421; + long i9422; + long i9423; + long i9424; + long i9425; + long i9426; + long i9427; + long i9428; + long i9429; + long i9430; + long i9431; + long i9432; + long i9433; + long i9434; + long i9435; + long i9436; + long i9437; + long i9438; + long i9439; + long i9440; + long i9441; + long i9442; + long i9443; + long i9444; + long i9445; + long i9446; + long i9447; + long i9448; + long i9449; + long i9450; + long i9451; + long i9452; + long i9453; + long i9454; + long i9455; + long i9456; + long i9457; + long i9458; + long i9459; + long i9460; + long i9461; + long i9462; + long i9463; + long i9464; + long i9465; + long i9466; + long i9467; + long i9468; + long i9469; + long i9470; + long i9471; + long i9472; + long i9473; + long i9474; + long i9475; + long i9476; + long i9477; + long i9478; + long i9479; + long i9480; + long i9481; + long i9482; + long i9483; + long i9484; + long i9485; + long i9486; + long i9487; + long i9488; + long i9489; + long i9490; + long i9491; + long i9492; + long i9493; + long i9494; + long i9495; + long i9496; + long i9497; + long i9498; + long i9499; + long i9500; + long i9501; + long i9502; + long i9503; + long i9504; + long i9505; + long i9506; + long i9507; + long i9508; + long i9509; + long i9510; + long i9511; + long i9512; + long i9513; + long i9514; + long i9515; + long i9516; + long i9517; + long i9518; + long i9519; + long i9520; + long i9521; + long i9522; + long i9523; + long i9524; + long i9525; + long i9526; + long i9527; + long i9528; + long i9529; + long i9530; + long i9531; + long i9532; + long i9533; + long i9534; + long i9535; + long i9536; + long i9537; + long i9538; + long i9539; + long i9540; + long i9541; + long i9542; + long i9543; + long i9544; + long i9545; + long i9546; + long i9547; + long i9548; + long i9549; + long i9550; + long i9551; + long i9552; + long i9553; + long i9554; + long i9555; + long i9556; + long i9557; + long i9558; + long i9559; + long i9560; + long i9561; + long i9562; + long i9563; + long i9564; + long i9565; + long i9566; + long i9567; + long i9568; + long i9569; + long i9570; + long i9571; + long i9572; + long i9573; + long i9574; + long i9575; + long i9576; + long i9577; + long i9578; + long i9579; + long i9580; + long i9581; + long i9582; + long i9583; + long i9584; + long i9585; + long i9586; + long i9587; + long i9588; + long i9589; + long i9590; + long i9591; + long i9592; + long i9593; + long i9594; + long i9595; + long i9596; + long i9597; + long i9598; + long i9599; + long i9600; + long i9601; + long i9602; + long i9603; + long i9604; + long i9605; + long i9606; + long i9607; + long i9608; + long i9609; + long i9610; + long i9611; + long i9612; + long i9613; + long i9614; + long i9615; + long i9616; + long i9617; + long i9618; + long i9619; + long i9620; + long i9621; + long i9622; + long i9623; + long i9624; + long i9625; + long i9626; + long i9627; + long i9628; + long i9629; + long i9630; + long i9631; + long i9632; + long i9633; + long i9634; + long i9635; + long i9636; + long i9637; + long i9638; + long i9639; + long i9640; + long i9641; + long i9642; + long i9643; + long i9644; + long i9645; + long i9646; + long i9647; + long i9648; + long i9649; + long i9650; + long i9651; + long i9652; + long i9653; + long i9654; + long i9655; + long i9656; + long i9657; + long i9658; + long i9659; + long i9660; + long i9661; + long i9662; + long i9663; + long i9664; + long i9665; + long i9666; + long i9667; + long i9668; + long i9669; + long i9670; + long i9671; + long i9672; + long i9673; + long i9674; + long i9675; + long i9676; + long i9677; + long i9678; + long i9679; + long i9680; + long i9681; + long i9682; + long i9683; + long i9684; + long i9685; + long i9686; + long i9687; + long i9688; + long i9689; + long i9690; + long i9691; + long i9692; + long i9693; + long i9694; + long i9695; + long i9696; + long i9697; + long i9698; + long i9699; + long i9700; + long i9701; + long i9702; + long i9703; + long i9704; + long i9705; + long i9706; + long i9707; + long i9708; + long i9709; + long i9710; + long i9711; + long i9712; + long i9713; + long i9714; + long i9715; + long i9716; + long i9717; + long i9718; + long i9719; + long i9720; + long i9721; + long i9722; + long i9723; + long i9724; + long i9725; + long i9726; + long i9727; + long i9728; + long i9729; + long i9730; + long i9731; + long i9732; + long i9733; + long i9734; + long i9735; + long i9736; + long i9737; + long i9738; + long i9739; + long i9740; + long i9741; + long i9742; + long i9743; + long i9744; + long i9745; + long i9746; + long i9747; + long i9748; + long i9749; + long i9750; + long i9751; + long i9752; + long i9753; + long i9754; + long i9755; + long i9756; + long i9757; + long i9758; + long i9759; + long i9760; + long i9761; + long i9762; + long i9763; + long i9764; + long i9765; + long i9766; + long i9767; + long i9768; + long i9769; + long i9770; + long i9771; + long i9772; + long i9773; + long i9774; + long i9775; + long i9776; + long i9777; + long i9778; + long i9779; + long i9780; + long i9781; + long i9782; + long i9783; + long i9784; + long i9785; + long i9786; + long i9787; + long i9788; + long i9789; + long i9790; + long i9791; + long i9792; + long i9793; + long i9794; + long i9795; + long i9796; + long i9797; + long i9798; + long i9799; + long i9800; + long i9801; + long i9802; + long i9803; + long i9804; + long i9805; + long i9806; + long i9807; + long i9808; + long i9809; + long i9810; + long i9811; + long i9812; + long i9813; + long i9814; + long i9815; + long i9816; + long i9817; + long i9818; + long i9819; + long i9820; + long i9821; + long i9822; + long i9823; + long i9824; + long i9825; + long i9826; + long i9827; + long i9828; + long i9829; + long i9830; + long i9831; + long i9832; + long i9833; + long i9834; + long i9835; + long i9836; + long i9837; + long i9838; + long i9839; + long i9840; + long i9841; + long i9842; + long i9843; + long i9844; + long i9845; + long i9846; + long i9847; + long i9848; + long i9849; + long i9850; + long i9851; + long i9852; + long i9853; + long i9854; + long i9855; + long i9856; + long i9857; + long i9858; + long i9859; + long i9860; + long i9861; + long i9862; + long i9863; + long i9864; + long i9865; + long i9866; + long i9867; + long i9868; + long i9869; + long i9870; + long i9871; + long i9872; + long i9873; + long i9874; + long i9875; + long i9876; + long i9877; + long i9878; + long i9879; + long i9880; + long i9881; + long i9882; + long i9883; + long i9884; + long i9885; + long i9886; + long i9887; + long i9888; + long i9889; + long i9890; + long i9891; + long i9892; + long i9893; + long i9894; + long i9895; + long i9896; + long i9897; + long i9898; + long i9899; + long i9900; + long i9901; + long i9902; + long i9903; + long i9904; + long i9905; + long i9906; + long i9907; + long i9908; + long i9909; + long i9910; + long i9911; + long i9912; + long i9913; + long i9914; + long i9915; + long i9916; + long i9917; + long i9918; + long i9919; + long i9920; + long i9921; + long i9922; + long i9923; + long i9924; + long i9925; + long i9926; + long i9927; + long i9928; + long i9929; + long i9930; + long i9931; + long i9932; + long i9933; + long i9934; + long i9935; + long i9936; + long i9937; + long i9938; + long i9939; + long i9940; + long i9941; + long i9942; + long i9943; + long i9944; + long i9945; + long i9946; + long i9947; + long i9948; + long i9949; + long i9950; + long i9951; + long i9952; + long i9953; + long i9954; + long i9955; + long i9956; + long i9957; + long i9958; + long i9959; + long i9960; + long i9961; + long i9962; + long i9963; + long i9964; + long i9965; + long i9966; + long i9967; + long i9968; + long i9969; + long i9970; + long i9971; + long i9972; + long i9973; + long i9974; + long i9975; + long i9976; + long i9977; + long i9978; + long i9979; + long i9980; + long i9981; + long i9982; + long i9983; + long i9984; + long i9985; + long i9986; + long i9987; + long i9988; + long i9989; + long i9990; + long i9991; + long i9992; + long i9993; + long i9994; + long i9995; + long i9996; + long i9997; + long i9998; + long i9999; + long i10000; + long i10001; + long i10002; + long i10003; + long i10004; + long i10005; + long i10006; + long i10007; + long i10008; + long i10009; + long i10010; + long i10011; + long i10012; + long i10013; + long i10014; + long i10015; + long i10016; + long i10017; + long i10018; + long i10019; + long i10020; + long i10021; + long i10022; + long i10023; + long i10024; + long i10025; + long i10026; + long i10027; + long i10028; + long i10029; + long i10030; + long i10031; + long i10032; + long i10033; + long i10034; + long i10035; + long i10036; + long i10037; + long i10038; + long i10039; + long i10040; + long i10041; + long i10042; + long i10043; + long i10044; + long i10045; + long i10046; + long i10047; + long i10048; + long i10049; + long i10050; + long i10051; + long i10052; + long i10053; + long i10054; + long i10055; + long i10056; + long i10057; + long i10058; + long i10059; + long i10060; + long i10061; + long i10062; + long i10063; + long i10064; + long i10065; + long i10066; + long i10067; + long i10068; + long i10069; + long i10070; + long i10071; + long i10072; + long i10073; + long i10074; + long i10075; + long i10076; + long i10077; + long i10078; + long i10079; + long i10080; + long i10081; + long i10082; + long i10083; + long i10084; + long i10085; + long i10086; + long i10087; + long i10088; + long i10089; + long i10090; + long i10091; + long i10092; + long i10093; + long i10094; + long i10095; + long i10096; + long i10097; + long i10098; + long i10099; + long i10100; + long i10101; + long i10102; + long i10103; + long i10104; + long i10105; + long i10106; + long i10107; + long i10108; + long i10109; + long i10110; + long i10111; + long i10112; + long i10113; + long i10114; + long i10115; + long i10116; + long i10117; + long i10118; + long i10119; + long i10120; + long i10121; + long i10122; + long i10123; + long i10124; + long i10125; + long i10126; + long i10127; + long i10128; + long i10129; + long i10130; + long i10131; + long i10132; + long i10133; + long i10134; + long i10135; + long i10136; + long i10137; + long i10138; + long i10139; + long i10140; + long i10141; + long i10142; + long i10143; + long i10144; + long i10145; + long i10146; + long i10147; + long i10148; + long i10149; + long i10150; + long i10151; + long i10152; + long i10153; + long i10154; + long i10155; + long i10156; + long i10157; + long i10158; + long i10159; + long i10160; + long i10161; + long i10162; + long i10163; + long i10164; + long i10165; + long i10166; + long i10167; + long i10168; + long i10169; + long i10170; + long i10171; + long i10172; + long i10173; + long i10174; + long i10175; + long i10176; + long i10177; + long i10178; + long i10179; + long i10180; + long i10181; + long i10182; + long i10183; + long i10184; + long i10185; + long i10186; + long i10187; + long i10188; + long i10189; + long i10190; + long i10191; + long i10192; + long i10193; + long i10194; + long i10195; + long i10196; + long i10197; + long i10198; + long i10199; + long i10200; + long i10201; + long i10202; + long i10203; + long i10204; + long i10205; + long i10206; + long i10207; + long i10208; + long i10209; + long i10210; + long i10211; + long i10212; + long i10213; + long i10214; + long i10215; + long i10216; + long i10217; + long i10218; + long i10219; + long i10220; + long i10221; + long i10222; + long i10223; + long i10224; + long i10225; + long i10226; + long i10227; + long i10228; + long i10229; + long i10230; + long i10231; + long i10232; + long i10233; + long i10234; + long i10235; + long i10236; + long i10237; + long i10238; + long i10239; + long i10240; + long i10241; + long i10242; + long i10243; + long i10244; + long i10245; + long i10246; + long i10247; + long i10248; + long i10249; + long i10250; + long i10251; + long i10252; + long i10253; + long i10254; + long i10255; + long i10256; + long i10257; + long i10258; + long i10259; + long i10260; + long i10261; + long i10262; + long i10263; + long i10264; + long i10265; + long i10266; + long i10267; + long i10268; + long i10269; + long i10270; + long i10271; + long i10272; + long i10273; + long i10274; + long i10275; + long i10276; + long i10277; + long i10278; + long i10279; + long i10280; + long i10281; + long i10282; + long i10283; + long i10284; + long i10285; + long i10286; + long i10287; + long i10288; + long i10289; + long i10290; + long i10291; + long i10292; + long i10293; + long i10294; + long i10295; + long i10296; + long i10297; + long i10298; + long i10299; + long i10300; + long i10301; + long i10302; + long i10303; + long i10304; + long i10305; + long i10306; + long i10307; + long i10308; + long i10309; + long i10310; + long i10311; + long i10312; + long i10313; + long i10314; + long i10315; + long i10316; + long i10317; + long i10318; + long i10319; + long i10320; + long i10321; + long i10322; + long i10323; + long i10324; + long i10325; + long i10326; + long i10327; + long i10328; + long i10329; + long i10330; + long i10331; + long i10332; + long i10333; + long i10334; + long i10335; + long i10336; + long i10337; + long i10338; + long i10339; + long i10340; + long i10341; + long i10342; + long i10343; + long i10344; + long i10345; + long i10346; + long i10347; + long i10348; + long i10349; + long i10350; + long i10351; + long i10352; + long i10353; + long i10354; + long i10355; + long i10356; + long i10357; + long i10358; + long i10359; + long i10360; + long i10361; + long i10362; + long i10363; + long i10364; + long i10365; + long i10366; + long i10367; + long i10368; + long i10369; + long i10370; + long i10371; + long i10372; + long i10373; + long i10374; + long i10375; + long i10376; + long i10377; + long i10378; + long i10379; + long i10380; + long i10381; + long i10382; + long i10383; + long i10384; + long i10385; + long i10386; + long i10387; + long i10388; + long i10389; + long i10390; + long i10391; + long i10392; + long i10393; + long i10394; + long i10395; + long i10396; + long i10397; + long i10398; + long i10399; + long i10400; + long i10401; + long i10402; + long i10403; + long i10404; + long i10405; + long i10406; + long i10407; + long i10408; + long i10409; + long i10410; + long i10411; + long i10412; + long i10413; + long i10414; + long i10415; + long i10416; + long i10417; + long i10418; + long i10419; + long i10420; + long i10421; + long i10422; + long i10423; + long i10424; + long i10425; + long i10426; + long i10427; + long i10428; + long i10429; + long i10430; + long i10431; + long i10432; + long i10433; + long i10434; + long i10435; + long i10436; + long i10437; + long i10438; + long i10439; + long i10440; + long i10441; + long i10442; + long i10443; + long i10444; + long i10445; + long i10446; + long i10447; + long i10448; + long i10449; + long i10450; + long i10451; + long i10452; + long i10453; + long i10454; + long i10455; + long i10456; + long i10457; + long i10458; + long i10459; + long i10460; + long i10461; + long i10462; + long i10463; + long i10464; + long i10465; + long i10466; + long i10467; + long i10468; + long i10469; + long i10470; + long i10471; + long i10472; + long i10473; + long i10474; + long i10475; + long i10476; + long i10477; + long i10478; + long i10479; + long i10480; + long i10481; + long i10482; + long i10483; + long i10484; + long i10485; + long i10486; + long i10487; + long i10488; + long i10489; + long i10490; + long i10491; + long i10492; + long i10493; + long i10494; + long i10495; + long i10496; + long i10497; + long i10498; + long i10499; + long i10500; + long i10501; + long i10502; + long i10503; + long i10504; + long i10505; + long i10506; + long i10507; + long i10508; + long i10509; + long i10510; + long i10511; + long i10512; + long i10513; + long i10514; + long i10515; + long i10516; + long i10517; + long i10518; + long i10519; + long i10520; + long i10521; + long i10522; + long i10523; + long i10524; + long i10525; + long i10526; + long i10527; + long i10528; + long i10529; + long i10530; + long i10531; + long i10532; + long i10533; + long i10534; + long i10535; + long i10536; + long i10537; + long i10538; + long i10539; + long i10540; + long i10541; + long i10542; + long i10543; + long i10544; + long i10545; + long i10546; + long i10547; + long i10548; + long i10549; + long i10550; + long i10551; + long i10552; + long i10553; + long i10554; + long i10555; + long i10556; + long i10557; + long i10558; + long i10559; + long i10560; + long i10561; + long i10562; + long i10563; + long i10564; + long i10565; + long i10566; + long i10567; + long i10568; + long i10569; + long i10570; + long i10571; + long i10572; + long i10573; + long i10574; + long i10575; + long i10576; + long i10577; + long i10578; + long i10579; + long i10580; + long i10581; + long i10582; + long i10583; + long i10584; + long i10585; + long i10586; + long i10587; + long i10588; + long i10589; + long i10590; + long i10591; + long i10592; + long i10593; + long i10594; + long i10595; + long i10596; + long i10597; + long i10598; + long i10599; + long i10600; + long i10601; + long i10602; + long i10603; + long i10604; + long i10605; + long i10606; + long i10607; + long i10608; + long i10609; + long i10610; + long i10611; + long i10612; + long i10613; + long i10614; + long i10615; + long i10616; + long i10617; + long i10618; + long i10619; + long i10620; + long i10621; + long i10622; + long i10623; + long i10624; + long i10625; + long i10626; + long i10627; + long i10628; + long i10629; + long i10630; + long i10631; + long i10632; + long i10633; + long i10634; + long i10635; + long i10636; + long i10637; + long i10638; + long i10639; + long i10640; + long i10641; + long i10642; + long i10643; + long i10644; + long i10645; + long i10646; + long i10647; + long i10648; + long i10649; + long i10650; + long i10651; + long i10652; + long i10653; + long i10654; + long i10655; + long i10656; + long i10657; + long i10658; + long i10659; + long i10660; + long i10661; + long i10662; + long i10663; + long i10664; + long i10665; + long i10666; + long i10667; + long i10668; + long i10669; + long i10670; + long i10671; + long i10672; + long i10673; + long i10674; + long i10675; + long i10676; + long i10677; + long i10678; + long i10679; + long i10680; + long i10681; + long i10682; + long i10683; + long i10684; + long i10685; + long i10686; + long i10687; + long i10688; + long i10689; + long i10690; + long i10691; + long i10692; + long i10693; + long i10694; + long i10695; + long i10696; + long i10697; + long i10698; + long i10699; + long i10700; + long i10701; + long i10702; + long i10703; + long i10704; + long i10705; + long i10706; + long i10707; + long i10708; + long i10709; + long i10710; + long i10711; + long i10712; + long i10713; + long i10714; + long i10715; + long i10716; + long i10717; + long i10718; + long i10719; + long i10720; + long i10721; + long i10722; + long i10723; + long i10724; + long i10725; + long i10726; + long i10727; + long i10728; + long i10729; + long i10730; + long i10731; + long i10732; + long i10733; + long i10734; + long i10735; + long i10736; + long i10737; + long i10738; + long i10739; + long i10740; + long i10741; + long i10742; + long i10743; + long i10744; + long i10745; + long i10746; + long i10747; + long i10748; + long i10749; + long i10750; + long i10751; + long i10752; + long i10753; + long i10754; + long i10755; + long i10756; + long i10757; + long i10758; + long i10759; + long i10760; + long i10761; + long i10762; + long i10763; + long i10764; + long i10765; + long i10766; + long i10767; + long i10768; + long i10769; + long i10770; + long i10771; + long i10772; + long i10773; + long i10774; + long i10775; + long i10776; + long i10777; + long i10778; + long i10779; + long i10780; + long i10781; + long i10782; + long i10783; + long i10784; + long i10785; + long i10786; + long i10787; + long i10788; + long i10789; + long i10790; + long i10791; + long i10792; + long i10793; + long i10794; + long i10795; + long i10796; + long i10797; + long i10798; + long i10799; + long i10800; + long i10801; + long i10802; + long i10803; + long i10804; + long i10805; + long i10806; + long i10807; + long i10808; + long i10809; + long i10810; + long i10811; + long i10812; + long i10813; + long i10814; + long i10815; + long i10816; + long i10817; + long i10818; + long i10819; + long i10820; + long i10821; + long i10822; + long i10823; + long i10824; + long i10825; + long i10826; + long i10827; + long i10828; + long i10829; + long i10830; + long i10831; + long i10832; + long i10833; + long i10834; + long i10835; + long i10836; + long i10837; + long i10838; + long i10839; + long i10840; + long i10841; + long i10842; + long i10843; + long i10844; + long i10845; + long i10846; + long i10847; + long i10848; + long i10849; + long i10850; + long i10851; + long i10852; + long i10853; + long i10854; + long i10855; + long i10856; + long i10857; + long i10858; + long i10859; + long i10860; + long i10861; + long i10862; + long i10863; + long i10864; + long i10865; + long i10866; + long i10867; + long i10868; + long i10869; + long i10870; + long i10871; + long i10872; + long i10873; + long i10874; + long i10875; + long i10876; + long i10877; + long i10878; + long i10879; + long i10880; + long i10881; + long i10882; + long i10883; + long i10884; + long i10885; + long i10886; + long i10887; + long i10888; + long i10889; + long i10890; + long i10891; + long i10892; + long i10893; + long i10894; + long i10895; + long i10896; + long i10897; + long i10898; + long i10899; + long i10900; + long i10901; + long i10902; + long i10903; + long i10904; + long i10905; + long i10906; + long i10907; + long i10908; + long i10909; + long i10910; + long i10911; + long i10912; + long i10913; + long i10914; + long i10915; + long i10916; + long i10917; + long i10918; + long i10919; + long i10920; + long i10921; + long i10922; + long i10923; + long i10924; + long i10925; + long i10926; + long i10927; + long i10928; + long i10929; + long i10930; + long i10931; + long i10932; + long i10933; + long i10934; + long i10935; + long i10936; + long i10937; + long i10938; + long i10939; + long i10940; + long i10941; + long i10942; + long i10943; + long i10944; + long i10945; + long i10946; + long i10947; + long i10948; + long i10949; + long i10950; + long i10951; + long i10952; + long i10953; + long i10954; + long i10955; + long i10956; + long i10957; + long i10958; + long i10959; + long i10960; + long i10961; + long i10962; + long i10963; + long i10964; + long i10965; + long i10966; + long i10967; + long i10968; + long i10969; + long i10970; + long i10971; + long i10972; + long i10973; + long i10974; + long i10975; + long i10976; + long i10977; + long i10978; + long i10979; + long i10980; + long i10981; + long i10982; + long i10983; + long i10984; + long i10985; + long i10986; + long i10987; + long i10988; + long i10989; + long i10990; + long i10991; + long i10992; + long i10993; + long i10994; + long i10995; + long i10996; + long i10997; + long i10998; + long i10999; + long i11000; + long i11001; + long i11002; + long i11003; + long i11004; + long i11005; + long i11006; + long i11007; + long i11008; + long i11009; + long i11010; + long i11011; + long i11012; + long i11013; + long i11014; + long i11015; + long i11016; + long i11017; + long i11018; + long i11019; + long i11020; + long i11021; + long i11022; + long i11023; + long i11024; + long i11025; + long i11026; + long i11027; + long i11028; + long i11029; + long i11030; + long i11031; + long i11032; + long i11033; + long i11034; + long i11035; + long i11036; + long i11037; + long i11038; + long i11039; + long i11040; + long i11041; + long i11042; + long i11043; + long i11044; + long i11045; + long i11046; + long i11047; + long i11048; + long i11049; + long i11050; + long i11051; + long i11052; + long i11053; + long i11054; + long i11055; + long i11056; + long i11057; + long i11058; + long i11059; + long i11060; + long i11061; + long i11062; + long i11063; + long i11064; + long i11065; + long i11066; + long i11067; + long i11068; + long i11069; + long i11070; + long i11071; + long i11072; + long i11073; + long i11074; + long i11075; + long i11076; + long i11077; + long i11078; + long i11079; + long i11080; + long i11081; + long i11082; + long i11083; + long i11084; + long i11085; + long i11086; + long i11087; + long i11088; + long i11089; + long i11090; + long i11091; + long i11092; + long i11093; + long i11094; + long i11095; + long i11096; + long i11097; + long i11098; + long i11099; + long i11100; + long i11101; + long i11102; + long i11103; + long i11104; + long i11105; + long i11106; + long i11107; + long i11108; + long i11109; + long i11110; + long i11111; + long i11112; + long i11113; + long i11114; + long i11115; + long i11116; + long i11117; + long i11118; + long i11119; + long i11120; + long i11121; + long i11122; + long i11123; + long i11124; + long i11125; + long i11126; + long i11127; + long i11128; + long i11129; + long i11130; + long i11131; + long i11132; + long i11133; + long i11134; + long i11135; + long i11136; + long i11137; + long i11138; + long i11139; + long i11140; + long i11141; + long i11142; + long i11143; + long i11144; + long i11145; + long i11146; + long i11147; + long i11148; + long i11149; + long i11150; + long i11151; + long i11152; + long i11153; + long i11154; + long i11155; + long i11156; + long i11157; + long i11158; + long i11159; + long i11160; + long i11161; + long i11162; + long i11163; + long i11164; + long i11165; + long i11166; + long i11167; + long i11168; + long i11169; + long i11170; + long i11171; + long i11172; + long i11173; + long i11174; + long i11175; + long i11176; + long i11177; + long i11178; + long i11179; + long i11180; + long i11181; + long i11182; + long i11183; + long i11184; + long i11185; + long i11186; + long i11187; + long i11188; + long i11189; + long i11190; + long i11191; + long i11192; + long i11193; + long i11194; + long i11195; + long i11196; + long i11197; + long i11198; + long i11199; + long i11200; + long i11201; + long i11202; + long i11203; + long i11204; + long i11205; + long i11206; + long i11207; + long i11208; + long i11209; + long i11210; + long i11211; + long i11212; + long i11213; + long i11214; + long i11215; + long i11216; + long i11217; + long i11218; + long i11219; + long i11220; + long i11221; + long i11222; + long i11223; + long i11224; + long i11225; + long i11226; + long i11227; + long i11228; + long i11229; + long i11230; + long i11231; + long i11232; + long i11233; + long i11234; + long i11235; + long i11236; + long i11237; + long i11238; + long i11239; + long i11240; + long i11241; + long i11242; + long i11243; + long i11244; + long i11245; + long i11246; + long i11247; + long i11248; + long i11249; + long i11250; + long i11251; + long i11252; + long i11253; + long i11254; + long i11255; + long i11256; + long i11257; + long i11258; + long i11259; + long i11260; + long i11261; + long i11262; + long i11263; + long i11264; + long i11265; + long i11266; + long i11267; + long i11268; + long i11269; + long i11270; + long i11271; + long i11272; + long i11273; + long i11274; + long i11275; + long i11276; + long i11277; + long i11278; + long i11279; + long i11280; + long i11281; + long i11282; + long i11283; + long i11284; + long i11285; + long i11286; + long i11287; + long i11288; + long i11289; + long i11290; + long i11291; + long i11292; + long i11293; + long i11294; + long i11295; + long i11296; + long i11297; + long i11298; + long i11299; + long i11300; + long i11301; + long i11302; + long i11303; + long i11304; + long i11305; + long i11306; + long i11307; + long i11308; + long i11309; + long i11310; + long i11311; + long i11312; + long i11313; + long i11314; + long i11315; + long i11316; + long i11317; + long i11318; + long i11319; + long i11320; + long i11321; + long i11322; + long i11323; + long i11324; + long i11325; + long i11326; + long i11327; + long i11328; + long i11329; + long i11330; + long i11331; + long i11332; + long i11333; + long i11334; + long i11335; + long i11336; + long i11337; + long i11338; + long i11339; + long i11340; + long i11341; + long i11342; + long i11343; + long i11344; + long i11345; + long i11346; + long i11347; + long i11348; + long i11349; + long i11350; + long i11351; + long i11352; + long i11353; + long i11354; + long i11355; + long i11356; + long i11357; + long i11358; + long i11359; + long i11360; + long i11361; + long i11362; + long i11363; + long i11364; + long i11365; + long i11366; + long i11367; + long i11368; + long i11369; + long i11370; + long i11371; + long i11372; + long i11373; + long i11374; + long i11375; + long i11376; + long i11377; + long i11378; + long i11379; + long i11380; + long i11381; + long i11382; + long i11383; + long i11384; + long i11385; + long i11386; + long i11387; + long i11388; + long i11389; + long i11390; + long i11391; + long i11392; + long i11393; + long i11394; + long i11395; + long i11396; + long i11397; + long i11398; + long i11399; + long i11400; + long i11401; + long i11402; + long i11403; + long i11404; + long i11405; + long i11406; + long i11407; + long i11408; + long i11409; + long i11410; + long i11411; + long i11412; + long i11413; + long i11414; + long i11415; + long i11416; + long i11417; + long i11418; + long i11419; + long i11420; + long i11421; + long i11422; + long i11423; + long i11424; + long i11425; + long i11426; + long i11427; + long i11428; + long i11429; + long i11430; + long i11431; + long i11432; + long i11433; + long i11434; + long i11435; + long i11436; + long i11437; + long i11438; + long i11439; + long i11440; + long i11441; + long i11442; + long i11443; + long i11444; + long i11445; + long i11446; + long i11447; + long i11448; + long i11449; + long i11450; + long i11451; + long i11452; + long i11453; + long i11454; + long i11455; + long i11456; + long i11457; + long i11458; + long i11459; + long i11460; + long i11461; + long i11462; + long i11463; + long i11464; + long i11465; + long i11466; + long i11467; + long i11468; + long i11469; + long i11470; + long i11471; + long i11472; + long i11473; + long i11474; + long i11475; + long i11476; + long i11477; + long i11478; + long i11479; + long i11480; + long i11481; + long i11482; + long i11483; + long i11484; + long i11485; + long i11486; + long i11487; + long i11488; + long i11489; + long i11490; + long i11491; + long i11492; + long i11493; + long i11494; + long i11495; + long i11496; + long i11497; + long i11498; + long i11499; + long i11500; + long i11501; + long i11502; + long i11503; + long i11504; + long i11505; + long i11506; + long i11507; + long i11508; + long i11509; + long i11510; + long i11511; + long i11512; + long i11513; + long i11514; + long i11515; + long i11516; + long i11517; + long i11518; + long i11519; + long i11520; + long i11521; + long i11522; + long i11523; + long i11524; + long i11525; + long i11526; + long i11527; + long i11528; + long i11529; + long i11530; + long i11531; + long i11532; + long i11533; + long i11534; + long i11535; + long i11536; + long i11537; + long i11538; + long i11539; + long i11540; + long i11541; + long i11542; + long i11543; + long i11544; + long i11545; + long i11546; + long i11547; + long i11548; + long i11549; + long i11550; + long i11551; + long i11552; + long i11553; + long i11554; + long i11555; + long i11556; + long i11557; + long i11558; + long i11559; + long i11560; + long i11561; + long i11562; + long i11563; + long i11564; + long i11565; + long i11566; + long i11567; + long i11568; + long i11569; + long i11570; + long i11571; + long i11572; + long i11573; + long i11574; + long i11575; + long i11576; + long i11577; + long i11578; + long i11579; + long i11580; + long i11581; + long i11582; + long i11583; + long i11584; + long i11585; + long i11586; + long i11587; + long i11588; + long i11589; + long i11590; + long i11591; + long i11592; + long i11593; + long i11594; + long i11595; + long i11596; + long i11597; + long i11598; + long i11599; + long i11600; + long i11601; + long i11602; + long i11603; + long i11604; + long i11605; + long i11606; + long i11607; + long i11608; + long i11609; + long i11610; + long i11611; + long i11612; + long i11613; + long i11614; + long i11615; + long i11616; + long i11617; + long i11618; + long i11619; + long i11620; + long i11621; + long i11622; + long i11623; + long i11624; + long i11625; + long i11626; + long i11627; + long i11628; + long i11629; + long i11630; + long i11631; + long i11632; + long i11633; + long i11634; + long i11635; + long i11636; + long i11637; + long i11638; + long i11639; + long i11640; + long i11641; + long i11642; + long i11643; + long i11644; + long i11645; + long i11646; + long i11647; + long i11648; + long i11649; + long i11650; + long i11651; + long i11652; + long i11653; + long i11654; + long i11655; + long i11656; + long i11657; + long i11658; + long i11659; + long i11660; + long i11661; + long i11662; + long i11663; + long i11664; + long i11665; + long i11666; + long i11667; + long i11668; + long i11669; + long i11670; + long i11671; + long i11672; + long i11673; + long i11674; + long i11675; + long i11676; + long i11677; + long i11678; + long i11679; + long i11680; + long i11681; + long i11682; + long i11683; + long i11684; + long i11685; + long i11686; + long i11687; + long i11688; + long i11689; + long i11690; + long i11691; + long i11692; + long i11693; + long i11694; + long i11695; + long i11696; + long i11697; + long i11698; + long i11699; + long i11700; + long i11701; + long i11702; + long i11703; + long i11704; + long i11705; + long i11706; + long i11707; + long i11708; + long i11709; + long i11710; + long i11711; + long i11712; + long i11713; + long i11714; + long i11715; + long i11716; + long i11717; + long i11718; + long i11719; + long i11720; + long i11721; + long i11722; + long i11723; + long i11724; + long i11725; + long i11726; + long i11727; + long i11728; + long i11729; + long i11730; + long i11731; + long i11732; + long i11733; + long i11734; + long i11735; + long i11736; + long i11737; + long i11738; + long i11739; + long i11740; + long i11741; + long i11742; + long i11743; + long i11744; + long i11745; + long i11746; + long i11747; + long i11748; + long i11749; + long i11750; + long i11751; + long i11752; + long i11753; + long i11754; + long i11755; + long i11756; + long i11757; + long i11758; + long i11759; + long i11760; + long i11761; + long i11762; + long i11763; + long i11764; + long i11765; + long i11766; + long i11767; + long i11768; + long i11769; + long i11770; + long i11771; + long i11772; + long i11773; + long i11774; + long i11775; + long i11776; + long i11777; + long i11778; + long i11779; + long i11780; + long i11781; + long i11782; + long i11783; + long i11784; + long i11785; + long i11786; + long i11787; + long i11788; + long i11789; + long i11790; + long i11791; + long i11792; + long i11793; + long i11794; + long i11795; + long i11796; + long i11797; + long i11798; + long i11799; + long i11800; + long i11801; + long i11802; + long i11803; + long i11804; + long i11805; + long i11806; + long i11807; + long i11808; + long i11809; + long i11810; + long i11811; + long i11812; + long i11813; + long i11814; + long i11815; + long i11816; + long i11817; + long i11818; + long i11819; + long i11820; + long i11821; + long i11822; + long i11823; + long i11824; + long i11825; + long i11826; + long i11827; + long i11828; + long i11829; + long i11830; + long i11831; + long i11832; + long i11833; + long i11834; + long i11835; + long i11836; + long i11837; + long i11838; + long i11839; + long i11840; + long i11841; + long i11842; + long i11843; + long i11844; + long i11845; + long i11846; + long i11847; + long i11848; + long i11849; + long i11850; + long i11851; + long i11852; + long i11853; + long i11854; + long i11855; + long i11856; + long i11857; + long i11858; + long i11859; + long i11860; + long i11861; + long i11862; + long i11863; + long i11864; + long i11865; + long i11866; + long i11867; + long i11868; + long i11869; + long i11870; + long i11871; + long i11872; + long i11873; + long i11874; + long i11875; + long i11876; + long i11877; + long i11878; + long i11879; + long i11880; + long i11881; + long i11882; + long i11883; + long i11884; + long i11885; + long i11886; + long i11887; + long i11888; + long i11889; + long i11890; + long i11891; + long i11892; + long i11893; + long i11894; + long i11895; + long i11896; + long i11897; + long i11898; + long i11899; + long i11900; + long i11901; + long i11902; + long i11903; + long i11904; + long i11905; + long i11906; + long i11907; + long i11908; + long i11909; + long i11910; + long i11911; + long i11912; + long i11913; + long i11914; + long i11915; + long i11916; + long i11917; + long i11918; + long i11919; + long i11920; + long i11921; + long i11922; + long i11923; + long i11924; + long i11925; + long i11926; + long i11927; + long i11928; + long i11929; + long i11930; + long i11931; + long i11932; + long i11933; + long i11934; + long i11935; + long i11936; + long i11937; + long i11938; + long i11939; + long i11940; + long i11941; + long i11942; + long i11943; + long i11944; + long i11945; + long i11946; + long i11947; + long i11948; + long i11949; + long i11950; + long i11951; + long i11952; + long i11953; + long i11954; + long i11955; + long i11956; + long i11957; + long i11958; + long i11959; + long i11960; + long i11961; + long i11962; + long i11963; + long i11964; + long i11965; + long i11966; + long i11967; + long i11968; + long i11969; + long i11970; + long i11971; + long i11972; + long i11973; + long i11974; + long i11975; + long i11976; + long i11977; + long i11978; + long i11979; + long i11980; + long i11981; + long i11982; + long i11983; + long i11984; + long i11985; + long i11986; + long i11987; + long i11988; + long i11989; + long i11990; + long i11991; + long i11992; + long i11993; + long i11994; + long i11995; + long i11996; + long i11997; + long i11998; + long i11999; + long i12000; + long i12001; + long i12002; + long i12003; + long i12004; + long i12005; + long i12006; + long i12007; + long i12008; + long i12009; + long i12010; + long i12011; + long i12012; + long i12013; + long i12014; + long i12015; + long i12016; + long i12017; + long i12018; + long i12019; + long i12020; + long i12021; + long i12022; + long i12023; + long i12024; + long i12025; + long i12026; + long i12027; + long i12028; + long i12029; + long i12030; + long i12031; + long i12032; + long i12033; + long i12034; + long i12035; + long i12036; + long i12037; + long i12038; + long i12039; + long i12040; + long i12041; + long i12042; + long i12043; + long i12044; + long i12045; + long i12046; + long i12047; + long i12048; + long i12049; + long i12050; + long i12051; + long i12052; + long i12053; + long i12054; + long i12055; + long i12056; + long i12057; + long i12058; + long i12059; + long i12060; + long i12061; + long i12062; + long i12063; + long i12064; + long i12065; + long i12066; + long i12067; + long i12068; + long i12069; + long i12070; + long i12071; + long i12072; + long i12073; + long i12074; + long i12075; + long i12076; + long i12077; + long i12078; + long i12079; + long i12080; + long i12081; + long i12082; + long i12083; + long i12084; + long i12085; + long i12086; + long i12087; + long i12088; + long i12089; + long i12090; + long i12091; + long i12092; + long i12093; + long i12094; + long i12095; + long i12096; + long i12097; + long i12098; + long i12099; + long i12100; + long i12101; + long i12102; + long i12103; + long i12104; + long i12105; + long i12106; + long i12107; + long i12108; + long i12109; + long i12110; + long i12111; + long i12112; + long i12113; + long i12114; + long i12115; + long i12116; + long i12117; + long i12118; + long i12119; + long i12120; + long i12121; + long i12122; + long i12123; + long i12124; + long i12125; + long i12126; + long i12127; + long i12128; + long i12129; + long i12130; + long i12131; + long i12132; + long i12133; + long i12134; + long i12135; + long i12136; + long i12137; + long i12138; + long i12139; + long i12140; + long i12141; + long i12142; + long i12143; + long i12144; + long i12145; + long i12146; + long i12147; + long i12148; + long i12149; + long i12150; + long i12151; + long i12152; + long i12153; + long i12154; + long i12155; + long i12156; + long i12157; + long i12158; + long i12159; + long i12160; + long i12161; + long i12162; + long i12163; + long i12164; + long i12165; + long i12166; + long i12167; + long i12168; + long i12169; + long i12170; + long i12171; + long i12172; + long i12173; + long i12174; + long i12175; + long i12176; + long i12177; + long i12178; + long i12179; + long i12180; + long i12181; + long i12182; + long i12183; + long i12184; + long i12185; + long i12186; + long i12187; + long i12188; + long i12189; + long i12190; + long i12191; + long i12192; + long i12193; + long i12194; + long i12195; + long i12196; + long i12197; + long i12198; + long i12199; + long i12200; + long i12201; + long i12202; + long i12203; + long i12204; + long i12205; + long i12206; + long i12207; + long i12208; + long i12209; + long i12210; + long i12211; + long i12212; + long i12213; + long i12214; + long i12215; + long i12216; + long i12217; + long i12218; + long i12219; + long i12220; + long i12221; + long i12222; + long i12223; + long i12224; + long i12225; + long i12226; + long i12227; + long i12228; + long i12229; + long i12230; + long i12231; + long i12232; + long i12233; + long i12234; + long i12235; + long i12236; + long i12237; + long i12238; + long i12239; + long i12240; + long i12241; + long i12242; + long i12243; + long i12244; + long i12245; + long i12246; + long i12247; + long i12248; + long i12249; + long i12250; + long i12251; + long i12252; + long i12253; + long i12254; + long i12255; + long i12256; + long i12257; + long i12258; + long i12259; + long i12260; + long i12261; + long i12262; + long i12263; + long i12264; + long i12265; + long i12266; + long i12267; + long i12268; + long i12269; + long i12270; + long i12271; + long i12272; + long i12273; + long i12274; + long i12275; + long i12276; + long i12277; + long i12278; + long i12279; + long i12280; + long i12281; + long i12282; + long i12283; + long i12284; + long i12285; + long i12286; + long i12287; + long i12288; + long i12289; + long i12290; + long i12291; + long i12292; + long i12293; + long i12294; + long i12295; + long i12296; + long i12297; + long i12298; + long i12299; + long i12300; + long i12301; + long i12302; + long i12303; + long i12304; + long i12305; + long i12306; + long i12307; + long i12308; + long i12309; + long i12310; + long i12311; + long i12312; + long i12313; + long i12314; + long i12315; + long i12316; + long i12317; + long i12318; + long i12319; + long i12320; + long i12321; + long i12322; + long i12323; + long i12324; + long i12325; + long i12326; + long i12327; + long i12328; + long i12329; + long i12330; + long i12331; + long i12332; + long i12333; + long i12334; + long i12335; + long i12336; + long i12337; + long i12338; + long i12339; + long i12340; + long i12341; + long i12342; + long i12343; + long i12344; + long i12345; + long i12346; + long i12347; + long i12348; + long i12349; + long i12350; + long i12351; + long i12352; + long i12353; + long i12354; + long i12355; + long i12356; + long i12357; + long i12358; + long i12359; + long i12360; + long i12361; + long i12362; + long i12363; + long i12364; + long i12365; + long i12366; + long i12367; + long i12368; + long i12369; + long i12370; + long i12371; + long i12372; + long i12373; + long i12374; + long i12375; + long i12376; + long i12377; + long i12378; + long i12379; + long i12380; + long i12381; + long i12382; + long i12383; + long i12384; + long i12385; + long i12386; + long i12387; + long i12388; + long i12389; + long i12390; + long i12391; + long i12392; + long i12393; + long i12394; + long i12395; + long i12396; + long i12397; + long i12398; + long i12399; + long i12400; + long i12401; + long i12402; + long i12403; + long i12404; + long i12405; + long i12406; + long i12407; + long i12408; + long i12409; + long i12410; + long i12411; + long i12412; + long i12413; + long i12414; + long i12415; + long i12416; + long i12417; + long i12418; + long i12419; + long i12420; + long i12421; + long i12422; + long i12423; + long i12424; + long i12425; + long i12426; + long i12427; + long i12428; + long i12429; + long i12430; + long i12431; + long i12432; + long i12433; + long i12434; + long i12435; + long i12436; + long i12437; + long i12438; + long i12439; + long i12440; + long i12441; + long i12442; + long i12443; + long i12444; + long i12445; + long i12446; + long i12447; + long i12448; + long i12449; + long i12450; + long i12451; + long i12452; + long i12453; + long i12454; + long i12455; + long i12456; + long i12457; + long i12458; + long i12459; + long i12460; + long i12461; + long i12462; + long i12463; + long i12464; + long i12465; + long i12466; + long i12467; + long i12468; + long i12469; + long i12470; + long i12471; + long i12472; + long i12473; + long i12474; + long i12475; + long i12476; + long i12477; + long i12478; + long i12479; + long i12480; + long i12481; + long i12482; + long i12483; + long i12484; + long i12485; + long i12486; + long i12487; + long i12488; + long i12489; + long i12490; + long i12491; + long i12492; + long i12493; + long i12494; + long i12495; + long i12496; + long i12497; + long i12498; + long i12499; + long i12500; + long i12501; + long i12502; + long i12503; + long i12504; + long i12505; + long i12506; + long i12507; + long i12508; + long i12509; + long i12510; + long i12511; + long i12512; + long i12513; + long i12514; + long i12515; + long i12516; + long i12517; + long i12518; + long i12519; + long i12520; + long i12521; + long i12522; + long i12523; + long i12524; + long i12525; + long i12526; + long i12527; + long i12528; + long i12529; + long i12530; + long i12531; + long i12532; + long i12533; + long i12534; + long i12535; + long i12536; + long i12537; + long i12538; + long i12539; + long i12540; + long i12541; + long i12542; + long i12543; + long i12544; + long i12545; + long i12546; + long i12547; + long i12548; + long i12549; + long i12550; + long i12551; + long i12552; + long i12553; + long i12554; + long i12555; + long i12556; + long i12557; + long i12558; + long i12559; + long i12560; + long i12561; + long i12562; + long i12563; + long i12564; + long i12565; + long i12566; + long i12567; + long i12568; + long i12569; + long i12570; + long i12571; + long i12572; + long i12573; + long i12574; + long i12575; + long i12576; + long i12577; + long i12578; + long i12579; + long i12580; + long i12581; + long i12582; + long i12583; + long i12584; + long i12585; + long i12586; + long i12587; + long i12588; + long i12589; + long i12590; + long i12591; + long i12592; + long i12593; + long i12594; + long i12595; + long i12596; + long i12597; + long i12598; + long i12599; + long i12600; + long i12601; + long i12602; + long i12603; + long i12604; + long i12605; + long i12606; + long i12607; + long i12608; + long i12609; + long i12610; + long i12611; + long i12612; + long i12613; + long i12614; + long i12615; + long i12616; + long i12617; + long i12618; + long i12619; + long i12620; + long i12621; + long i12622; + long i12623; + long i12624; + long i12625; + long i12626; + long i12627; + long i12628; + long i12629; + long i12630; + long i12631; + long i12632; + long i12633; + long i12634; + long i12635; + long i12636; + long i12637; + long i12638; + long i12639; + long i12640; + long i12641; + long i12642; + long i12643; + long i12644; + long i12645; + long i12646; + long i12647; + long i12648; + long i12649; + long i12650; + long i12651; + long i12652; + long i12653; + long i12654; + long i12655; + long i12656; + long i12657; + long i12658; + long i12659; + long i12660; + long i12661; + long i12662; + long i12663; + long i12664; + long i12665; + long i12666; + long i12667; + long i12668; + long i12669; + long i12670; + long i12671; + long i12672; + long i12673; + long i12674; + long i12675; + long i12676; + long i12677; + long i12678; + long i12679; + long i12680; + long i12681; + long i12682; + long i12683; + long i12684; + long i12685; + long i12686; + long i12687; + long i12688; + long i12689; + long i12690; + long i12691; + long i12692; + long i12693; + long i12694; + long i12695; + long i12696; + long i12697; + long i12698; + long i12699; + long i12700; + long i12701; + long i12702; + long i12703; + long i12704; + long i12705; + long i12706; + long i12707; + long i12708; + long i12709; + long i12710; + long i12711; + long i12712; + long i12713; + long i12714; + long i12715; + long i12716; + long i12717; + long i12718; + long i12719; + long i12720; + long i12721; + long i12722; + long i12723; + long i12724; + long i12725; + long i12726; + long i12727; + long i12728; + long i12729; + long i12730; + long i12731; + long i12732; + long i12733; + long i12734; + long i12735; + long i12736; + long i12737; + long i12738; + long i12739; + long i12740; + long i12741; + long i12742; + long i12743; + long i12744; + long i12745; + long i12746; + long i12747; + long i12748; + long i12749; + long i12750; + long i12751; + long i12752; + long i12753; + long i12754; + long i12755; + long i12756; + long i12757; + long i12758; + long i12759; + long i12760; + long i12761; + long i12762; + long i12763; + long i12764; + long i12765; + long i12766; + long i12767; + long i12768; + long i12769; + long i12770; + long i12771; + long i12772; + long i12773; + long i12774; + long i12775; + long i12776; + long i12777; + long i12778; + long i12779; + long i12780; + long i12781; + long i12782; + long i12783; + long i12784; + long i12785; + long i12786; + long i12787; + long i12788; + long i12789; + long i12790; + long i12791; + long i12792; + long i12793; + long i12794; + long i12795; + long i12796; + long i12797; + long i12798; + long i12799; + long i12800; + long i12801; + long i12802; + long i12803; + long i12804; + long i12805; + long i12806; + long i12807; + long i12808; + long i12809; + long i12810; + long i12811; + long i12812; + long i12813; + long i12814; + long i12815; + long i12816; + long i12817; + long i12818; + long i12819; + long i12820; + long i12821; + long i12822; + long i12823; + long i12824; + long i12825; + long i12826; + long i12827; + long i12828; + long i12829; + long i12830; + long i12831; + long i12832; + long i12833; + long i12834; + long i12835; + long i12836; + long i12837; + long i12838; + long i12839; + long i12840; + long i12841; + long i12842; + long i12843; + long i12844; + long i12845; + long i12846; + long i12847; + long i12848; + long i12849; + long i12850; + long i12851; + long i12852; + long i12853; + long i12854; + long i12855; + long i12856; + long i12857; + long i12858; + long i12859; + long i12860; + long i12861; + long i12862; + long i12863; + long i12864; + long i12865; + long i12866; + long i12867; + long i12868; + long i12869; + long i12870; + long i12871; + long i12872; + long i12873; + long i12874; + long i12875; + long i12876; + long i12877; + long i12878; + long i12879; + long i12880; + long i12881; + long i12882; + long i12883; + long i12884; + long i12885; + long i12886; + long i12887; + long i12888; + long i12889; + long i12890; + long i12891; + long i12892; + long i12893; + long i12894; + long i12895; + long i12896; + long i12897; + long i12898; + long i12899; + long i12900; + long i12901; + long i12902; + long i12903; + long i12904; + long i12905; + long i12906; + long i12907; + long i12908; + long i12909; + long i12910; + long i12911; + long i12912; + long i12913; + long i12914; + long i12915; + long i12916; + long i12917; + long i12918; + long i12919; + long i12920; + long i12921; + long i12922; + long i12923; + long i12924; + long i12925; + long i12926; + long i12927; + long i12928; + long i12929; + long i12930; + long i12931; + long i12932; + long i12933; + long i12934; + long i12935; + long i12936; + long i12937; + long i12938; + long i12939; + long i12940; + long i12941; + long i12942; + long i12943; + long i12944; + long i12945; + long i12946; + long i12947; + long i12948; + long i12949; + long i12950; + long i12951; + long i12952; + long i12953; + long i12954; + long i12955; + long i12956; + long i12957; + long i12958; + long i12959; + long i12960; + long i12961; + long i12962; + long i12963; + long i12964; + long i12965; + long i12966; + long i12967; + long i12968; + long i12969; + long i12970; + long i12971; + long i12972; + long i12973; + long i12974; + long i12975; + long i12976; + long i12977; + long i12978; + long i12979; + long i12980; + long i12981; + long i12982; + long i12983; + long i12984; + long i12985; + long i12986; + long i12987; + long i12988; + long i12989; + long i12990; + long i12991; + long i12992; + long i12993; + long i12994; + long i12995; + long i12996; + long i12997; + long i12998; + long i12999; + long i13000; + long i13001; + long i13002; + long i13003; + long i13004; + long i13005; + long i13006; + long i13007; + long i13008; + long i13009; + long i13010; + long i13011; + long i13012; + long i13013; + long i13014; + long i13015; + long i13016; + long i13017; + long i13018; + long i13019; + long i13020; + long i13021; + long i13022; + long i13023; + long i13024; + long i13025; + long i13026; + long i13027; + long i13028; + long i13029; + long i13030; + long i13031; + long i13032; + long i13033; + long i13034; + long i13035; + long i13036; + long i13037; + long i13038; + long i13039; + long i13040; + long i13041; + long i13042; + long i13043; + long i13044; + long i13045; + long i13046; + long i13047; + long i13048; + long i13049; + long i13050; + long i13051; + long i13052; + long i13053; + long i13054; + long i13055; + long i13056; + long i13057; + long i13058; + long i13059; + long i13060; + long i13061; + long i13062; + long i13063; + long i13064; + long i13065; + long i13066; + long i13067; + long i13068; + long i13069; + long i13070; + long i13071; + long i13072; + long i13073; + long i13074; + long i13075; + long i13076; + long i13077; + long i13078; + long i13079; + long i13080; + long i13081; + long i13082; + long i13083; + long i13084; + long i13085; + long i13086; + long i13087; + long i13088; + long i13089; + long i13090; + long i13091; + long i13092; + long i13093; + long i13094; + long i13095; + long i13096; + long i13097; + long i13098; + long i13099; + long i13100; + long i13101; + long i13102; + long i13103; + long i13104; + long i13105; + long i13106; + long i13107; + long i13108; + long i13109; + long i13110; + long i13111; + long i13112; + long i13113; + long i13114; + long i13115; + long i13116; + long i13117; + long i13118; + long i13119; + long i13120; + long i13121; + long i13122; + long i13123; + long i13124; + long i13125; + long i13126; + long i13127; + long i13128; + long i13129; + long i13130; + long i13131; + long i13132; + long i13133; + long i13134; + long i13135; + long i13136; + long i13137; + long i13138; + long i13139; + long i13140; + long i13141; + long i13142; + long i13143; + long i13144; + long i13145; + long i13146; + long i13147; + long i13148; + long i13149; + long i13150; + long i13151; + long i13152; + long i13153; + long i13154; + long i13155; + long i13156; + long i13157; + long i13158; + long i13159; + long i13160; + long i13161; + long i13162; + long i13163; + long i13164; + long i13165; + long i13166; + long i13167; + long i13168; + long i13169; + long i13170; + long i13171; + long i13172; + long i13173; + long i13174; + long i13175; + long i13176; + long i13177; + long i13178; + long i13179; + long i13180; + long i13181; + long i13182; + long i13183; + long i13184; + long i13185; + long i13186; + long i13187; + long i13188; + long i13189; + long i13190; + long i13191; + long i13192; + long i13193; + long i13194; + long i13195; + long i13196; + long i13197; + long i13198; + long i13199; + long i13200; + long i13201; + long i13202; + long i13203; + long i13204; + long i13205; + long i13206; + long i13207; + long i13208; + long i13209; + long i13210; + long i13211; + long i13212; + long i13213; + long i13214; + long i13215; + long i13216; + long i13217; + long i13218; + long i13219; + long i13220; + long i13221; + long i13222; + long i13223; + long i13224; + long i13225; + long i13226; + long i13227; + long i13228; + long i13229; + long i13230; + long i13231; + long i13232; + long i13233; + long i13234; + long i13235; + long i13236; + long i13237; + long i13238; + long i13239; + long i13240; + long i13241; + long i13242; + long i13243; + long i13244; + long i13245; + long i13246; + long i13247; + long i13248; + long i13249; + long i13250; + long i13251; + long i13252; + long i13253; + long i13254; + long i13255; + long i13256; + long i13257; + long i13258; + long i13259; + long i13260; + long i13261; + long i13262; + long i13263; + long i13264; + long i13265; + long i13266; + long i13267; + long i13268; + long i13269; + long i13270; + long i13271; + long i13272; + long i13273; + long i13274; + long i13275; + long i13276; + long i13277; + long i13278; + long i13279; + long i13280; + long i13281; + long i13282; + long i13283; + long i13284; + long i13285; + long i13286; + long i13287; + long i13288; + long i13289; + long i13290; + long i13291; + long i13292; + long i13293; + long i13294; + long i13295; + long i13296; + long i13297; + long i13298; + long i13299; + long i13300; + long i13301; + long i13302; + long i13303; + long i13304; + long i13305; + long i13306; + long i13307; + long i13308; + long i13309; + long i13310; + long i13311; + long i13312; + long i13313; + long i13314; + long i13315; + long i13316; + long i13317; + long i13318; + long i13319; + long i13320; + long i13321; + long i13322; + long i13323; + long i13324; + long i13325; + long i13326; + long i13327; + long i13328; + long i13329; + long i13330; + long i13331; + long i13332; + long i13333; + long i13334; + long i13335; + long i13336; + long i13337; + long i13338; + long i13339; + long i13340; + long i13341; + long i13342; + long i13343; + long i13344; + long i13345; + long i13346; + long i13347; + long i13348; + long i13349; + long i13350; + long i13351; + long i13352; + long i13353; + long i13354; + long i13355; + long i13356; + long i13357; + long i13358; + long i13359; + long i13360; + long i13361; + long i13362; + long i13363; + long i13364; + long i13365; + long i13366; + long i13367; + long i13368; + long i13369; + long i13370; + long i13371; + long i13372; + long i13373; + long i13374; + long i13375; + long i13376; + long i13377; + long i13378; + long i13379; + long i13380; + long i13381; + long i13382; + long i13383; + long i13384; + long i13385; + long i13386; + long i13387; + long i13388; + long i13389; + long i13390; + long i13391; + long i13392; + long i13393; + long i13394; + long i13395; + long i13396; + long i13397; + long i13398; + long i13399; + long i13400; + long i13401; + long i13402; + long i13403; + long i13404; + long i13405; + long i13406; + long i13407; + long i13408; + long i13409; + long i13410; + long i13411; + long i13412; + long i13413; + long i13414; + long i13415; + long i13416; + long i13417; + long i13418; + long i13419; + long i13420; + long i13421; + long i13422; + long i13423; + long i13424; + long i13425; + long i13426; + long i13427; + long i13428; + long i13429; + long i13430; + long i13431; + long i13432; + long i13433; + long i13434; + long i13435; + long i13436; + long i13437; + long i13438; + long i13439; + long i13440; + long i13441; + long i13442; + long i13443; + long i13444; + long i13445; + long i13446; + long i13447; + long i13448; + long i13449; + long i13450; + long i13451; + long i13452; + long i13453; + long i13454; + long i13455; + long i13456; + long i13457; + long i13458; + long i13459; + long i13460; + long i13461; + long i13462; + long i13463; + long i13464; + long i13465; + long i13466; + long i13467; + long i13468; + long i13469; + long i13470; + long i13471; + long i13472; + long i13473; + long i13474; + long i13475; + long i13476; + long i13477; + long i13478; + long i13479; + long i13480; + long i13481; + long i13482; + long i13483; + long i13484; + long i13485; + long i13486; + long i13487; + long i13488; + long i13489; + long i13490; + long i13491; + long i13492; + long i13493; + long i13494; + long i13495; + long i13496; + long i13497; + long i13498; + long i13499; + long i13500; + long i13501; + long i13502; + long i13503; + long i13504; + long i13505; + long i13506; + long i13507; + long i13508; + long i13509; + long i13510; + long i13511; + long i13512; + long i13513; + long i13514; + long i13515; + long i13516; + long i13517; + long i13518; + long i13519; + long i13520; + long i13521; + long i13522; + long i13523; + long i13524; + long i13525; + long i13526; + long i13527; + long i13528; + long i13529; + long i13530; + long i13531; + long i13532; + long i13533; + long i13534; + long i13535; + long i13536; + long i13537; + long i13538; + long i13539; + long i13540; + long i13541; + long i13542; + long i13543; + long i13544; + long i13545; + long i13546; + long i13547; + long i13548; + long i13549; + long i13550; + long i13551; + long i13552; + long i13553; + long i13554; + long i13555; + long i13556; + long i13557; + long i13558; + long i13559; + long i13560; + long i13561; + long i13562; + long i13563; + long i13564; + long i13565; + long i13566; + long i13567; + long i13568; + long i13569; + long i13570; + long i13571; + long i13572; + long i13573; + long i13574; + long i13575; + long i13576; + long i13577; + long i13578; + long i13579; + long i13580; + long i13581; + long i13582; + long i13583; + long i13584; + long i13585; + long i13586; + long i13587; + long i13588; + long i13589; + long i13590; + long i13591; + long i13592; + long i13593; + long i13594; + long i13595; + long i13596; + long i13597; + long i13598; + long i13599; + long i13600; + long i13601; + long i13602; + long i13603; + long i13604; + long i13605; + long i13606; + long i13607; + long i13608; + long i13609; + long i13610; + long i13611; + long i13612; + long i13613; + long i13614; + long i13615; + long i13616; + long i13617; + long i13618; + long i13619; + long i13620; + long i13621; + long i13622; + long i13623; + long i13624; + long i13625; + long i13626; + long i13627; + long i13628; + long i13629; + long i13630; + long i13631; + long i13632; + long i13633; + long i13634; + long i13635; + long i13636; + long i13637; + long i13638; + long i13639; + long i13640; + long i13641; + long i13642; + long i13643; + long i13644; + long i13645; + long i13646; + long i13647; + long i13648; + long i13649; + long i13650; + long i13651; + long i13652; + long i13653; + long i13654; + long i13655; + long i13656; + long i13657; + long i13658; + long i13659; + long i13660; + long i13661; + long i13662; + long i13663; + long i13664; + long i13665; + long i13666; + long i13667; + long i13668; + long i13669; + long i13670; + long i13671; + long i13672; + long i13673; + long i13674; + long i13675; + long i13676; + long i13677; + long i13678; + long i13679; + long i13680; + long i13681; + long i13682; + long i13683; + long i13684; + long i13685; + long i13686; + long i13687; + long i13688; + long i13689; + long i13690; + long i13691; + long i13692; + long i13693; + long i13694; + long i13695; + long i13696; + long i13697; + long i13698; + long i13699; + long i13700; + long i13701; + long i13702; + long i13703; + long i13704; + long i13705; + long i13706; + long i13707; + long i13708; + long i13709; + long i13710; + long i13711; + long i13712; + long i13713; + long i13714; + long i13715; + long i13716; + long i13717; + long i13718; + long i13719; + long i13720; + long i13721; + long i13722; + long i13723; + long i13724; + long i13725; + long i13726; + long i13727; + long i13728; + long i13729; + long i13730; + long i13731; + long i13732; + long i13733; + long i13734; + long i13735; + long i13736; + long i13737; + long i13738; + long i13739; + long i13740; + long i13741; + long i13742; + long i13743; + long i13744; + long i13745; + long i13746; + long i13747; + long i13748; + long i13749; + long i13750; + long i13751; + long i13752; + long i13753; + long i13754; + long i13755; + long i13756; + long i13757; + long i13758; + long i13759; + long i13760; + long i13761; + long i13762; + long i13763; + long i13764; + long i13765; + long i13766; + long i13767; + long i13768; + long i13769; + long i13770; + long i13771; + long i13772; + long i13773; + long i13774; + long i13775; + long i13776; + long i13777; + long i13778; + long i13779; + long i13780; + long i13781; + long i13782; + long i13783; + long i13784; + long i13785; + long i13786; + long i13787; + long i13788; + long i13789; + long i13790; + long i13791; + long i13792; + long i13793; + long i13794; + long i13795; + long i13796; + long i13797; + long i13798; + long i13799; + long i13800; + long i13801; + long i13802; + long i13803; + long i13804; + long i13805; + long i13806; + long i13807; + long i13808; + long i13809; + long i13810; + long i13811; + long i13812; + long i13813; + long i13814; + long i13815; + long i13816; + long i13817; + long i13818; + long i13819; + long i13820; + long i13821; + long i13822; + long i13823; + long i13824; + long i13825; + long i13826; + long i13827; + long i13828; + long i13829; + long i13830; + long i13831; + long i13832; + long i13833; + long i13834; + long i13835; + long i13836; + long i13837; + long i13838; + long i13839; + long i13840; + long i13841; + long i13842; + long i13843; + long i13844; + long i13845; + long i13846; + long i13847; + long i13848; + long i13849; + long i13850; + long i13851; + long i13852; + long i13853; + long i13854; + long i13855; + long i13856; + long i13857; + long i13858; + long i13859; + long i13860; + long i13861; + long i13862; + long i13863; + long i13864; + long i13865; + long i13866; + long i13867; + long i13868; + long i13869; + long i13870; + long i13871; + long i13872; + long i13873; + long i13874; + long i13875; + long i13876; + long i13877; + long i13878; + long i13879; + long i13880; + long i13881; + long i13882; + long i13883; + long i13884; + long i13885; + long i13886; + long i13887; + long i13888; + long i13889; + long i13890; + long i13891; + long i13892; + long i13893; + long i13894; + long i13895; + long i13896; + long i13897; + long i13898; + long i13899; + long i13900; + long i13901; + long i13902; + long i13903; + long i13904; + long i13905; + long i13906; + long i13907; + long i13908; + long i13909; + long i13910; + long i13911; + long i13912; + long i13913; + long i13914; + long i13915; + long i13916; + long i13917; + long i13918; + long i13919; + long i13920; + long i13921; + long i13922; + long i13923; + long i13924; + long i13925; + long i13926; + long i13927; + long i13928; + long i13929; + long i13930; + long i13931; + long i13932; + long i13933; + long i13934; + long i13935; + long i13936; + long i13937; + long i13938; + long i13939; + long i13940; + long i13941; + long i13942; + long i13943; + long i13944; + long i13945; + long i13946; + long i13947; + long i13948; + long i13949; + long i13950; + long i13951; + long i13952; + long i13953; + long i13954; + long i13955; + long i13956; + long i13957; + long i13958; + long i13959; + long i13960; + long i13961; + long i13962; + long i13963; + long i13964; + long i13965; + long i13966; + long i13967; + long i13968; + long i13969; + long i13970; + long i13971; + long i13972; + long i13973; + long i13974; + long i13975; + long i13976; + long i13977; + long i13978; + long i13979; + long i13980; + long i13981; + long i13982; + long i13983; + long i13984; + long i13985; + long i13986; + long i13987; + long i13988; + long i13989; + long i13990; + long i13991; + long i13992; + long i13993; + long i13994; + long i13995; + long i13996; + long i13997; + long i13998; + long i13999; + long i14000; + long i14001; + long i14002; + long i14003; + long i14004; + long i14005; + long i14006; + long i14007; + long i14008; + long i14009; + long i14010; + long i14011; + long i14012; + long i14013; + long i14014; + long i14015; + long i14016; + long i14017; + long i14018; + long i14019; + long i14020; + long i14021; + long i14022; + long i14023; + long i14024; + long i14025; + long i14026; + long i14027; + long i14028; + long i14029; + long i14030; + long i14031; + long i14032; + long i14033; + long i14034; + long i14035; + long i14036; + long i14037; + long i14038; + long i14039; + long i14040; + long i14041; + long i14042; + long i14043; + long i14044; + long i14045; + long i14046; + long i14047; + long i14048; + long i14049; + long i14050; + long i14051; + long i14052; + long i14053; + long i14054; + long i14055; + long i14056; + long i14057; + long i14058; + long i14059; + long i14060; + long i14061; + long i14062; + long i14063; + long i14064; + long i14065; + long i14066; + long i14067; + long i14068; + long i14069; + long i14070; + long i14071; + long i14072; + long i14073; + long i14074; + long i14075; + long i14076; + long i14077; + long i14078; + long i14079; + long i14080; + long i14081; + long i14082; + long i14083; + long i14084; + long i14085; + long i14086; + long i14087; + long i14088; + long i14089; + long i14090; + long i14091; + long i14092; + long i14093; + long i14094; + long i14095; + long i14096; + long i14097; + long i14098; + long i14099; + long i14100; + long i14101; + long i14102; + long i14103; + long i14104; + long i14105; + long i14106; + long i14107; + long i14108; + long i14109; + long i14110; + long i14111; + long i14112; + long i14113; + long i14114; + long i14115; + long i14116; + long i14117; + long i14118; + long i14119; + long i14120; + long i14121; + long i14122; + long i14123; + long i14124; + long i14125; + long i14126; + long i14127; + long i14128; + long i14129; + long i14130; + long i14131; + long i14132; + long i14133; + long i14134; + long i14135; + long i14136; + long i14137; + long i14138; + long i14139; + long i14140; + long i14141; + long i14142; + long i14143; + long i14144; + long i14145; + long i14146; + long i14147; + long i14148; + long i14149; + long i14150; + long i14151; + long i14152; + long i14153; + long i14154; + long i14155; + long i14156; + long i14157; + long i14158; + long i14159; + long i14160; + long i14161; + long i14162; + long i14163; + long i14164; + long i14165; + long i14166; + long i14167; + long i14168; + long i14169; + long i14170; + long i14171; + long i14172; + long i14173; + long i14174; + long i14175; + long i14176; + long i14177; + long i14178; + long i14179; + long i14180; + long i14181; + long i14182; + long i14183; + long i14184; + long i14185; + long i14186; + long i14187; + long i14188; + long i14189; + long i14190; + long i14191; + long i14192; + long i14193; + long i14194; + long i14195; + long i14196; + long i14197; + long i14198; + long i14199; + long i14200; + long i14201; + long i14202; + long i14203; + long i14204; + long i14205; + long i14206; + long i14207; + long i14208; + long i14209; + long i14210; + long i14211; + long i14212; + long i14213; + long i14214; + long i14215; + long i14216; + long i14217; + long i14218; + long i14219; + long i14220; + long i14221; + long i14222; + long i14223; + long i14224; + long i14225; + long i14226; + long i14227; + long i14228; + long i14229; + long i14230; + long i14231; + long i14232; + long i14233; + long i14234; + long i14235; + long i14236; + long i14237; + long i14238; + long i14239; + long i14240; + long i14241; + long i14242; + long i14243; + long i14244; + long i14245; + long i14246; + long i14247; + long i14248; + long i14249; + long i14250; + long i14251; + long i14252; + long i14253; + long i14254; + long i14255; + long i14256; + long i14257; + long i14258; + long i14259; + long i14260; + long i14261; + long i14262; + long i14263; + long i14264; + long i14265; + long i14266; + long i14267; + long i14268; + long i14269; + long i14270; + long i14271; + long i14272; + long i14273; + long i14274; + long i14275; + long i14276; + long i14277; + long i14278; + long i14279; + long i14280; + long i14281; + long i14282; + long i14283; + long i14284; + long i14285; + long i14286; + long i14287; + long i14288; + long i14289; + long i14290; + long i14291; + long i14292; + long i14293; + long i14294; + long i14295; + long i14296; + long i14297; + long i14298; + long i14299; + long i14300; + long i14301; + long i14302; + long i14303; + long i14304; + long i14305; + long i14306; + long i14307; + long i14308; + long i14309; + long i14310; + long i14311; + long i14312; + long i14313; + long i14314; + long i14315; + long i14316; + long i14317; + long i14318; + long i14319; + long i14320; + long i14321; + long i14322; + long i14323; + long i14324; + long i14325; + long i14326; + long i14327; + long i14328; + long i14329; + long i14330; + long i14331; + long i14332; + long i14333; + long i14334; + long i14335; + long i14336; + long i14337; + long i14338; + long i14339; + long i14340; + long i14341; + long i14342; + long i14343; + long i14344; + long i14345; + long i14346; + long i14347; + long i14348; + long i14349; + long i14350; + long i14351; + long i14352; + long i14353; + long i14354; + long i14355; + long i14356; + long i14357; + long i14358; + long i14359; + long i14360; + long i14361; + long i14362; + long i14363; + long i14364; + long i14365; + long i14366; + long i14367; + long i14368; + long i14369; + long i14370; + long i14371; + long i14372; + long i14373; + long i14374; + long i14375; + long i14376; + long i14377; + long i14378; + long i14379; + long i14380; + long i14381; + long i14382; + long i14383; + long i14384; + long i14385; + long i14386; + long i14387; + long i14388; + long i14389; + long i14390; + long i14391; + long i14392; + long i14393; + long i14394; + long i14395; + long i14396; + long i14397; + long i14398; + long i14399; + long i14400; + long i14401; + long i14402; + long i14403; + long i14404; + long i14405; + long i14406; + long i14407; + long i14408; + long i14409; + long i14410; + long i14411; + long i14412; + long i14413; + long i14414; + long i14415; + long i14416; + long i14417; + long i14418; + long i14419; + long i14420; + long i14421; + long i14422; + long i14423; + long i14424; + long i14425; + long i14426; + long i14427; + long i14428; + long i14429; + long i14430; + long i14431; + long i14432; + long i14433; + long i14434; + long i14435; + long i14436; + long i14437; + long i14438; + long i14439; + long i14440; + long i14441; + long i14442; + long i14443; + long i14444; + long i14445; + long i14446; + long i14447; + long i14448; + long i14449; + long i14450; + long i14451; + long i14452; + long i14453; + long i14454; + long i14455; + long i14456; + long i14457; + long i14458; + long i14459; + long i14460; + long i14461; + long i14462; + long i14463; + long i14464; + long i14465; + long i14466; + long i14467; + long i14468; + long i14469; + long i14470; + long i14471; + long i14472; + long i14473; + long i14474; + long i14475; + long i14476; + long i14477; + long i14478; + long i14479; + long i14480; + long i14481; + long i14482; + long i14483; + long i14484; + long i14485; + long i14486; + long i14487; + long i14488; + long i14489; + long i14490; + long i14491; + long i14492; + long i14493; + long i14494; + long i14495; + long i14496; + long i14497; + long i14498; + long i14499; + long i14500; + long i14501; + long i14502; + long i14503; + long i14504; + long i14505; + long i14506; + long i14507; + long i14508; + long i14509; + long i14510; + long i14511; + long i14512; + long i14513; + long i14514; + long i14515; + long i14516; + long i14517; + long i14518; + long i14519; + long i14520; + long i14521; + long i14522; + long i14523; + long i14524; + long i14525; + long i14526; + long i14527; + long i14528; + long i14529; + long i14530; + long i14531; + long i14532; + long i14533; + long i14534; + long i14535; + long i14536; + long i14537; + long i14538; + long i14539; + long i14540; + long i14541; + long i14542; + long i14543; + long i14544; + long i14545; + long i14546; + long i14547; + long i14548; + long i14549; + long i14550; + long i14551; + long i14552; + long i14553; + long i14554; + long i14555; + long i14556; + long i14557; + long i14558; + long i14559; + long i14560; + long i14561; + long i14562; + long i14563; + long i14564; + long i14565; + long i14566; + long i14567; + long i14568; + long i14569; + long i14570; + long i14571; + long i14572; + long i14573; + long i14574; + long i14575; + long i14576; + long i14577; + long i14578; + long i14579; + long i14580; + long i14581; + long i14582; + long i14583; + long i14584; + long i14585; + long i14586; + long i14587; + long i14588; + long i14589; + long i14590; + long i14591; + long i14592; + long i14593; + long i14594; + long i14595; + long i14596; + long i14597; + long i14598; + long i14599; + long i14600; + long i14601; + long i14602; + long i14603; + long i14604; + long i14605; + long i14606; + long i14607; + long i14608; + long i14609; + long i14610; + long i14611; + long i14612; + long i14613; + long i14614; + long i14615; + long i14616; + long i14617; + long i14618; + long i14619; + long i14620; + long i14621; + long i14622; + long i14623; + long i14624; + long i14625; + long i14626; + long i14627; + long i14628; + long i14629; + long i14630; + long i14631; + long i14632; + long i14633; + long i14634; + long i14635; + long i14636; + long i14637; + long i14638; + long i14639; + long i14640; + long i14641; + long i14642; + long i14643; + long i14644; + long i14645; + long i14646; + long i14647; + long i14648; + long i14649; + long i14650; + long i14651; + long i14652; + long i14653; + long i14654; + long i14655; + long i14656; + long i14657; + long i14658; + long i14659; + long i14660; + long i14661; + long i14662; + long i14663; + long i14664; + long i14665; + long i14666; + long i14667; + long i14668; + long i14669; + long i14670; + long i14671; + long i14672; + long i14673; + long i14674; + long i14675; + long i14676; + long i14677; + long i14678; + long i14679; + long i14680; + long i14681; + long i14682; + long i14683; + long i14684; + long i14685; + long i14686; + long i14687; + long i14688; + long i14689; + long i14690; + long i14691; + long i14692; + long i14693; + long i14694; + long i14695; + long i14696; + long i14697; + long i14698; + long i14699; + long i14700; + long i14701; + long i14702; + long i14703; + long i14704; + long i14705; + long i14706; + long i14707; + long i14708; + long i14709; + long i14710; + long i14711; + long i14712; + long i14713; + long i14714; + long i14715; + long i14716; + long i14717; + long i14718; + long i14719; + long i14720; + long i14721; + long i14722; + long i14723; + long i14724; + long i14725; + long i14726; + long i14727; + long i14728; + long i14729; + long i14730; + long i14731; + long i14732; + long i14733; + long i14734; + long i14735; + long i14736; + long i14737; + long i14738; + long i14739; + long i14740; + long i14741; + long i14742; + long i14743; + long i14744; + long i14745; + long i14746; + long i14747; + long i14748; + long i14749; + long i14750; + long i14751; + long i14752; + long i14753; + long i14754; + long i14755; + long i14756; + long i14757; + long i14758; + long i14759; + long i14760; + long i14761; + long i14762; + long i14763; + long i14764; + long i14765; + long i14766; + long i14767; + long i14768; + long i14769; + long i14770; + long i14771; + long i14772; + long i14773; + long i14774; + long i14775; + long i14776; + long i14777; + long i14778; + long i14779; + long i14780; + long i14781; + long i14782; + long i14783; + long i14784; + long i14785; + long i14786; + long i14787; + long i14788; + long i14789; + long i14790; + long i14791; + long i14792; + long i14793; + long i14794; + long i14795; + long i14796; + long i14797; + long i14798; + long i14799; + long i14800; + long i14801; + long i14802; + long i14803; + long i14804; + long i14805; + long i14806; + long i14807; + long i14808; + long i14809; + long i14810; + long i14811; + long i14812; + long i14813; + long i14814; + long i14815; + long i14816; + long i14817; + long i14818; + long i14819; + long i14820; + long i14821; + long i14822; + long i14823; + long i14824; + long i14825; + long i14826; + long i14827; + long i14828; + long i14829; + long i14830; + long i14831; + long i14832; + long i14833; + long i14834; + long i14835; + long i14836; + long i14837; + long i14838; + long i14839; + long i14840; + long i14841; + long i14842; + long i14843; + long i14844; + long i14845; + long i14846; + long i14847; + long i14848; + long i14849; + long i14850; + long i14851; + long i14852; + long i14853; + long i14854; + long i14855; + long i14856; + long i14857; + long i14858; + long i14859; + long i14860; + long i14861; + long i14862; + long i14863; + long i14864; + long i14865; + long i14866; + long i14867; + long i14868; + long i14869; + long i14870; + long i14871; + long i14872; + long i14873; + long i14874; + long i14875; + long i14876; + long i14877; + long i14878; + long i14879; + long i14880; + long i14881; + long i14882; + long i14883; + long i14884; + long i14885; + long i14886; + long i14887; + long i14888; + long i14889; + long i14890; + long i14891; + long i14892; + long i14893; + long i14894; + long i14895; + long i14896; + long i14897; + long i14898; + long i14899; + long i14900; + long i14901; + long i14902; + long i14903; + long i14904; + long i14905; + long i14906; + long i14907; + long i14908; + long i14909; + long i14910; + long i14911; + long i14912; + long i14913; + long i14914; + long i14915; + long i14916; + long i14917; + long i14918; + long i14919; + long i14920; + long i14921; + long i14922; + long i14923; + long i14924; + long i14925; + long i14926; + long i14927; + long i14928; + long i14929; + long i14930; + long i14931; + long i14932; + long i14933; + long i14934; + long i14935; + long i14936; + long i14937; + long i14938; + long i14939; + long i14940; + long i14941; + long i14942; + long i14943; + long i14944; + long i14945; + long i14946; + long i14947; + long i14948; + long i14949; + long i14950; + long i14951; + long i14952; + long i14953; + long i14954; + long i14955; + long i14956; + long i14957; + long i14958; + long i14959; + long i14960; + long i14961; + long i14962; + long i14963; + long i14964; + long i14965; + long i14966; + long i14967; + long i14968; + long i14969; + long i14970; + long i14971; + long i14972; + long i14973; + long i14974; + long i14975; + long i14976; + long i14977; + long i14978; + long i14979; + long i14980; + long i14981; + long i14982; + long i14983; + long i14984; + long i14985; + long i14986; + long i14987; + long i14988; + long i14989; + long i14990; + long i14991; + long i14992; + long i14993; + long i14994; + long i14995; + long i14996; + long i14997; + long i14998; + long i14999; + long i15000; + long i15001; + long i15002; + long i15003; + long i15004; + long i15005; + long i15006; + long i15007; + long i15008; + long i15009; + long i15010; + long i15011; + long i15012; + long i15013; + long i15014; + long i15015; + long i15016; + long i15017; + long i15018; + long i15019; + long i15020; + long i15021; + long i15022; + long i15023; + long i15024; + long i15025; + long i15026; + long i15027; + long i15028; + long i15029; + long i15030; + long i15031; + long i15032; + long i15033; + long i15034; + long i15035; + long i15036; + long i15037; + long i15038; + long i15039; + long i15040; + long i15041; + long i15042; + long i15043; + long i15044; + long i15045; + long i15046; + long i15047; + long i15048; + long i15049; + long i15050; + long i15051; + long i15052; + long i15053; + long i15054; + long i15055; + long i15056; + long i15057; + long i15058; + long i15059; + long i15060; + long i15061; + long i15062; + long i15063; + long i15064; + long i15065; + long i15066; + long i15067; + long i15068; + long i15069; + long i15070; + long i15071; + long i15072; + long i15073; + long i15074; + long i15075; + long i15076; + long i15077; + long i15078; + long i15079; + long i15080; + long i15081; + long i15082; + long i15083; + long i15084; + long i15085; + long i15086; + long i15087; + long i15088; + long i15089; + long i15090; + long i15091; + long i15092; + long i15093; + long i15094; + long i15095; + long i15096; + long i15097; + long i15098; + long i15099; + long i15100; + long i15101; + long i15102; + long i15103; + long i15104; + long i15105; + long i15106; + long i15107; + long i15108; + long i15109; + long i15110; + long i15111; + long i15112; + long i15113; + long i15114; + long i15115; + long i15116; + long i15117; + long i15118; + long i15119; + long i15120; + long i15121; + long i15122; + long i15123; + long i15124; + long i15125; + long i15126; + long i15127; + long i15128; + long i15129; + long i15130; + long i15131; + long i15132; + long i15133; + long i15134; + long i15135; + long i15136; + long i15137; + long i15138; + long i15139; + long i15140; + long i15141; + long i15142; + long i15143; + long i15144; + long i15145; + long i15146; + long i15147; + long i15148; + long i15149; + long i15150; + long i15151; + long i15152; + long i15153; + long i15154; + long i15155; + long i15156; + long i15157; + long i15158; + long i15159; + long i15160; + long i15161; + long i15162; + long i15163; + long i15164; + long i15165; + long i15166; + long i15167; + long i15168; + long i15169; + long i15170; + long i15171; + long i15172; + long i15173; + long i15174; + long i15175; + long i15176; + long i15177; + long i15178; + long i15179; + long i15180; + long i15181; + long i15182; + long i15183; + long i15184; + long i15185; + long i15186; + long i15187; + long i15188; + long i15189; + long i15190; + long i15191; + long i15192; + long i15193; + long i15194; + long i15195; + long i15196; + long i15197; + long i15198; + long i15199; + long i15200; + long i15201; + long i15202; + long i15203; + long i15204; + long i15205; + long i15206; + long i15207; + long i15208; + long i15209; + long i15210; + long i15211; + long i15212; + long i15213; + long i15214; + long i15215; + long i15216; + long i15217; + long i15218; + long i15219; + long i15220; + long i15221; + long i15222; + long i15223; + long i15224; + long i15225; + long i15226; + long i15227; + long i15228; + long i15229; + long i15230; + long i15231; + long i15232; + long i15233; + long i15234; + long i15235; + long i15236; + long i15237; + long i15238; + long i15239; + long i15240; + long i15241; + long i15242; + long i15243; + long i15244; + long i15245; + long i15246; + long i15247; + long i15248; + long i15249; + long i15250; + long i15251; + long i15252; + long i15253; + long i15254; + long i15255; + long i15256; + long i15257; + long i15258; + long i15259; + long i15260; + long i15261; + long i15262; + long i15263; + long i15264; + long i15265; + long i15266; + long i15267; + long i15268; + long i15269; + long i15270; + long i15271; + long i15272; + long i15273; + long i15274; + long i15275; + long i15276; + long i15277; + long i15278; + long i15279; + long i15280; + long i15281; + long i15282; + long i15283; + long i15284; + long i15285; + long i15286; + long i15287; + long i15288; + long i15289; + long i15290; + long i15291; + long i15292; + long i15293; + long i15294; + long i15295; + long i15296; + long i15297; + long i15298; + long i15299; + long i15300; + long i15301; + long i15302; + long i15303; + long i15304; + long i15305; + long i15306; + long i15307; + long i15308; + long i15309; + long i15310; + long i15311; + long i15312; + long i15313; + long i15314; + long i15315; + long i15316; + long i15317; + long i15318; + long i15319; + long i15320; + long i15321; + long i15322; + long i15323; + long i15324; + long i15325; + long i15326; + long i15327; + long i15328; + long i15329; + long i15330; + long i15331; + long i15332; + long i15333; + long i15334; + long i15335; + long i15336; + long i15337; + long i15338; + long i15339; + long i15340; + long i15341; + long i15342; + long i15343; + long i15344; + long i15345; + long i15346; + long i15347; + long i15348; + long i15349; + long i15350; + long i15351; + long i15352; + long i15353; + long i15354; + long i15355; + long i15356; + long i15357; + long i15358; + long i15359; + long i15360; + long i15361; + long i15362; + long i15363; + long i15364; + long i15365; + long i15366; + long i15367; + long i15368; + long i15369; + long i15370; + long i15371; + long i15372; + long i15373; + long i15374; + long i15375; + long i15376; + long i15377; + long i15378; + long i15379; + long i15380; + long i15381; + long i15382; + long i15383; + long i15384; + long i15385; + long i15386; + long i15387; + long i15388; + long i15389; + long i15390; + long i15391; + long i15392; + long i15393; + long i15394; + long i15395; + long i15396; + long i15397; + long i15398; + long i15399; + long i15400; + long i15401; + long i15402; + long i15403; + long i15404; + long i15405; + long i15406; + long i15407; + long i15408; + long i15409; + long i15410; + long i15411; + long i15412; + long i15413; + long i15414; + long i15415; + long i15416; + long i15417; + long i15418; + long i15419; + long i15420; + long i15421; + long i15422; + long i15423; + long i15424; + long i15425; + long i15426; + long i15427; + long i15428; + long i15429; + long i15430; + long i15431; + long i15432; + long i15433; + long i15434; + long i15435; + long i15436; + long i15437; + long i15438; + long i15439; + long i15440; + long i15441; + long i15442; + long i15443; + long i15444; + long i15445; + long i15446; + long i15447; + long i15448; + long i15449; + long i15450; + long i15451; + long i15452; + long i15453; + long i15454; + long i15455; + long i15456; + long i15457; + long i15458; + long i15459; + long i15460; + long i15461; + long i15462; + long i15463; + long i15464; + long i15465; + long i15466; + long i15467; + long i15468; + long i15469; + long i15470; + long i15471; + long i15472; + long i15473; + long i15474; + long i15475; + long i15476; + long i15477; + long i15478; + long i15479; + long i15480; + long i15481; + long i15482; + long i15483; + long i15484; + long i15485; + long i15486; + long i15487; + long i15488; + long i15489; + long i15490; + long i15491; + long i15492; + long i15493; + long i15494; + long i15495; + long i15496; + long i15497; + long i15498; + long i15499; + long i15500; + long i15501; + long i15502; + long i15503; + long i15504; + long i15505; + long i15506; + long i15507; + long i15508; + long i15509; + long i15510; + long i15511; + long i15512; + long i15513; + long i15514; + long i15515; + long i15516; + long i15517; + long i15518; + long i15519; + long i15520; + long i15521; + long i15522; + long i15523; + long i15524; + long i15525; + long i15526; + long i15527; + long i15528; + long i15529; + long i15530; + long i15531; + long i15532; + long i15533; + long i15534; + long i15535; + long i15536; + long i15537; + long i15538; + long i15539; + long i15540; + long i15541; + long i15542; + long i15543; + long i15544; + long i15545; + long i15546; + long i15547; + long i15548; + long i15549; + long i15550; + long i15551; + long i15552; + long i15553; + long i15554; + long i15555; + long i15556; + long i15557; + long i15558; + long i15559; + long i15560; + long i15561; + long i15562; + long i15563; + long i15564; + long i15565; + long i15566; + long i15567; + long i15568; + long i15569; + long i15570; + long i15571; + long i15572; + long i15573; + long i15574; + long i15575; + long i15576; + long i15577; + long i15578; + long i15579; + long i15580; + long i15581; + long i15582; + long i15583; + long i15584; + long i15585; + long i15586; + long i15587; + long i15588; + long i15589; + long i15590; + long i15591; + long i15592; + long i15593; + long i15594; + long i15595; + long i15596; + long i15597; + long i15598; + long i15599; + long i15600; + long i15601; + long i15602; + long i15603; + long i15604; + long i15605; + long i15606; + long i15607; + long i15608; + long i15609; + long i15610; + long i15611; + long i15612; + long i15613; + long i15614; + long i15615; + long i15616; + long i15617; + long i15618; + long i15619; + long i15620; + long i15621; + long i15622; + long i15623; + long i15624; + long i15625; + long i15626; + long i15627; + long i15628; + long i15629; + long i15630; + long i15631; + long i15632; + long i15633; + long i15634; + long i15635; + long i15636; + long i15637; + long i15638; + long i15639; + long i15640; + long i15641; + long i15642; + long i15643; + long i15644; + long i15645; + long i15646; + long i15647; + long i15648; + long i15649; + long i15650; + long i15651; + long i15652; + long i15653; + long i15654; + long i15655; + long i15656; + long i15657; + long i15658; + long i15659; + long i15660; + long i15661; + long i15662; + long i15663; + long i15664; + long i15665; + long i15666; + long i15667; + long i15668; + long i15669; + long i15670; + long i15671; + long i15672; + long i15673; + long i15674; + long i15675; + long i15676; + long i15677; + long i15678; + long i15679; + long i15680; + long i15681; + long i15682; + long i15683; + long i15684; + long i15685; + long i15686; + long i15687; + long i15688; + long i15689; + long i15690; + long i15691; + long i15692; + long i15693; + long i15694; + long i15695; + long i15696; + long i15697; + long i15698; + long i15699; + long i15700; + long i15701; + long i15702; + long i15703; + long i15704; + long i15705; + long i15706; + long i15707; + long i15708; + long i15709; + long i15710; + long i15711; + long i15712; + long i15713; + long i15714; + long i15715; + long i15716; + long i15717; + long i15718; + long i15719; + long i15720; + long i15721; + long i15722; + long i15723; + long i15724; + long i15725; + long i15726; + long i15727; + long i15728; + long i15729; + long i15730; + long i15731; + long i15732; + long i15733; + long i15734; + long i15735; + long i15736; + long i15737; + long i15738; + long i15739; + long i15740; + long i15741; + long i15742; + long i15743; + long i15744; + long i15745; + long i15746; + long i15747; + long i15748; + long i15749; + long i15750; + long i15751; + long i15752; + long i15753; + long i15754; + long i15755; + long i15756; + long i15757; + long i15758; + long i15759; + long i15760; + long i15761; + long i15762; + long i15763; + long i15764; + long i15765; + long i15766; + long i15767; + long i15768; + long i15769; + long i15770; + long i15771; + long i15772; + long i15773; + long i15774; + long i15775; + long i15776; + long i15777; + long i15778; + long i15779; + long i15780; + long i15781; + long i15782; + long i15783; + long i15784; + long i15785; + long i15786; + long i15787; + long i15788; + long i15789; + long i15790; + long i15791; + long i15792; + long i15793; + long i15794; + long i15795; + long i15796; + long i15797; + long i15798; + long i15799; + long i15800; + long i15801; + long i15802; + long i15803; + long i15804; + long i15805; + long i15806; + long i15807; + long i15808; + long i15809; + long i15810; + long i15811; + long i15812; + long i15813; + long i15814; + long i15815; + long i15816; + long i15817; + long i15818; + long i15819; + long i15820; + long i15821; + long i15822; + long i15823; + long i15824; + long i15825; + long i15826; + long i15827; + long i15828; + long i15829; + long i15830; + long i15831; + long i15832; + long i15833; + long i15834; + long i15835; + long i15836; + long i15837; + long i15838; + long i15839; + long i15840; + long i15841; + long i15842; + long i15843; + long i15844; + long i15845; + long i15846; + long i15847; + long i15848; + long i15849; + long i15850; + long i15851; + long i15852; + long i15853; + long i15854; + long i15855; + long i15856; + long i15857; + long i15858; + long i15859; + long i15860; + long i15861; + long i15862; + long i15863; + long i15864; + long i15865; + long i15866; + long i15867; + long i15868; + long i15869; + long i15870; + long i15871; + long i15872; + long i15873; + long i15874; + long i15875; + long i15876; + long i15877; + long i15878; + long i15879; + long i15880; + long i15881; + long i15882; + long i15883; + long i15884; + long i15885; + long i15886; + long i15887; + long i15888; + long i15889; + long i15890; + long i15891; + long i15892; + long i15893; + long i15894; + long i15895; + long i15896; + long i15897; + long i15898; + long i15899; + long i15900; + long i15901; + long i15902; + long i15903; + long i15904; + long i15905; + long i15906; + long i15907; + long i15908; + long i15909; + long i15910; + long i15911; + long i15912; + long i15913; + long i15914; + long i15915; + long i15916; + long i15917; + long i15918; + long i15919; + long i15920; + long i15921; + long i15922; + long i15923; + long i15924; + long i15925; + long i15926; + long i15927; + long i15928; + long i15929; + long i15930; + long i15931; + long i15932; + long i15933; + long i15934; + long i15935; + long i15936; + long i15937; + long i15938; + long i15939; + long i15940; + long i15941; + long i15942; + long i15943; + long i15944; + long i15945; + long i15946; + long i15947; + long i15948; + long i15949; + long i15950; + long i15951; + long i15952; + long i15953; + long i15954; + long i15955; + long i15956; + long i15957; + long i15958; + long i15959; + long i15960; + long i15961; + long i15962; + long i15963; + long i15964; + long i15965; + long i15966; + long i15967; + long i15968; + long i15969; + long i15970; + long i15971; + long i15972; + long i15973; + long i15974; + long i15975; + long i15976; + long i15977; + long i15978; + long i15979; + long i15980; + long i15981; + long i15982; + long i15983; + long i15984; + long i15985; + long i15986; + long i15987; + long i15988; + long i15989; + long i15990; + long i15991; + long i15992; + long i15993; + long i15994; + long i15995; + long i15996; + long i15997; + long i15998; + long i15999; + long i16000; + long i16001; + long i16002; + long i16003; + long i16004; + long i16005; + long i16006; + long i16007; + long i16008; + long i16009; + long i16010; + long i16011; + long i16012; + long i16013; + long i16014; + long i16015; + long i16016; + long i16017; + long i16018; + long i16019; + long i16020; + long i16021; + long i16022; + long i16023; + long i16024; + long i16025; + long i16026; + long i16027; + long i16028; + long i16029; + long i16030; + long i16031; + long i16032; + long i16033; + long i16034; + long i16035; + long i16036; + long i16037; + long i16038; + long i16039; + long i16040; + long i16041; + long i16042; + long i16043; + long i16044; + long i16045; + long i16046; + long i16047; + long i16048; + long i16049; + long i16050; + long i16051; + long i16052; + long i16053; + long i16054; + long i16055; + long i16056; + long i16057; + long i16058; + long i16059; + long i16060; + long i16061; + long i16062; + long i16063; + long i16064; + long i16065; + long i16066; + long i16067; + long i16068; + long i16069; + long i16070; + long i16071; + long i16072; + long i16073; + long i16074; + long i16075; + long i16076; + long i16077; + long i16078; + long i16079; + long i16080; + long i16081; + long i16082; + long i16083; + long i16084; + long i16085; + long i16086; + long i16087; + long i16088; + long i16089; + long i16090; + long i16091; + long i16092; + long i16093; + long i16094; + long i16095; + long i16096; + long i16097; + long i16098; + long i16099; + long i16100; + long i16101; + long i16102; + long i16103; + long i16104; + long i16105; + long i16106; + long i16107; + long i16108; + long i16109; + long i16110; + long i16111; + long i16112; + long i16113; + long i16114; + long i16115; + long i16116; + long i16117; + long i16118; + long i16119; + long i16120; + long i16121; + long i16122; + long i16123; + long i16124; + long i16125; + long i16126; + long i16127; + long i16128; + long i16129; + long i16130; + long i16131; + long i16132; + long i16133; + long i16134; + long i16135; + long i16136; + long i16137; + long i16138; + long i16139; + long i16140; + long i16141; + long i16142; + long i16143; + long i16144; + long i16145; + long i16146; + long i16147; + long i16148; + long i16149; + long i16150; + long i16151; + long i16152; + long i16153; + long i16154; + long i16155; + long i16156; + long i16157; + long i16158; + long i16159; + long i16160; + long i16161; + long i16162; + long i16163; + long i16164; + long i16165; + long i16166; + long i16167; + long i16168; + long i16169; + long i16170; + long i16171; + long i16172; + long i16173; + long i16174; + long i16175; + long i16176; + long i16177; + long i16178; + long i16179; + long i16180; + long i16181; + long i16182; + long i16183; + long i16184; + long i16185; + long i16186; + long i16187; + long i16188; + long i16189; + long i16190; + long i16191; + long i16192; + long i16193; + long i16194; + long i16195; + long i16196; + long i16197; + long i16198; + long i16199; + long i16200; + long i16201; + long i16202; + long i16203; + long i16204; + long i16205; + long i16206; + long i16207; + long i16208; + long i16209; + long i16210; + long i16211; + long i16212; + long i16213; + long i16214; + long i16215; + long i16216; + long i16217; + long i16218; + long i16219; + long i16220; + long i16221; + long i16222; + long i16223; + long i16224; + long i16225; + long i16226; + long i16227; + long i16228; + long i16229; + long i16230; + long i16231; + long i16232; + long i16233; + long i16234; + long i16235; + long i16236; + long i16237; + long i16238; + long i16239; + long i16240; + long i16241; + long i16242; + long i16243; + long i16244; + long i16245; + long i16246; + long i16247; + long i16248; + long i16249; + long i16250; + long i16251; + long i16252; + long i16253; + long i16254; + long i16255; + long i16256; + long i16257; + long i16258; + long i16259; + long i16260; + long i16261; + long i16262; + long i16263; + long i16264; + long i16265; + long i16266; + long i16267; + long i16268; + long i16269; + long i16270; + long i16271; + long i16272; + long i16273; + long i16274; + long i16275; + long i16276; + long i16277; + long i16278; + long i16279; + long i16280; + long i16281; + long i16282; + long i16283; + long i16284; + long i16285; + long i16286; + long i16287; + long i16288; + long i16289; + long i16290; + long i16291; + long i16292; + long i16293; + long i16294; + long i16295; + long i16296; + long i16297; + long i16298; + long i16299; + long i16300; + long i16301; + long i16302; + long i16303; + long i16304; + long i16305; + long i16306; + long i16307; + long i16308; + long i16309; + long i16310; + long i16311; + long i16312; + long i16313; + long i16314; + long i16315; + long i16316; + long i16317; + long i16318; + long i16319; + long i16320; + long i16321; + long i16322; + long i16323; + long i16324; + long i16325; + long i16326; + long i16327; + long i16328; + long i16329; + long i16330; + long i16331; + long i16332; + long i16333; + long i16334; + long i16335; + long i16336; + long i16337; + long i16338; + long i16339; + long i16340; + long i16341; + long i16342; + long i16343; + long i16344; + long i16345; + long i16346; + long i16347; + long i16348; + long i16349; + long i16350; + long i16351; + long i16352; + long i16353; + long i16354; + long i16355; + long i16356; + long i16357; + long i16358; + long i16359; + long i16360; + long i16361; + long i16362; + long i16363; + long i16364; + long i16365; + long i16366; + long i16367; + long i16368; + long i16369; + long i16370; + long i16371; + long i16372; + long i16373; + long i16374; + long i16375; + long i16376; + long i16377; + long i16378; + long i16379; + long i16380; + long i16381; + } + + static final BaseClass newInstance(int size) { + switch (size) { + case 32: + return new Class32(); + case 64: + return new Class64(); + case 256: + return new Class256(); + case 1024: + return new Class1024(); + case 2048: + return new Class2048(); + case 4096: + return new Class4096(); + case 8192: + return new Class8192(); + case 16384: + return new Class16384(); + case 65536: + return new Class65536(); + case 131072: + return new Class131072(); + default: + throw new RuntimeException(" Huh? " + size); + } + } +}