H
Harold Yarmouth
I did some testing of ImageIO robustness and found some disturbing problems.
Bug #1: com.sun.media.imageioimpl.plugins.raw.RawImageReader does not
accept ImageInputStream in setInput.
java.lang.ClassCastException: javax.imageio.stream.FileImageInputStream
cannot be cast to com.sun.media.imageio.stream.RawImageInputStream
at
com.sun.media.imageioimpl.plugins.raw.RawImageReader.setInput(RawImageReader.java:121)
at javax.imageio.ImageReader.setInput(ImageReader.java:363)
Got this calling imageReader.setInput(new ImageInputStream(someFile));
Obviously, this should not be, given the Javadocs:
setInput
public void setInput(Object input)
Sets the input source to use to the given ImageInputStream or other
Object. The input source must be set before any of the query or read
methods are used. If input is null, any currently set input source will
be removed. In any case, the value of minIndex will be initialized to 0.
This method is equivalent to setInput(input, false, false).
Parameters:
input - the ImageInputStream or other Object to use for future
decoding.
Throws:
IllegalArgumentException - if input is not an instance of one
of the classes returned by the originating service provider's
getInputTypes method, or is not an ImageInputStream.
See Also:
getInput()
This makes it quite clear that ImageReader implementations are supposed
to accept ImageInputStreams, and furthermore are supposed to throw
IllegalArgumentException, not ClassCastException, if passed an object
that is not accepted.
Workaround: Catch ClassCastException and try another ImageReader on that
input stream.
Bug #2: com.sun.media.imageioimpl.plugins.pnm.PNMImageReader throws
RuntimeException instead of IOException when the file format is unfamiliar.
java.lang.RuntimeException: What in the stream isn't a PNM image.
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.readHeader(PNMImageReader.java:187)
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.getWidth(PNMImageReader.java:153)
calling getWidth on a PNMImageReader invoked on a jpeg. This time the
error message isn't even quite grammatical...
The correct behavior when the image format is not the expected one is to
throw an IOException, of course. Throwing a RuntimeException is bad.
Throwing an unsubtyped RuntimeException is worse, because client code
has to catch all RuntimeExceptions and treat them as IOExceptions, which
may mask real RuntimeExceptions.
Workaround: Catch RuntimeException, test with getClass() whether it is
exactly RuntimeException, if not rethrow, and if yes treat as if
IOException.
Bug #1: com.sun.media.imageioimpl.plugins.raw.RawImageReader does not
accept ImageInputStream in setInput.
java.lang.ClassCastException: javax.imageio.stream.FileImageInputStream
cannot be cast to com.sun.media.imageio.stream.RawImageInputStream
at
com.sun.media.imageioimpl.plugins.raw.RawImageReader.setInput(RawImageReader.java:121)
at javax.imageio.ImageReader.setInput(ImageReader.java:363)
Got this calling imageReader.setInput(new ImageInputStream(someFile));
Obviously, this should not be, given the Javadocs:
setInput
public void setInput(Object input)
Sets the input source to use to the given ImageInputStream or other
Object. The input source must be set before any of the query or read
methods are used. If input is null, any currently set input source will
be removed. In any case, the value of minIndex will be initialized to 0.
This method is equivalent to setInput(input, false, false).
Parameters:
input - the ImageInputStream or other Object to use for future
decoding.
Throws:
IllegalArgumentException - if input is not an instance of one
of the classes returned by the originating service provider's
getInputTypes method, or is not an ImageInputStream.
See Also:
getInput()
This makes it quite clear that ImageReader implementations are supposed
to accept ImageInputStreams, and furthermore are supposed to throw
IllegalArgumentException, not ClassCastException, if passed an object
that is not accepted.
Workaround: Catch ClassCastException and try another ImageReader on that
input stream.
Bug #2: com.sun.media.imageioimpl.plugins.pnm.PNMImageReader throws
RuntimeException instead of IOException when the file format is unfamiliar.
java.lang.RuntimeException: What in the stream isn't a PNM image.
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.readHeader(PNMImageReader.java:187)
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.getWidth(PNMImageReader.java:153)
calling getWidth on a PNMImageReader invoked on a jpeg. This time the
error message isn't even quite grammatical...
The correct behavior when the image format is not the expected one is to
throw an IOException, of course. Throwing a RuntimeException is bad.
Throwing an unsubtyped RuntimeException is worse, because client code
has to catch all RuntimeExceptions and treat them as IOExceptions, which
may mask real RuntimeExceptions.
Workaround: Catch RuntimeException, test with getClass() whether it is
exactly RuntimeException, if not rethrow, and if yes treat as if
IOException.