Reputation: 1976
I have a weird JPEG image file that ImageIO.read() fails to load:
ImageIO.read(new URL("http://nocturne.wmw.cc/a.jpg"));
Any ideas?
Exception in thread "main" javax.imageio.IIOException: Unsupported Image Type
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:995)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:966)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at Main.main(Main.java:23)
Upvotes: 4
Views: 4552
Reputation: 8405
Okay... Took me a while to find the problem with this... The problem is with the image itself, it has a CMYK colour profile (namely Coated FOGRA27), confusing the JPEG reading library in java.
Opening the image in photoshop yields an image in CMYK color mode (for me at least) which seems to be unsupported by java. Changing the color mode to RGB and saving with a sRGB color profile allowed the ImageIO library to successfully read the image.
The ImageIO library only implements a subset of readable colour profiles and does not handle images without any profiles.
Further reading into the JPEGImageReader source yielded the following code:
switch (colorSpaceCode) {
case JPEG.JCS_GRAYSCALE:
list.add(raw);
list.add(getImageType(JPEG.JCS_RGB));
break;
case JPEG.JCS_RGB:
list.add(raw);
list.add(getImageType(JPEG.JCS_GRAYSCALE));
list.add(getImageType(JPEG.JCS_YCC));
break;
case JPEG.JCS_RGBA:
list.add(raw);
break;
case JPEG.JCS_YCC:
if (raw != null) { // Might be null if PYCC.pf not installed
list.add(raw);
list.add(getImageType(JPEG.JCS_RGB));
}
break;
case JPEG.JCS_YCCA:
if (raw != null) { // Might be null if PYCC.pf not installed
list.add(raw);
}
break;
case JPEG.JCS_YCbCr:
// As there is no YCbCr ColorSpace, we can't support
// the raw type.
// due to 4705399, use RGB as default in order to avoid
// slowing down of drawing operations with result image.
list.add(getImageType(JPEG.JCS_RGB));
if (iccCS != null) {
list.add(new ImageTypeProducer() {
protected ImageTypeSpecifier produce() {
return ImageTypeSpecifier.createInterleaved
(iccCS,
JPEG.bOffsRGB, // Assume it's for RGB
DataBuffer.TYPE_BYTE,
false,
false);
}
});
}
list.add(getImageType(JPEG.JCS_GRAYSCALE));
list.add(getImageType(JPEG.JCS_YCC));
break;
case JPEG.JCS_YCbCrA: // Default is to convert to RGBA
// As there is no YCbCr ColorSpace, we can't support
// the raw type.
list.add(getImageType(JPEG.JCS_RGBA));
break;
}
The source of the exception:
Iterator imageTypes = getImageTypes(imageIndex);
if (imageTypes.hasNext() == false) {
throw new IIOException("Unsupported Image Type");
}
As you can see, when the color profile of the JPEG image is not listed in the switch statement, nothing is added to the 'list' variable which eventually gets passed to the particular iterator in the second segment of code. With an empty list, the Iterator.hasNext() method returns a false, throwing the exception.
Upvotes: 5