RFR: 8274735: javax.imageio.IIOException: Unsupported Image Type while processing a valid JPEG image

Phil Race prr at openjdk.java.net
Fri Mar 18 18:21:08 UTC 2022


On Thu, 17 Mar 2022 03:23:49 GMT, Phil Race <prr at openjdk.org> wrote:

> The JDK's built-in Image I/O JPEG plugin decodes JPEGs which are YCbCr and RGb and Grayscale but rejects CMYK and YCCK JPEGs.
> These would correspond to JFIF encapsulated JPEGs.
> 
> This was a reasonable decision to limit support to what was actually likely to be seen - CMYK JPEGs probably should just be created for direct to print devices and never seen on the internet as an interchange format.
> 
> Indeed this (below) RFC for mail suggests JFIF is what clients should transmit :
> 
> https://datatracker.ietf.org/doc/html/rfc2046 :  Multipurpose Internet Mail Extensions - Part 2
> 
> 
>    A media type of "image" indicates that the body contains an image.
>    The subtype names the specific image format.  These names are not
>    case sensitive. An initial subtype is "jpeg" for the JPEG format
>    using JFIF encoding [JPEG].
> 
> And for many years, browsers either failed to display CMYK JPEGs or displayed them incorrectly.
> 
> But alas they do crop up and when they do, Image I/O rejects them - to the surprise and
> consternation of some developer who knows little of JPEGs and arcane colour spaces.
> 
> Full support of CMYK JPEGs via the whole Image I/O API including proper handling as metadata
> will lead us down a path that might even extend into EXIF support for JPEG and likely will
> require the JPEG Metadata spec to be updated. 
> 
> So the goal here is to skirt that as much as possible by just 
> (1) not rejecting read of CMYK JPEGs and returning a BufferedImage with a suitable ColorModel
> (2) allowing the same BufferedImage with that ColorSpace to be written back out again as CMYK JPEGs 
> 
> Reading will preserve any embedded ICC Color Profile, but writing will not re-encode it since
> that requires work on metadata. That will have to be a follow-up fix, but at the very least it
> means that a re-written JPEG will benefit from a default treatment CMYK by any other client.
> 
> A test is provided which verifies that the colours are interpreted reasonably, both on initial read
> and on write and re-read. 
> 
> JPEGs with embedded profiles have been tested on read, but since there are licensing issues with those,
> the test uses JPEGs which have no embedded profile and depend on an internal implementation class.
> 
> That class has its hashCode() method updated because testing showed that toString() invoked hashCode()
> in a way that caused a StackOverflowError - so nothing per se to do with this fix but a necessary update.
> 
> Anyone who has trustworthy CMYK JPEGs that render properly in (eg) major web browsers but not with this
> code can submit those JPEGs so I can evaluate.
> 
> But all our automated tests pass as well as some manual testing and evaluation etc.

> Note that [`gray_cmyk.jpg`](https://github.com/openjdk/jdk/blob/2573ebdc1afe0c46b621c39195ffd49bf2f724a2/test/jdk/javax/imageio/plugins/jpeg/CMYK/gray_cmyk.jpg) ([![gray_cmyk.jpg](https://raw.githubusercontent.com/openjdk/jdk/2573ebdc1afe0c46b621c39195ffd49bf2f724a2/test/jdk/javax/imageio/plugins/jpeg/CMYK/gray_cmyk.jpg)](https://github.com/openjdk/jdk/blob/2573ebdc1afe0c46b621c39195ffd49bf2f724a2/test/jdk/javax/imageio/plugins/jpeg/CMYK/gray_cmyk.jpg)) looks more like a greyish brown (`#4A4642`) on my end.

It was created using java.awt.Color.gray which is 128.128,128 - ie #808080 as RGB, saved as JPG then converted via an online tool to CMYK  and the round trip tolerance check is passing when comparing to the original gray color, so it must be something about whatever you are using to display it and how it interprets that.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7849



More information about the client-libs-dev mailing list