ColorProfilesTest.java
package com.twelvemonkeys.imageio.color;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class ColorProfilesTest {
@Test
public void testCreateColorSpaceFromBrokenProfileIsFixedCS_sRGB() {
ICC_Profile internal = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
ICC_Profile profile = createBrokenProfile(internal);
assertNotSame(internal, profile); // Sanity check
assertTrue(ColorProfiles.isOffendingColorProfile(profile));
ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
assertSame(ColorSpace.getInstance(ColorSpace.CS_sRGB), created);
assertTrue(created.isCS_sRGB());
}
private ICC_Profile createBrokenProfile(ICC_Profile internal) {
byte[] data = internal.getData();
data[ICC_Profile.icHdrRenderingIntent] = 1; // Intent: 1 == Relative Colormetric Little Endian
data[ICC_Profile.icHdrRenderingIntent + 1] = 0;
data[ICC_Profile.icHdrRenderingIntent + 2] = 0;
data[ICC_Profile.icHdrRenderingIntent + 3] = 0;
return ICC_Profile.getInstance(data);
}
@Test
public void testIsOffendingColorProfile() {
ICC_Profile broken = createBrokenProfile(ICC_Profile.getInstance(ColorSpace.CS_GRAY));
assertTrue(ColorProfiles.isOffendingColorProfile(broken));
}
@Test
public void testIsCS_sRGBTrue() {
assertTrue(ColorProfiles.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_sRGB)));
}
@Test
public void testIsCS_sRGBFalse() {
assertFalse(ColorProfiles.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB)));
assertFalse(ColorProfiles.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ)));
assertFalse(ColorProfiles.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_GRAY)));
assertFalse(ColorProfiles.isCS_sRGB(ICC_Profile.getInstance(ColorSpace.CS_PYCC)));
}
@Test
public void testIsCS_sRGBNull() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.isCS_sRGB(null));
}
@Test
public void testIsCS_GRAYTrue() {
assertTrue(ColorProfiles.isCS_GRAY(ICC_Profile.getInstance(ColorSpace.CS_GRAY)));
}
@Test
public void testIsCS_GRAYFalse() {
assertFalse(ColorProfiles.isCS_GRAY(ICC_Profile.getInstance(ColorSpace.CS_sRGB)));
assertFalse(ColorProfiles.isCS_GRAY(ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB)));
assertFalse(ColorProfiles.isCS_GRAY(ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ)));
assertFalse(ColorProfiles.isCS_GRAY(ICC_Profile.getInstance(ColorSpace.CS_PYCC)));
}
@Test
public void testIsCS_GRAYNull() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.isCS_GRAY(null));
}
@Test
public void testCreateProfileNull() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfile(null));
}
@Test
public void testReadProfileNull() throws IOException {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfile(null));
}
@Test
public void testCreateProfileRawNull() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfileRaw(null));
}
@Test
public void testReadProfileRawNull() throws IOException {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfileRaw(null));
}
@Test
public void testCreateProfileRaw() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
ICC_Profile profileRaw = ColorProfiles.createProfileRaw(data);
assertArrayEquals(data, profileRaw.getData());
}
@Test
public void testReadProfileRaw() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
ICC_Profile profileRaw = ColorProfiles.readProfileRaw(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
assertArrayEquals(data, profileRaw.getData());
}
@Test
public void testCreateProfileRawBadData() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfileRaw(new byte[5]));
}
@Test
public void testReadProfileRawBadData() throws IOException {
// NOTE: The array here is larger, as there's a bug in OpenJDK 15 & 16, that throws
// ArrayIndexOutOfBoundsException if the stream is shorter than the profile signature...
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfileRaw(new ByteArrayInputStream(new byte[40])));
}
@Test
public void testCreateProfileBadData() {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfile(new byte[5]));
}
@Test
public void testReadProfileBadData() throws IOException {
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfile(new ByteArrayInputStream(new byte[5])));
}
@Test
public void testCreateProfileRawTruncated() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfileRaw(Arrays.copyOf(data, 200)));
}
@Test
public void testReadProfileRawTruncated() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfileRaw(new ByteArrayInputStream(data, 0, 200)));
}
@Test
public void testCreateProfileTruncated() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfile(Arrays.copyOf(data, 200)));
}
@Test
public void testReadProfileTruncated() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfile(new ByteArrayInputStream(data, 0, 200)));
}
@Test
public void testCreateProfileRawTruncatedHeader() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfileRaw(Arrays.copyOf(data, 125)));
}
@Test
public void testReadProfileRawTruncatedHeader() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfileRaw(new ByteArrayInputStream(data, 0, 125)));
}
@Test
public void testCreateProfileTruncatedHeader() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.createProfile(Arrays.copyOf(data, 125)));
}
@Test
public void testReadProfileTruncatedHeader() throws IOException {
byte[] data = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")).getData();
assertThrows(IllegalArgumentException.class, () -> ColorProfiles.readProfile(new ByteArrayInputStream(data, 0, 125)));
}
@Test
public void testCreateProfileBytesSame() throws IOException {
ICC_Profile profile = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
ICC_Profile profile1 = ColorProfiles.createProfile(profile.getData());
ICC_Profile profile2 = ColorProfiles.createProfile(profile.getData());
assertEquals(profile1, profile2);
assertSame(profile1, profile2);
}
@Test
public void testReadProfileInputStreamSame() throws IOException {
ICC_Profile profile1 = ColorProfiles.readProfile(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
ICC_Profile profile2 = ColorProfiles.readProfile(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
assertEquals(profile1, profile2);
assertSame(profile1, profile2);
}
@Test
public void testReadProfileDifferent() throws IOException {
// These profiles are extracted from various JPEGs, and have the exact same profile header (but are different profiles)...
ICC_Profile profile1 = ColorProfiles.readProfile(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
ICC_Profile profile2 = ColorProfiles.readProfile(getClass().getResourceAsStream("/profiles/color_match_rgb.icc"));
assertNotSame(profile1, profile2);
}
@Test
public void testCreateProfileBytesSameAsCached() throws IOException {
ICC_Profile profile = ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
ICC_ColorSpace cs1 = ColorSpaces.createColorSpace(profile);
ICC_Profile profile2 = ColorProfiles.createProfile(profile.getData());
assertEquals(cs1.getProfile(), profile2);
assertSame(cs1.getProfile(), profile2);
}
@Test
public void testReadProfileInputStreamSameAsCached() throws IOException {
ICC_ColorSpace cs1 = ColorSpaces.createColorSpace(ICC_Profile.getInstance(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc")));
ICC_Profile profile2 = ColorProfiles.readProfile(getClass().getResourceAsStream("/profiles/adobe_rgb_1998.icc"));
assertEquals(cs1.getProfile(), profile2);
assertSame(cs1.getProfile(), profile2);
}
@Test
public void testCreateProfileBytesSameAsInternal() {
ICC_Profile profile1 = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
ICC_Profile profile2 = ColorProfiles.createProfile(ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData());
assertEquals(profile1, profile2);
assertSame(profile1, profile2);
}
@Test
public void testReadProfileInputStreamSameAsInternal() throws IOException {
ICC_Profile profile1 = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
ICC_Profile profile2 = ColorProfiles.readProfile(new ByteArrayInputStream(ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData()));
assertEquals(profile1, profile2);
assertSame(profile1, profile2);
}
}