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

Phil Race prr at openjdk.java.net
Thu Mar 17 03:31:18 UTC 2022


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.

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

Commit messages:
 - 8274735: javax.imageio.IIOException: Unsupported Image Type while processing a valid JPEG image

Changes: https://git.openjdk.java.net/jdk/pull/7849/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=7849&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8274735
  Stats: 284 lines in 13 files changed: 283 ins; 0 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7849.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7849/head:pull/7849

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



More information about the client-libs-dev mailing list