001: /*
002: * $RCSfile: SimpleCMYKColorSpace.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.5 $
009: * $Date: 2006/02/17 19:08:53 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.util;
013:
014: import java.awt.color.ColorSpace;
015:
016: /**
017: * Singleton class representing a simple, mathematically defined CMYK
018: * color space.
019: */
020: public final class SimpleCMYKColorSpace extends ColorSpace {
021: private static ColorSpace theInstance = null;
022: private ColorSpace csRGB;
023:
024: /** The exponent for gamma correction. */
025: private static final double power1 = 1.0 / 2.4;
026:
027: public static final synchronized ColorSpace getInstance() {
028: if (theInstance == null) {
029: theInstance = new SimpleCMYKColorSpace();
030: }
031: return theInstance;
032: }
033:
034: private SimpleCMYKColorSpace() {
035: super (TYPE_CMYK, 4);
036: csRGB = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
037: }
038:
039: public boolean equals(Object o) {
040: return o != null && o instanceof SimpleCMYKColorSpace;
041: }
042:
043: public float[] toRGB(float[] colorvalue) {
044: float C = colorvalue[0];
045: float M = colorvalue[1];
046: float Y = colorvalue[2];
047: float K = colorvalue[3];
048:
049: float K1 = 1.0F - K;
050:
051: // Convert from CMYK to linear RGB.
052: float[] rgbvalue = new float[] { K1 * (1.0F - C),
053: K1 * (1.0F - M), K1 * (1.0F - Y) };
054:
055: // Convert from linear RGB to sRGB.
056: for (int i = 0; i < 3; i++) {
057: float v = rgbvalue[i];
058:
059: if (v < 0.0F)
060: v = 0.0F;
061:
062: if (v < 0.0031308F) {
063: rgbvalue[i] = 12.92F * v;
064: } else {
065: if (v > 1.0F)
066: v = 1.0F;
067:
068: rgbvalue[i] = (float) (1.055 * Math.pow(v, power1) - 0.055);
069: }
070: }
071:
072: return rgbvalue;
073: }
074:
075: public float[] fromRGB(float[] rgbvalue) {
076: // Convert from sRGB to linear RGB.
077: for (int i = 0; i < 3; i++) {
078: if (rgbvalue[i] < 0.040449936F) {
079: rgbvalue[i] /= 12.92F;
080: } else {
081: rgbvalue[i] = (float) (Math.pow(
082: (rgbvalue[i] + 0.055) / 1.055, 2.4));
083: }
084: }
085:
086: // Convert from linear RGB to CMYK.
087: float C = 1.0F - rgbvalue[0];
088: float M = 1.0F - rgbvalue[1];
089: float Y = 1.0F - rgbvalue[2];
090: float K = Math.min(C, Math.min(M, Y));
091:
092: // If K == 1.0F, then C = M = Y = 1.0F.
093: if (K != 1.0F) {
094: float K1 = 1.0F - K;
095:
096: C = (C - K) / K1;
097: M = (M - K) / K1;
098: Y = (Y - K) / K1;
099: } else {
100: C = M = Y = 0.0F;
101: }
102:
103: return new float[] { C, M, Y, K };
104: }
105:
106: public float[] toCIEXYZ(float[] colorvalue) {
107: return csRGB.toCIEXYZ(toRGB(colorvalue));
108: }
109:
110: public float[] fromCIEXYZ(float[] xyzvalue) {
111: return fromRGB(csRGB.fromCIEXYZ(xyzvalue));
112: }
113: }
|