Image I/O developers are having trouble loading PNG/GIF images from
compressed JAR files (uncompressed JAR files and loading the classes/resources
directly from disk work correctly). I've written a small testcase that mimicks
the PNGImageReader's usage of InputStreams. Basically, it uses an
InflaterInputStream (wrapped by a BufferedInputStream/DataInputStream)
in order to read the ZLIB compressed portion of the PNG image. The test
reads these uncompressed bytes and prints them one line at a time. I
have a feeling this is problematic when the original InputStream is a
ZipFileInputStream (because the PNG is loaded from a compressed JAR file). I
can run my testcase in an uncompressed JAR, and it's fine (because the original
InputStream is a plain FileInputStream), but when I run it in a compressed
JAR file, the printed bytes do not match the uncompressed case. In
practice, the PNGImageReader sees this garbage as unknown markers and
emits warnings/exceptions. The GIFImageReader simply produces a visibly
corrupted image.
Testcase source code, image, and JAR files are attached.
The testcase is JarredImage.java, and the test image is key40grey.png.
comp.jar contains the class files and PNG (compressed), and nocomp.jar
contains the same files, but store-only (non-compressed). The testcase
mimicks our IIO PNGImageReader, and as it reads the ZLIB compressed
portion of the PNG image, it spits the byte index and value line by line
to stdout. You can diff the results from the comp.jar run and the
nocomp.jar run, and you'll see they begin to differ around line number
660 (that is, the 660th byte in the compressed image segment).
Usage:
% java -cp comp.jar JarredImage > comp.txt
% java -cp nocomp.jar JarredImage > nocomp.txt
% java JarredImage > nojar.txt (should be the same as nocomp.jar)
% diff comp.txt nocomp.txt