JPEG images with CMYK and YCCK image data
In order to improve the compatibility of my EmbedPDF applet, I am trying to implement support for JPEG images with CMYK and YCCK colors.
Reading this kind of images is harder than I thought. The JPEG file format is complex. The file format can be a basic JFIF (JPEG file interchange format) or an extended variant named EXIF (Exchangeable image file format for digital still cameras). In addition, Adobe Photoshop includes some application data in JPEG files which is relevant for decoding CMYK and YCCK encoded image data.
Together with the ‘JPEG Still Image Data Compression Standard’ book on my desk, and the comments given in bug report 4799903 for Java, I have managed to read the basic JFIF file structure, and put some preliminary code in place which performs a basic decoding of CMYK and YCCK image data. My reader is not yet able to always determine the encoding type, and does not yet take color profiles into account – thus the hue is sometimes wrong and saturation is often too high.
This image sums up my progress on the JPEG reader. The window at the top left, shows the raw file data, the window in the middle the file structure, and the window at the bottom right a decoded image (which currently has too much saturation):
Update 2008-10-20: I solved the hue and saturation issue. It turns out that the APP2 marker segments of a JFIF file contain fragments of an ICC Profile, if they start with the null-terminated string “ICC_Profile”. (The APP2 marker segments can be seen listed on the second window of my screenshot). Surprisingly, JPEG images with YCCK image data contain a CMYK ICC Profile, and not a YCCK profile, as one would expect. I am now converting the image from YCCK to CMYK, and then I perform the conversion to RGB using the ICC Profile provided in the JPEG image. This gives the right colors:
Trackbacks & Pingbacks
- Reading JPEGs with CMYK profile | JavaHelp.info
- Reading CMYK JPEG images with Java ImageIO | Werner Randelshofer's Blog
Comments are closed.
Oiyee! Congratulations on making it through the JPEG file format. Isn’t it awful? 🙂 You made it farther than I ever did.
The most I’ve ever done is extract pieces of information out of it — such as thumbnails from EXIF files (it turns out ImageIO, least I knew, can’t actually do this… so it saves a huge amount of time when you’re dealing with megapixel images in a file-browser setting). And THAT was pretty hard; I can’t imagine how much work it was making sense of the rest of it!
Hi,
I’ve encountered the same problems when trying to encode a cmyk jpeg (out of flash as3 specifically).
I’m currently testing writing various icc profiles to the APP2 marker but with no success – do you have any advice or examples – I understand you are (were?) working to display/embed cmyk jpegs and I’m working the other way around (trying to emulate photoshop’s creation of) but you may be able to help all the same.
Many thanks in advance,
Wayne
Hi Wayne,
I have no experience with writing CMYK JPEG files.
If you compare the structure of a CMYK JPEG file written by your code with one written by Photoshop you might find out where the problem is.
Maybe it is just a simple issue. For example, the data in the APP2 segment might not have the proper start or ending.
Eventually MultiShow can be a useful tool for this.
You can launch it from the following page:
http://www.randelshofer.ch/multishow/
To view the structure of a file with MultiShow, open it, then choose “View As > Struct JFIF”. Make sure that the menu item “View > Show Parsed Structures” is checked.
You can even export the contents of an individual JFIF segment by right-clicking it in the column on the left and choosing “Export Struct…”.
HTH,
Werner
Hi Werner,
I’ve got your software in front of me now and can immediately see how that’s going to help in the various file comparisons.
Many, many thanks for your kind help!
Wayne
Hi werner,
I am using com.itextpdf.text.Image class for finding DPI of JPEG image. It works fine for RGB colorspace images, but for CMYK colorspace Images it returns 0. Is there any way to find DPI of JPEG images using Java?
Image img = Image.getInstance(“I:/Vikash/36119_3006_alt.jpg”);
int x = img.getDpiX();
int y = img.getDpiY();
Thanks,
Vikash