diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/CMYKColorSpace.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/CMYKColorSpace.java
similarity index 61%
rename from imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/CMYKColorSpace.java
rename to imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/CMYKColorSpace.java
index 54715827..2223ec77 100644
--- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/CMYKColorSpace.java
+++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/CMYKColorSpace.java
@@ -1,17 +1,17 @@
/*
- * Copyright (c) 2008, Harald Kuhr
+ * Copyright (c) 2011, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name "TwelveMonkeys" nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -26,25 +26,24 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package com.twelvemonkeys.imageio.plugins.psd;
+package com.twelvemonkeys.imageio.color;
import java.awt.color.ColorSpace;
/**
- * CMYKColorSpace
+ * A fallback CMYK ColorSpace, in case none can be read from disk.
*
* @author Harald Kuhr
* @author last modified by $Author: haraldk$
* @version $Id: CMYKColorSpace.java,v 1.0 Apr 30, 2008 1:38:13 PM haraldk Exp$
*/
-// TODO: Move to com.twelvemonkeys.image?
-// TODO: Read a ICC CMYK profile from classpath resource (from ECI)? ISO coated?
final class CMYKColorSpace extends ColorSpace {
static final ColorSpace INSTANCE = new CMYKColorSpace();
+
final ColorSpace sRGB = getInstance(CS_sRGB);
- CMYKColorSpace() {
+ private CMYKColorSpace() {
super(ColorSpace.TYPE_CMYK, 4);
}
@@ -58,6 +57,7 @@ final class CMYKColorSpace extends ColorSpace {
(1 - colorvalue[1]) * (1 - colorvalue[3]),
(1 - colorvalue[2]) * (1 - colorvalue[3])
};
+
// TODO: Convert via CIEXYZ space using sRGB space, as suggested in docs
// return sRGB.fromCIEXYZ(toCIEXYZ(colorvalue));
}
@@ -73,33 +73,35 @@ final class CMYKColorSpace extends ColorSpace {
// Convert to CMYK values
return new float[] {(c - k), (m - k), (y - k), k};
-/*
-http://www.velocityreviews.com/forums/t127265-rgb-to-cmyk.html
-(Step 0: Normalize R,G, and B values to fit into range [0.0 ... 1.0], or
-adapt the following matrix.)
+ /*
+ http://www.velocityreviews.com/forums/t127265-rgb-to-cmyk.html
-Step 1: RGB to CMY
+ (Step 0: Normalize R,G, and B values to fit into range [0.0 ... 1.0], or
+ adapt the following matrix.)
-| C | | 1 | | R |
-| M | = | 1 | - | G |
-| Y | | 1 | | B |
+ Step 1: RGB to CMY
-Step 2: CMY to CMYK
+ | C | | 1 | | R |
+ | M | = | 1 | - | G |
+ | Y | | 1 | | B |
-| C' | | C | | min(C,M,Y) |
-| M' | | M | | min(C,M,Y) |
-| Y' | = | Y | - | min(C,M,Y) |
-| K' | | min(C,M,Y) | | 0 |
+ Step 2: CMY to CMYK
-Easier to calculate if K' is calculated first, because K' = min(C,M,Y):
+ | C' | | C | | min(C,M,Y) |
+ | M' | | M | | min(C,M,Y) |
+ | Y' | = | Y | - | min(C,M,Y) |
+ | K' | | min(C,M,Y) | | 0 |
-| C' | | C | | K' |
-| M' | | M | | K' |
-| Y' | = | Y | - | K' |
-| K' | | K'| | 0 |
- */
-// return fromCIEXYZ(sRGB.toCIEXYZ(rgbvalue));
+ Easier to calculate if K' is calculated first, because K' = min(C,M,Y):
+
+ | C' | | C | | K' |
+ | M' | | M | | K' |
+ | Y' | = | Y | - | K' |
+ | K' | | K'| | 0 |
+ */
+
+ // return fromCIEXYZ(sRGB.toCIEXYZ(rgbvalue));
}
public float[] toCIEXYZ(float[] colorvalue) {
diff --git a/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/ColorSpaces.java b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/ColorSpaces.java
new file mode 100644
index 00000000..2deffc11
--- /dev/null
+++ b/imageio/imageio-core/src/main/java/com/twelvemonkeys/imageio/color/ColorSpaces.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2011, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.color;
+
+import com.twelvemonkeys.io.FileUtil;
+import com.twelvemonkeys.lang.Validate;
+import com.twelvemonkeys.util.LRUHashMap;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+/**
+ * A helper class for working with ICC color profiles and color spaces.
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: ColorSpaces.java,v 1.0 24.01.11 17.51 haraldk Exp$
+ */
+public final class ColorSpaces {
+ // NOTE: java.awt.color.ColorSpace.CS_* uses 1000-1004, we'll use 5000+ to not interfere with future additions
+
+ /** The Adobe RGB 1998 (or compatible) color space. Either read from disk or built-in. */
+ public static final int CS_ADOBE_RGB_98 = 5000;
+
+ /** A best-effort "generic" CMYK color space. Either read from disk or built-in. */
+ public static final int CS_GENERIC_CMYK = 5001;
+
+ private static final LRUHashMap cache = new LRUHashMap(10);
+
+ private ColorSpaces() {}
+
+ /**
+ * Creates an ICC color space from the given ICC color profile.
+ *
+ * For standard Java color spaces, the built-in instance is returned.
+ * Otherwise, color spaces are looked up from cache and created on demand.
+ *
+ * @param profile the ICC color profile. May not be {@code null}.
+ * @return an ICC color space
+ * @throws IllegalArgumentException if {@code profile} is {@code null}
+ */
+ public static ICC_ColorSpace createColorSpace(final ICC_Profile profile) {
+ Validate.notNull(profile, "profile");
+
+ byte[] profileHeader = profile.getData(ICC_Profile.icSigHead);
+
+ ICC_ColorSpace cs = getInternalCS(profile, profileHeader);
+ if (cs != null) {
+ return cs;
+ }
+
+ // Special case for color profiles with rendering intent != 0, see isOffendingColorProfile method
+ // NOTE: Rendering intent is really a 4 byte value, but legal values are 0-3 (ICC1v42_2006_05_1.pdf, 7.2.15, p. 19)
+ if (profileHeader[ICC_Profile.icHdrRenderingIntent] != 0) {
+ profileHeader[ICC_Profile.icHdrRenderingIntent] = 0;
+
+ // Test again if this is an internal CS
+ cs = getInternalCS(profile, profileHeader);
+ if (cs != null) {
+ return cs;
+ }
+
+ // Fix profile
+ profile.setData(ICC_Profile.icSigHead, profileHeader);
+ }
+
+ return getCachedCS(profile, profileHeader);
+ }
+
+ private static ICC_ColorSpace getInternalCS(final ICC_Profile profile, final byte[] profileHeader) {
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_RGB && Arrays.equals(profileHeader, sRGB.header)) {
+ return (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ }
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_GRAY && Arrays.equals(profileHeader, GRAY.header)) {
+ return (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ }
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_3CLR && Arrays.equals(profileHeader, PYCC.header)) {
+ return (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_PYCC);
+ }
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_RGB && Arrays.equals(profileHeader, LINEAR_RGB.header)) {
+ return (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
+ }
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_XYZ && Arrays.equals(profileHeader, CIEXYZ.header)) {
+ return (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+ }
+
+ return null;
+ }
+
+ private static ICC_ColorSpace getCachedCS(final ICC_Profile profile, final byte[] profileHeader) {
+ Key key = new Key(profileHeader);
+
+ synchronized (cache) {
+ ICC_ColorSpace cs = cache.get(key);
+
+ if (cs == null) {
+ cs = new ICC_ColorSpace(profile);
+ cache.put(key, cs);
+ }
+
+ return cs;
+ }
+ }
+
+ /**
+ * Tests whether an ICC color profile is known to cause problems for {@link java.awt.image.ColorConvertOp}.
+ *
+ *
+ * Note that this method only tests if a color conversion using this profile is known to fail.
+ * There's no guarantee that the color conversion will succeed even if this method returns {@code false}.
+ *
+ *
+ * @param profile the ICC color profile. May not be {@code null}.
+ * @return {@code true} if known to be offending, {@code false} otherwise
+ * @throws IllegalArgumentException if {@code profile} is {@code null}
+ */
+ public static boolean isOffendingColorProfile(final ICC_Profile profile) {
+ Validate.notNull(profile, "profile");
+
+ // NOTE:
+ // Several embedded ICC color profiles are non-compliant with Java and throws CMMException
+ // The problem with these embedded ICC profiles seems to be the rendering intent
+ // being 1 (01000000) - "Media Relative Colormetric" in the offending profiles,
+ // and 0 (00000000) - "Perceptual" in the good profiles
+ // (that is 1 single bit of difference right there.. ;-)
+
+ // This is particularly annoying, as the byte copying isn't really necessary,
+ // except the getRenderingIntent method is package protected in java.awt.color
+ byte[] data = profile.getData(ICC_Profile.icSigHead);
+ return data[ICC_Profile.icHdrRenderingIntent] != 0;
+ }
+
+ // TODO: Use internal cache (needs mapping between ID and Key...)
+ // TODO: Allow system-property/config file on class path to configure location of color profiles
+ // TODO: Document how to download, install and configure Adobe color profiles or other profiles
+
+ /**
+ * Gets or creates the color space specified by the given color space constant.
+ *
+ * For standard Java color spaces, the built-in instance is returned.
+ * Otherwise, color spaces are looked up from cache and created on demand.
+ *
+ * @param colorSpace the color space constant.
+ * @return the {@link ColorSpace} specified by the color space constant.
+ * @throws IllegalArgumentException if {@code colorSpace} is not one of the defined color spaces ({@code CS_*}).
+ * @see ColorSpace
+ * @see ColorSpaces#CS_ADOBE_RGB_98
+ * @see ColorSpaces#CS_GENERIC_CMYK
+ */
+ public static ColorSpace getColorSpace(int colorSpace) {
+ switch (colorSpace) {
+ // Default cases for convenience
+ case ColorSpace.CS_sRGB:
+ case ColorSpace.CS_GRAY:
+ case ColorSpace.CS_PYCC:
+ case ColorSpace.CS_CIEXYZ:
+ case ColorSpace.CS_LINEAR_RGB:
+ return ColorSpace.getInstance(colorSpace);
+
+ case CS_ADOBE_RGB_98:
+ // TODO: Read profile specified by config file instead of hard coded
+ try {
+ // This works for OS X only
+ return createColorSpace(ICC_Profile.getInstance("/System/Library/ColorSync/Profiles/AdobeRGB1998.icc"));
+ }
+ catch (IOException ignore) {
+ }
+
+ // Fall back to the bundled ClayRGB1998 public domain Adobe RGB 1998 compatible profile
+ InputStream stream = ColorSpaces.class.getResourceAsStream("/profiles/ClayRGB1998.icc");
+ try {
+ return createColorSpace(ICC_Profile.getInstance(stream));
+ }
+ catch (IOException ignore) {
+ }
+ finally {
+ FileUtil.close(stream);
+ }
+
+ // Should never happen...
+ throw new RuntimeException("Could not read AdobeRGB1998 profile");
+
+ case CS_GENERIC_CMYK:
+ // TODO: Read profile specified by config file instead of hard coded
+ // TODO: C:\Windows\System32\spool\drivers\color\RSWOP.icm for Windows Vista?
+ try {
+ // This works for OS X only
+ return createColorSpace(ICC_Profile.getInstance("/System/Library/ColorSync/Profiles/Generic CMYK Profile.icc"));
+ }
+ catch (IOException ignore) {
+ }
+
+ // Fall back to generic CMYK ColorSpace, which is *insanely slow* using ColorConvertOp... :-P
+ return CMYKColorSpace.getInstance();
+ default:
+
+ // TODO: Allow more customizable models based on the config file?
+ }
+
+ throw new IllegalArgumentException(String.format("Unsupported color space: %s", colorSpace));
+ }
+
+ private static final class Key {
+ private final byte[] data;
+
+ public Key(byte[] data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof Key && Arrays.equals(data, ((Key) other).data);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(data);
+ }
+ }
+
+ // Cache header profile data to avoid excessive array creation/copying in static inner class for on-demand lazy init
+ private static class sRGB {
+ private static final byte[] header = ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData(ICC_Profile.icSigHead);
+ }
+ private static class CIEXYZ {
+ private static final byte[] header = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ).getData(ICC_Profile.icSigHead);
+ }
+ private static class PYCC {
+ private static final byte[] header = ICC_Profile.getInstance(ColorSpace.CS_PYCC).getData(ICC_Profile.icSigHead);
+ }
+ private static class GRAY {
+ private static final byte[] header = ICC_Profile.getInstance(ColorSpace.CS_GRAY).getData(ICC_Profile.icSigHead);
+ }
+ private static class LINEAR_RGB {
+ private static final byte[] header = ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB).getData(ICC_Profile.icSigHead);
+ }
+}
diff --git a/imageio/imageio-core/src/main/resources/profiles/ClayRGB1998.icc b/imageio/imageio-core/src/main/resources/profiles/ClayRGB1998.icc
new file mode 100644
index 00000000..1eedf093
Binary files /dev/null and b/imageio/imageio-core/src/main/resources/profiles/ClayRGB1998.icc differ
diff --git a/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/color/ColorSpacesTest.java b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/color/ColorSpacesTest.java
new file mode 100644
index 00000000..095652d8
--- /dev/null
+++ b/imageio/imageio-core/src/test/java/com/twelvemonkeys/imageio/color/ColorSpacesTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.color;
+
+import org.junit.Test;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+
+import static org.junit.Assert.*;
+
+/**
+ * ColorSpacesTest
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: haraldk$
+ * @version $Id: ColorSpacesTest.java,v 1.0 07.02.11 14.32 haraldk Exp$
+ */
+public class ColorSpacesTest {
+ @Test
+ public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_sRGB() {
+ ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(created, ColorSpace.getInstance(ColorSpace.CS_sRGB));
+ assertTrue(created.isCS_sRGB());
+ }
+
+ @Test
+ public void testCreateColorSpaceFromKnownProfileDataReturnsInternalCS_sRGB() {
+ ICC_Profile internal = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+ byte[] data = internal.getData();
+ assertNotSame(internal.getData(), data); // Sanity check
+
+ ICC_Profile profile = ICC_Profile.getInstance(data);
+ assertNotSame(internal, profile); // Sanity check
+
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(ColorSpace.getInstance(ColorSpace.CS_sRGB), created);
+ assertTrue(created.isCS_sRGB());
+ }
+
+ @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(ColorSpaces.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
+ return ICC_Profile.getInstance(data);
+ }
+
+ @Test
+ public void testIsOffendingColorProfile() {
+ ICC_Profile broken = createBrokenProfile(ICC_Profile.getInstance(ColorSpace.CS_GRAY));
+ assertTrue(ColorSpaces.isOffendingColorProfile(broken));
+ }
+
+ @Test
+ public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_GRAY() {
+ ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_GRAY);
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(ColorSpace.getInstance(ColorSpace.CS_GRAY), created);
+ }
+
+ @Test
+ public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_PYCC() {
+ ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_PYCC);
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(ColorSpace.getInstance(ColorSpace.CS_PYCC), created);
+ }
+
+ @Test
+ public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_CIEXYZ() {
+ ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(ColorSpace.getInstance(ColorSpace.CS_CIEXYZ), created);
+ }
+
+ @Test
+ public void testCreateColorSpaceFromKnownProfileReturnsInternalCS_LINEAR_RGB() {
+ ICC_Profile profile = ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB);
+ ICC_ColorSpace created = ColorSpaces.createColorSpace(profile);
+ assertSame(ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), created);
+ }
+
+ @Test
+ public void testAdobeRGB98NotNull() {
+ assertNotNull(ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_98));
+ }
+
+ @Test
+ public void testAdobeRGB98IsTypeRGB() {
+ assertEquals(ColorSpace.TYPE_RGB, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_98).getType());
+ }
+
+ @Test
+ public void testAdobeRGB98AlwaysSame() {
+ ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_98);
+ assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_ADOBE_RGB_98));
+
+ if (cs instanceof ICC_ColorSpace) {
+ ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
+ assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
+ }
+ else {
+ System.err.println("Not an ICC_ColorSpace: " + cs);
+ }
+ }
+
+ @Test
+ public void testCMYKNotNull() {
+ assertNotNull(ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK));
+ }
+
+ @Test
+ public void testCMYKIsTypeCMYK() {
+ assertEquals(ColorSpace.TYPE_CMYK, ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK).getType());
+ }
+
+ @Test
+ public void testCMYKAlwaysSame() {
+ ColorSpace cs = ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK);
+ assertSame(cs, ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK));
+
+ if (cs instanceof ICC_ColorSpace) {
+ ICC_ColorSpace iccCs = (ICC_ColorSpace) cs;
+ assertSame(cs, ColorSpaces.createColorSpace(iccCs.getProfile()));
+ }
+ else {
+ System.err.println("Not an ICC_ColorSpace: " + cs);
+ }
+ }
+}