blob: db96e67bb1dfedb8c14b324b9340aa0ad4fbf9b2 [file] [log] [blame]
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.imageio.plugins.common;
import java.awt.color.ColorSpace;
/**
* Singleton class representing a simple, mathematically defined CMYK
* color space.
*/
public final class SimpleCMYKColorSpace extends ColorSpace {
private static final long serialVersionUID = 5387117338644522424L;
private static ColorSpace theInstance = null;
private ColorSpace csRGB;
/** The exponent for gamma correction. */
private static final double power1 = 1.0 / 2.4;
public static final synchronized ColorSpace getInstance() {
if(theInstance == null) {
theInstance = new SimpleCMYKColorSpace();
}
return theInstance;
}
private SimpleCMYKColorSpace() {
super(TYPE_CMYK, 4);
csRGB = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
}
public boolean equals(Object o) {
return o != null && o instanceof SimpleCMYKColorSpace;
}
public int hashCode() {
return theInstance.hashCode();
}
public float[] toRGB(float[] colorvalue) {
float C = colorvalue[0];
float M = colorvalue[1];
float Y = colorvalue[2];
float K = colorvalue[3];
float K1 = 1.0F - K;
// Convert from CMYK to linear RGB.
float[] rgbvalue = new float[] {K1*(1.0F - C),
K1*(1.0F - M),
K1*(1.0F - Y)};
// Convert from linear RGB to sRGB.
for (int i = 0; i < 3; i++) {
float v = rgbvalue[i];
if (v < 0.0F) v = 0.0F;
if (v < 0.0031308F) {
rgbvalue[i] = 12.92F * v;
} else {
if (v > 1.0F) v = 1.0F;
rgbvalue[i] = (float)(1.055 * Math.pow(v, power1) - 0.055);
}
}
return rgbvalue;
}
public float[] fromRGB(float[] rgbvalue) {
// Convert from sRGB to linear RGB.
for (int i = 0; i < 3; i++) {
if (rgbvalue[i] < 0.040449936F) {
rgbvalue[i] /= 12.92F;
} else {
rgbvalue[i] =
(float)(Math.pow((rgbvalue[i] + 0.055)/1.055, 2.4));
}
}
// Convert from linear RGB to CMYK.
float C = 1.0F - rgbvalue[0];
float M = 1.0F - rgbvalue[1];
float Y = 1.0F - rgbvalue[2];
float K = Math.min(C, Math.min(M, Y));
// If K == 1.0F, then C = M = Y = 1.0F.
if(K != 1.0F) {
float K1 = 1.0F - K;
C = (C - K)/K1;
M = (M - K)/K1;
Y = (Y - K)/K1;
} else {
C = M = Y = 0.0F;
}
return new float[] {C, M, Y, K};
}
public float[] toCIEXYZ(float[] colorvalue) {
return csRGB.toCIEXYZ(toRGB(colorvalue));
}
public float[] fromCIEXYZ(float[] xyzvalue) {
return fromRGB(csRGB.fromCIEXYZ(xyzvalue));
}
}