Skip to content

JPEGImageReader: Reading same file the 2nd time causes java.awt.color.CMMException #1208

@MichaelSchaich

Description

@MichaelSchaich

Describe the bug
With JPEGImageReader using java.desktop/sun.java2d.cmm.lcms.LCMS, reading the same file a 2nd time causes
java.awt.color.CMMException: LCMS error 13: LUT is not suitable to be saved as LutAToB

Version information

  1. The version of the TwelveMonkeys ImageIO library in use.
    3.12.0

  2. The exact output of java --version (or java -version for older Java releases).
    java version "25" 2025-09-16 LTS
    Java(TM) SE Runtime Environment (build 25+37-LTS-3491)
    Java HotSpot(TM) 64-Bit Server VM (build 25+37-LTS-3491, mixed mode, sharing)

  3. Extra information about OS version, server version, standalone program or web application packaging, executable wrapper, etc. Please state exact version numbers where applicable.
    OS version: Windows 11 24H2 (Build 26100.6584)

To Reproduce
Steps to reproduce the behavior:

  1. Compile the below sample code
  2. Download the attached sample image file CMMException.jpg
  3. Run the code with the sample file
  4. See error

Expected behavior
The 2nd read should not fail, at least not after renewed
iis = ImageIO.createImageInputStream(new File(testFileName));
reader.setInput(iis);

Example code

package com.agfa.hap;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class ProblemCmmException {
    public static void main(String[] args) {

        ImageIO.setUseCache(false);
        IIORegistry iioRegistry = IIORegistry.getDefaultInstance();
        com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi jpegImageReaderSpi = iioRegistry.getServiceProviderByClass(com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi.class);
        ImageReader reader;
        try {
            reader = jpegImageReaderSpi.createReaderInstance();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (!(reader instanceof com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader)) {
            throw new RuntimeException("reader is not of type Twelvemonkeys JPEGImageReader");
        }
        String testFileName = "CMMException.jpg";
        URL testFileUrl = ProblemCmmException.class.getResource("/CMMException.jpg");
        if (testFileUrl == null) {
            throw new RuntimeException("Test file CMMException.jpg not found");
        } else {
            testFileName = testFileUrl.getPath();
        }

        Image image = null;
        ImageInputStream iis = null;
        try {
            iis = ImageIO.createImageInputStream(new File(testFileName));
            reader.setInput(iis);
            image = reader.read(0);
        } catch (IOException e) {
            throw new RuntimeException("Failed reading test file 1st time, reason: ",e);
        }
        try {
            iis = ImageIO.createImageInputStream(new File(testFileName));
            reader.setInput(iis);
            image = reader.read(0);
        } catch (Exception e) {
            throw new RuntimeException("Failed reading test file 2nd time, reason: ",e);
        }

    }
}

Sample file(s)
Attached CMMException.jpg:
Image

Stack trace

Exception in thread "main" java.lang.RuntimeException: Failed reading test file 1st time, reason: 
	at com.agfa.hap.ProblemCmmException.main(ProblemCmmException.java:54)
Caused by: java.awt.color.CMMException: LCMS error 13: LUT is not suitable to be saved as LutAToB
	at java.desktop/sun.java2d.cmm.lcms.LCMS.getProfileDataNative(Native Method)
	at java.desktop/sun.java2d.cmm.lcms.LCMSProfile.getProfileData(LCMSProfile.java:52)
	at java.desktop/sun.java2d.cmm.lcms.LCMS.getProfileData(LCMS.java:80)
	at java.desktop/java.awt.color.ICC_Profile.getData(ICC_Profile.java:1106)
	at com.twelvemonkeys.imageio.color.ColorProfiles.getProfileHeaderWithProfileId(ColorProfiles.java:99)
	at com.twelvemonkeys.imageio.color.ColorProfiles.isCS_sRGB(ColorProfiles.java:149)
	at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:340)
	at java.desktop/javax.imageio.ImageReader.read(ImageReader.java:938)

Additional context
My analysis so far:
Apparently it has to do with the color space, which is altered on 1st read, but cached and reused on 2nd read.
When during debug setting both the color space retrieved from cache and the CMMProfile retrieved from cache to null, the 2nd read succeeds.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions