/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
import java.lang.annotation.
Native;
import sun.java2d.cmm.
PCMM;
import sun.java2d.cmm.
CMSManager;
/**
* This abstract class is used to serve as a color space tag to identify the
* specific color space of a Color object or, via a ColorModel object,
* of an Image, a BufferedImage, or a GraphicsDevice. It contains
* methods that transform colors in a specific color space to/from sRGB
* and to/from a well-defined CIEXYZ color space.
* <p>
* For purposes of the methods in this class, colors are represented as
* arrays of color components represented as floats in a normalized range
* defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
* range is 0.0 to 1.0. However, some ColorSpaces have components whose
* values have a different range. Methods are provided to inquire per
* component minimum and maximum normalized values.
* <p>
* Several variables are defined for purposes of referring to color
* space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
* color spaces (e.g. CS_sRGB and CS_CIEXYZ).
* sRGB is a proposed standard RGB color space. For more information,
* see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
* </A>.
* <p>
* The purpose of the methods to transform to/from the well-defined
* CIEXYZ color space is to support conversions between any two color
* spaces at a reasonably high degree of accuracy. It is expected that
* particular implementations of subclasses of ColorSpace (e.g.
* ICC_ColorSpace) will support high performance conversion based on
* underlying platform color management systems.
* <p>
* The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
* described as follows:
<pre>
CIEXYZ
viewing illuminance: 200 lux
viewing white point: CIE D50
media white point: "that of a perfectly reflecting diffuser" -- D50
media black point: 0 lux or 0 Reflectance
flare: 1 percent
surround: 20percent of the media white point
media description: reflection print (i.e., RLAB, Hunt viewing media)
note: For developers creating an ICC profile for this conversion
space, the following is applicable. Use a simple Von Kries
white point adaptation folded into the 3X3 matrix parameters
and fold the flare and surround effects into the three
one-dimensional lookup tables (assuming one uses the minimal
model for monitors).
</pre>
*
* @see ICC_ColorSpace
*/
public abstract class
ColorSpace implements java.io.
Serializable {
static final long
serialVersionUID = -409452704308689724L;
private int
type;
private int
numComponents;
private transient
String []
compName = null;
// Cache of singletons for the predefined color spaces.
private static
ColorSpace sRGBspace;
private static
ColorSpace XYZspace;
private static
ColorSpace PYCCspace;
private static
ColorSpace GRAYspace;
private static
ColorSpace LINEAR_RGBspace;
/**
* Any of the family of XYZ color spaces.
*/
@
Native public static final int
TYPE_XYZ = 0;
/**
* Any of the family of Lab color spaces.
*/
@
Native public static final int
TYPE_Lab = 1;
/**
* Any of the family of Luv color spaces.
*/
@
Native public static final int
TYPE_Luv = 2;
/**
* Any of the family of YCbCr color spaces.
*/
@
Native public static final int
TYPE_YCbCr = 3;
/**
* Any of the family of Yxy color spaces.
*/
@
Native public static final int
TYPE_Yxy = 4;
/**
* Any of the family of RGB color spaces.
*/
@
Native public static final int
TYPE_RGB = 5;
/**
* Any of the family of GRAY color spaces.
*/
@
Native public static final int
TYPE_GRAY = 6;
/**
* Any of the family of HSV color spaces.
*/
@
Native public static final int
TYPE_HSV = 7;
/**
* Any of the family of HLS color spaces.
*/
@
Native public static final int
TYPE_HLS = 8;
/**
* Any of the family of CMYK color spaces.
*/
@
Native public static final int
TYPE_CMYK = 9;
/**
* Any of the family of CMY color spaces.
*/
@
Native public static final int
TYPE_CMY = 11;
/**
* Generic 2 component color spaces.
*/
@
Native public static final int
TYPE_2CLR = 12;
/**
* Generic 3 component color spaces.
*/
@
Native public static final int
TYPE_3CLR = 13;
/**
* Generic 4 component color spaces.
*/
@
Native public static final int
TYPE_4CLR = 14;
/**
* Generic 5 component color spaces.
*/
@
Native public static final int
TYPE_5CLR = 15;
/**
* Generic 6 component color spaces.
*/
@
Native public static final int
TYPE_6CLR = 16;
/**
* Generic 7 component color spaces.
*/
@
Native public static final int
TYPE_7CLR = 17;
/**
* Generic 8 component color spaces.
*/
@
Native public static final int
TYPE_8CLR = 18;
/**
* Generic 9 component color spaces.
*/
@
Native public static final int
TYPE_9CLR = 19;
/**
* Generic 10 component color spaces.
*/
@
Native public static final int
TYPE_ACLR = 20;
/**
* Generic 11 component color spaces.
*/
@
Native public static final int
TYPE_BCLR = 21;
/**
* Generic 12 component color spaces.
*/
@
Native public static final int
TYPE_CCLR = 22;
/**
* Generic 13 component color spaces.
*/
@
Native public static final int
TYPE_DCLR = 23;
/**
* Generic 14 component color spaces.
*/
@
Native public static final int
TYPE_ECLR = 24;
/**
* Generic 15 component color spaces.
*/
@
Native public static final int
TYPE_FCLR = 25;
/**
* The sRGB color space defined at
* <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
* </A>.
*/
@
Native public static final int
CS_sRGB = 1000;
/**
* A built-in linear RGB color space. This space is based on the
* same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
*/
@
Native public static final int
CS_LINEAR_RGB = 1004;
/**
* The CIEXYZ conversion color space defined above.
*/
@
Native public static final int
CS_CIEXYZ = 1001;
/**
* The Photo YCC conversion color space.
*/
@
Native public static final int
CS_PYCC = 1002;
/**
* The built-in linear gray scale color space.
*/
@
Native public static final int
CS_GRAY = 1003;
/**
* Constructs a ColorSpace object given a color space type
* and the number of components.
* @param type one of the <CODE>ColorSpace</CODE> type constants
* @param numcomponents the number of components in the color space
*/
protected
ColorSpace (int
type, int
numcomponents) {
this.
type =
type;
this.
numComponents =
numcomponents;
}
/**
* Returns a ColorSpace representing one of the specific
* predefined color spaces.
* @param colorspace a specific color space identified by one of
* the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
* CS_CIEXYZ, CS_GRAY, or CS_PYCC)
* @return the requested <CODE>ColorSpace</CODE> object
*/
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public static
ColorSpace getInstance (int
colorspace)
{
ColorSpace theColorSpace;
switch (
colorspace) {
case
CS_sRGB:
synchronized(
ColorSpace.class) {
if (
sRGBspace == null) {
ICC_Profile theProfile =
ICC_Profile.
getInstance (
CS_sRGB);
sRGBspace = new
ICC_ColorSpace (
theProfile);
}
theColorSpace =
sRGBspace;
}
break;
case
CS_CIEXYZ:
synchronized(
ColorSpace.class) {
if (
XYZspace == null) {
ICC_Profile theProfile =
ICC_Profile.
getInstance (
CS_CIEXYZ);
XYZspace = new
ICC_ColorSpace (
theProfile);
}
theColorSpace =
XYZspace;
}
break;
case
CS_PYCC:
synchronized(
ColorSpace.class) {
if (
PYCCspace == null) {
ICC_Profile theProfile =
ICC_Profile.
getInstance (
CS_PYCC);
PYCCspace = new
ICC_ColorSpace (
theProfile);
}
theColorSpace =
PYCCspace;
}
break;
case
CS_GRAY:
synchronized(
ColorSpace.class) {
if (
GRAYspace == null) {
ICC_Profile theProfile =
ICC_Profile.
getInstance (
CS_GRAY);
GRAYspace = new
ICC_ColorSpace (
theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.
GRAYspace =
GRAYspace;
}
theColorSpace =
GRAYspace;
}
break;
case
CS_LINEAR_RGB:
synchronized(
ColorSpace.class) {
if (
LINEAR_RGBspace == null) {
ICC_Profile theProfile =
ICC_Profile.
getInstance(
CS_LINEAR_RGB);
LINEAR_RGBspace = new
ICC_ColorSpace (
theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.
LINEAR_RGBspace =
LINEAR_RGBspace;
}
theColorSpace =
LINEAR_RGBspace;
}
break;
default:
throw new
IllegalArgumentException ("Unknown color space");
}
return
theColorSpace;
}
/**
* Returns true if the ColorSpace is CS_sRGB.
* @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
* space, <code>false</code> if it is not
*/
public boolean
isCS_sRGB () {
/* REMIND - make sure we know sRGBspace exists already */
return (this ==
sRGBspace);
}
/**
* Transforms a color value assumed to be in this ColorSpace
* into a value in the default CS_sRGB color space.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of this color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace
*/
public abstract float[]
toRGB(float[]
colorvalue);
/**
* Transforms a color value assumed to be in the default CS_sRGB
* color space into this ColorSpace.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of the CS_sRGB color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of this color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param rgbvalue a float array with length of at least 3
* @return a float array with length equal to the number of
* components in this ColorSpace
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3
*/
public abstract float[]
fromRGB(float[]
rgbvalue);
/**
* Transforms a color value assumed to be in this ColorSpace
* into the CS_CIEXYZ conversion color space.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the International Color Consortium standard. This
* means that the XYZ values returned by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. This
* representation is not the same as the XYZ values that would
* be measured from the given color value by a colorimeter.
* A further transformation is necessary to compute the XYZ values
* that would be measured using current CIE recommended practices.
* See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
* <code>ICC_ColorSpace</code> for further information.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace.
*/
public abstract float[]
toCIEXYZ(float[]
colorvalue);
/**
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
* color space into this ColorSpace.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the International Color Consortium standard. This
* means that the XYZ argument values taken by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. The color
* values returned by this method are not those that would produce
* the XYZ value passed to the method when measured by a colorimeter.
* If you have XYZ values corresponding to measurements made using
* current CIE recommended practices, they must be converted to D50
* relative values before being passed to this method.
* See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
* <code>ICC_ColorSpace</code> for further information.
* <p>
* @param colorvalue a float array with length of at least 3
* @return a float array with length equal to the number of
* components in this ColorSpace
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3
*/
public abstract float[]
fromCIEXYZ(float[]
colorvalue);
/**
* Returns the color space type of this ColorSpace (for example
* TYPE_RGB, TYPE_XYZ, ...). The type defines the
* number of components of the color space and the interpretation,
* e.g. TYPE_RGB identifies a color space with three components - red,
* green, and blue. It does not define the particular color
* characteristics of the space, e.g. the chromaticities of the
* primaries.
*
* @return the type constant that represents the type of this
* <CODE>ColorSpace</CODE>
*/
public int
getType() {
return
type;
}
/**
* Returns the number of components of this ColorSpace.
* @return The number of components in this <CODE>ColorSpace</CODE>.
*/
public int
getNumComponents() {
return
numComponents;
}
/**
* Returns the name of the component given the component index.
*
* @param idx the component index
* @return the name of the component at the specified index
* @throws IllegalArgumentException if <code>idx</code> is
* less than 0 or greater than numComponents - 1
*/
public
String getName (int
idx) {
/* REMIND - handle common cases here */
if ((
idx < 0) || (
idx >
numComponents - 1)) {
throw new
IllegalArgumentException(
"Component index out of range: " +
idx);
}
if (
compName == null) {
switch (
type) {
case
ColorSpace.
TYPE_XYZ:
compName = new
String[] {"X", "Y", "Z"};
break;
case
ColorSpace.
TYPE_Lab:
compName = new
String[] {"L", "a", "b"};
break;
case
ColorSpace.
TYPE_Luv:
compName = new
String[] {"L", "u", "v"};
break;
case
ColorSpace.
TYPE_YCbCr:
compName = new
String[] {"Y", "Cb", "Cr"};
break;
case
ColorSpace.
TYPE_Yxy:
compName = new
String[] {"Y", "x", "y"};
break;
case
ColorSpace.
TYPE_RGB:
compName = new
String[] {"Red", "Green", "Blue"};
break;
case
ColorSpace.
TYPE_GRAY:
compName = new
String[] {"Gray"};
break;
case
ColorSpace.
TYPE_HSV:
compName = new
String[] {"Hue", "Saturation", "Value"};
break;
case
ColorSpace.
TYPE_HLS:
compName = new
String[] {"Hue", "Lightness",
"Saturation"};
break;
case
ColorSpace.
TYPE_CMYK:
compName = new
String[] {"Cyan", "Magenta", "Yellow",
"Black"};
break;
case
ColorSpace.
TYPE_CMY:
compName = new
String[] {"Cyan", "Magenta", "Yellow"};
break;
default:
String []
tmp = new
String[
numComponents];
for (int
i = 0;
i <
tmp.length;
i++) {
tmp[
i] = "Unnamed color component(" +
i + ")";
}
compName =
tmp;
}
}
return
compName[
idx];
}
/**
* Returns the minimum normalized color component value for the
* specified component. The default implementation in this abstract
* class returns 0.0 for all components. Subclasses should override
* this method if necessary.
*
* @param component the component index
* @return the minimum normalized component value
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1
* @since 1.4
*/
public float
getMinValue(int
component) {
if ((
component < 0) || (
component >
numComponents - 1)) {
throw new
IllegalArgumentException(
"Component index out of range: " +
component);
}
return 0.0f;
}
/**
* Returns the maximum normalized color component value for the
* specified component. The default implementation in this abstract
* class returns 1.0 for all components. Subclasses should override
* this method if necessary.
*
* @param component the component index
* @return the maximum normalized component value
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1
* @since 1.4
*/
public float
getMaxValue(int
component) {
if ((
component < 0) || (
component >
numComponents - 1)) {
throw new
IllegalArgumentException(
"Component index out of range: " +
component);
}
return 1.0f;
}
/* Returns true if cspace is the XYZspace.
*/
static boolean
isCS_CIEXYZ(
ColorSpace cspace) {
return (
cspace ==
XYZspace);
}
}