/*
* Copyright (c) 1997, 2018, 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.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** 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.CMSManager;
/**
* This abstract class is used to serve as a color space tag to identify the
* specific color space of a {@code Color} object or, via a {@code ColorModel}
* object, of an {@code Image}, a {@code BufferedImage}, or a
* {@code 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 {@code ColorSpace}. For many {@code ColorSpaces} (e.g. sRGB), this range
* is 0.0 to 1.0. However, some {@code 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. {@code TYPE_RGB}, {@code TYPE_XYZ}, etc.) and to refer to specific
* color spaces (e.g. {@code CS_sRGB} and {@code 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 {@code ColorSpace} (e.g. {@code ICC_ColorSpace}) will support
* high performance conversion based on underlying platform color management
* systems.
* <p>
* The {@code CS_CIEXYZ} space used by the {@code 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 {@code 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 {@code ColorSpace} object given a color space type and the
* number of components.
*
* @param type one of the {@code ColorSpace} 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 {@code 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. {@code CS_sRGB},
* {@code CS_LINEAR_RGB}, {@code CS_CIEXYZ}, {@code CS_GRAY}, or
* {@code CS_PYCC})
* @return the requested {@code ColorSpace} 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 {@code ColorSpace} is {@code CS_sRGB}.
*
* @return {@code true} if this is a {@code CS_sRGB} color space,
* {@code false} 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 {@code ColorSpace} into a
* value in the default {@code 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} 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} method of the {@code CS_sRGB} color space to convert
* from {@code CS_CIEXYZ} to the output color space. See
* {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
*
* @param colorvalue a float array with length of at least the number of
* components in this {@code ColorSpace}
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not at least
* the number of components in this {@code ColorSpace}
*/
public abstract float[] toRGB(float[] colorvalue);
/**
* Transforms a color value assumed to be in the default {@code CS_sRGB}
* color space into this {@code 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} method of the {@code CS_sRGB} color space to first
* convert from the input color space to the {@code CS_CIEXYZ} color space,
* and then use the {@code fromCIEXYZ} method of this color space to convert
* from {@code CS_CIEXYZ} to the output color space. See
* {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
*
* @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 {@code 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 {@code ColorSpace} into
* the {@code 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 {@code 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 {@code 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} for further information.
*
* @param colorvalue a float array with length of at least the number of
* components in this {@code ColorSpace}
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not at least
* the number of components in this {@code ColorSpace}.
*/
public abstract float[] toCIEXYZ(float[] colorvalue);
/**
* Transforms a color value assumed to be in the {@code CS_CIEXYZ}
* conversion color space into this {@code 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 {@code 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 {@code 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} for further information.
*
* @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 {@code ColorSpace}
* @throws ArrayIndexOutOfBoundsException if array length is not at least 3
*/
public abstract float[] fromCIEXYZ(float[] colorvalue);
/**
* Returns the color space type of this {@code ColorSpace} (for example
* {@code TYPE_RGB}, {@code TYPE_XYZ}, ...). The type defines the number of
* components of the color space and the interpretation, e.g.
* {@code 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}
*/
public int getType() {
return type;
}
/**
* Returns the number of components of this ColorSpace.
*
* @return the number of components in this {@code ColorSpace}
*/
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} is less than 0 or greater
* than {@code 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:
/**代码未完, 请加载全部代码(NowJava.com).**/