-
Bug
-
Resolution: Fixed
-
P3
-
10
-
b34
Using the same PNGImageReader to read multiple images may lead to failures. To reproduce, please download the attached diff and apply it to a recent (consolidated) JDK checkout. It should add test "test/jdk/javax/imageio/plugins/png/ResetImageStartPosition.java" (+2 test images). Run the test, it you should see it fail with:
---
java.lang.IllegalStateException: javax.imageio.IIOException: Error reading PNG image data
at PNGRead.read(PNGRead.java:30)
at PNGRead.main(PNGRead.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.imageio.IIOException: Error reading PNG image data
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1405)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1674)
at PNGRead.read(PNGRead.java:28)
... 7 more
Caused by: java.util.zip.ZipException: incorrect header check
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:165)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:83)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1172)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1275)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1396)
... 9 more
---
It fails when it read the "metal_minimize_rollover.png" for the second time (after reading "pause.png"). It is able to read the "metal_minimize_rollover.png" at the beginning of the test, so there does not appear to be anything wrong with the image itself.
The reason appears to be that:
PNGImageReader.imageStartPosition is set while reading "pause.png", but reset neither in PNGImageReader.setInput, nor while reading the last image, so the stray value from reading the "pause.png" is used, which then lead to the problem. Note that the javadoc for ImageReader.setInput(Object, boolean, boolean) says (snipped):
---
* <p> Subclasses should take care to remove any cached
* information based on the previous stream, such as header
* information or partially decoded image data.
---
I.e. it would seem appropriate to clear the imageStartPosition inside PNGImageReader.setInput (PNGImageReader.resetStreamSettings).
---
java.lang.IllegalStateException: javax.imageio.IIOException: Error reading PNG image data
at PNGRead.read(PNGRead.java:30)
at PNGRead.main(PNGRead.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.imageio.IIOException: Error reading PNG image data
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1405)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1674)
at PNGRead.read(PNGRead.java:28)
... 7 more
Caused by: java.util.zip.ZipException: incorrect header check
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:165)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:83)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1172)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1275)
at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1396)
... 9 more
---
It fails when it read the "metal_minimize_rollover.png" for the second time (after reading "pause.png"). It is able to read the "metal_minimize_rollover.png" at the beginning of the test, so there does not appear to be anything wrong with the image itself.
The reason appears to be that:
PNGImageReader.imageStartPosition is set while reading "pause.png", but reset neither in PNGImageReader.setInput, nor while reading the last image, so the stray value from reading the "pause.png" is used, which then lead to the problem. Note that the javadoc for ImageReader.setInput(Object, boolean, boolean) says (snipped):
---
* <p> Subclasses should take care to remove any cached
* information based on the previous stream, such as header
* information or partially decoded image data.
---
I.e. it would seem appropriate to clear the imageStartPosition inside PNGImageReader.setInput (PNGImageReader.resetStreamSettings).
- relates to
-
JDK-8164971 PNG metadata does not handle ImageCreationTime
- Resolved
- links to