javax.media.jai
Class ColorSpaceJAI

java.lang.Object
  extended byjava.awt.color.ColorSpace
      extended byjavax.media.jai.ColorSpaceJAI
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
IHSColorSpace

public abstract class ColorSpaceJAI
extends ColorSpace

An abstract subclass of ColorSpace which adds methods to transform colors represented as pixels in a Raster between a specific color space and either sRGB or a well-defined C.I.E. X,Y,Z color space. As mentioned in the documentation of ColorSpace, sRGB is a proposed standard default RGB color space for the Internet.

This class is particularly applicable for use with color spaces which are mathematically defined and for which no I.C.C. profile is readily available. (Note however that color conversions specified by a simple matrix transformation might best be effected using the "BandCombine" operation.) The JAI "ColorConvert" operation recognizes when an instance of ColorSpaceJAI is present and uses the Raster-based conversion methods to improve performance. This is possible because without the ColorSpaceJAI definition, a ColorSpace which was not an ICC_ColorSpace would permit color conversion only by means of pixel-by-pixel invocations of toCIEXYZ(float[]) and fromCIEXYZ(float[]) (or, equivalently toRGB(float[]) and fromRGB(float[])).

Since:
JAI 1.1
See Also:
ColorSpace, ICC_ColorSpace, ColorConvertDescriptor, BandCombineDescriptor, Serialized Form

Field Summary
 
Fields inherited from class java.awt.color.ColorSpace
CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC, CS_sRGB, TYPE_2CLR, TYPE_3CLR, TYPE_4CLR, TYPE_5CLR, TYPE_6CLR, TYPE_7CLR, TYPE_8CLR, TYPE_9CLR, TYPE_ACLR, TYPE_BCLR, TYPE_CCLR, TYPE_CMY, TYPE_CMYK, TYPE_DCLR, TYPE_ECLR, TYPE_FCLR, TYPE_GRAY, TYPE_HLS, TYPE_HSV, TYPE_Lab, TYPE_Luv, TYPE_RGB, TYPE_XYZ, TYPE_YCbCr, TYPE_Yxy
 
Constructor Summary
protected ColorSpaceJAI(int type, int numComponents, boolean isRGBPreferredIntermediary)
          Constructs a ColorSpaceJAI object given the color space type, the number of components, and an indicator of the preferred intermediary or connection color space.
 
Method Summary
protected static void checkParameters(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Verify that the parameters are compatible with the limitations of the static methods CIEXYZToRGB(java.awt.image.Raster, int[], java.awt.image.WritableRaster, int[]) and RGBToCIEXYZ(java.awt.image.Raster, int[], java.awt.image.WritableRaster, int[]).
static WritableRaster CIEXYZToRGB(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from CIEXYZ to sRGB.
abstract  WritableRaster fromCIEXYZ(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from CIEXYZ values with respect to the CIE D50 white point to the color space represented by this class.
abstract  WritableRaster fromRGB(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from sRGB to the color space represented by this class.
 boolean isRGBPreferredIntermediary()
          Whether sRGB is the preferred intermediary color space when converting to another color space which is neither sRGB nor CIEXYZ.
static WritableRaster RGBToCIEXYZ(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from sRGB to CIEXYZ.
abstract  WritableRaster toCIEXYZ(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from the color space represented by this class to CIEXYZ values with respect to the CIE D50 white point.
abstract  WritableRaster toRGB(Raster src, int[] srcComponentSize, WritableRaster dest, int[] destComponentSize)
          Transforms the pixel data in the source Raster from the color space represented by this class to sRGB.
 
Methods inherited from class java.awt.color.ColorSpace
fromCIEXYZ, fromRGB, getInstance, getMaxValue, getMinValue, getName, getNumComponents, getType, isCS_sRGB, toCIEXYZ, toRGB
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ColorSpaceJAI

protected ColorSpaceJAI(int type,
                        int numComponents,
                        boolean isRGBPreferredIntermediary)
Constructs a ColorSpaceJAI object given the color space type, the number of components, and an indicator of the preferred intermediary or connection color space.

Parameters:
type - The color space type (ColorSpace.TYPE_*).
numComponents - The number of color components.
isRGBPreferredIntermediary - Whether sRGB (true) or CIEXYZ (false) is the preferred connection color space.
Throws:
IllegalArgumentException - if numComponents is non-positive.
Method Detail

CIEXYZToRGB

public static WritableRaster CIEXYZToRGB(Raster src,
                                         int[] srcComponentSize,
                                         WritableRaster dest,
                                         int[] destComponentSize)
Transforms the pixel data in the source Raster from CIEXYZ to sRGB. It is assumed that the input XYZ values are represented relative to the CIE D50 white point of the ColorSpace.CS_CIEXYZ color space. Integral data will be normalized according to the number of bits specified for the respective component; floating point data should be between 0.0 and 1.0 + (32767.0 / 32768.0). All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

The exact sequence of transformations applied is as follows:

  1. If the source data are integral, convert the digital codes to CIE XYZ values in the range [0.0, Fmax] as:
     Fd50 = Fmax * Isrc / 2Msrc
     
    where
     Isrc is the digital code of a source color component
     Msrc is the number of significant bits per source color
     component
     Fmax is 1.0 + (32767.0 / 32768.0)
     Fd50 is the corresponding CIE XYZ value relative to CIE D50
     
    If the source data are floating point no scaling is performed and it is assumed that the data are already clipped to the range [0.0, 1.0 + (32767.0 / 32768.0)].
  2. Perform chromatic adaptation from the CIE D50 white point to the CIE D65 white point as described in ICC_ColorSpace.fromCIEXYZ(float[]):
     Xd65 = Xd50 * (Xwd65 / Xwd50)
     Yd65 = Yd50 * (Ywd65 / Ywd50)
     Zd65 = Zd50 * (Zwd65 / Zwd50)
     
    where
     Xd50, Yd50, Zd50 are the XYZ values relative to CIE D50
     Xwd65, Ywd65, Zwd65 are the CIE D65 white point values
     Xwd50, Ywd50, Zwd50 are the CIE D50 white point values
     Xd65, Yd65, Zd65 are the XYZ values relative to CIE D65
     
    Substituting the actual CIE D50 and D65 white point values in the above gives:
     Xd65 = Xd50 * (0.3127/0.3457)
     Yd65 = Yd50 * (0.3291/0.3585)
     Zd65 = Zd50 * (0.3582/0.2958)
     
  3. Calculate sRGB tristimulus values as:
     [ RsRGB ]   [  3.2406 -1.5372 -0.4986 ] [ Xd65 ]
     [ GsRGB ] = [ -0.9689  1.8758  0.0415 ] [ Yd65 ]
     [ BsRGB ]   [  0.0557 -0.2040  1.0570 ] [ Zd65 ]
     
  4. Clip sRGB tristimulus values to the range [0.0, 1.0].
  5. Transform sRGB tristimulus values to non-linear sR'G'B' values as:
     C'sRGB = 12.92*CsRGB if CsRGB <= 0.0031308
     C'sRGB = 1.055*CsRGB(1.0/2.4) - 0.055 if CsRGB > 0.0031308
     
    where
     CsRGB is a sRGB tristimulus value
     C'sRGB is the corresponding non-linear sR'G'B' value
     
  6. If the destination data are integral, convert the non-linear sR'G'B' values to digital codes as:
     Idest = round(C'sRGB * 2Mdest)
     
    where
     C'sRGB is the a non-linear sR'G'B' value
     Mdest is the number of significant bits per destination color
     component
     Idest is the digital code of a destination color component
     
    If the destination data are floating point neither scaling nor rounding is performed.

If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

This method is provided for the convenience of extenders defining a color space for which the conversion is defined with respect to CIEXYZ.

It should be noted that there is no official specification of sRGB with respect to digital codes of depths other than 8 bits. The present implementation for other bit depths is provided as an extrapolation of the 8-bit sRGB standard and its use should be recognized as such. The extrapolation is implemented by replacing the white digital count (WDC) and black digital count (KDC) in the 8-bit sRGB specification with values corresponding to the extrema of the data type in question when treated as unsigned. For all data types KDC is zero and WDC is specified by the component size parameters.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands is not 3, or either component size array is non-null and has length not equal to 3.

checkParameters

protected static void checkParameters(Raster src,
                                      int[] srcComponentSize,
                                      WritableRaster dest,
                                      int[] destComponentSize)
Verify that the parameters are compatible with the limitations of the static methods CIEXYZToRGB(java.awt.image.Raster, int[], java.awt.image.WritableRaster, int[]) and RGBToCIEXYZ(java.awt.image.Raster, int[], java.awt.image.WritableRaster, int[]). If any of the parameters are not compatible with the requirements of these methods, throw an IllegalArgumentException

Throws:
IllegalArgumentException - if src is null.
IllegalArgumentException - if src.getNumBands() does not return the value 3.
IllegalArgumentException - if dst is non-null and dst.getNumBands() does not return the value 3.
IllegalArgumentException - if srcComponentSize is non-null but its length is not 3.
IllegalArgumentException - if destComponentSize is non-null but its length is not 3.

RGBToCIEXYZ

public static WritableRaster RGBToCIEXYZ(Raster src,
                                         int[] srcComponentSize,
                                         WritableRaster dest,
                                         int[] destComponentSize)
Transforms the pixel data in the source Raster from sRGB to CIEXYZ. The output XYZ values are represented relative to the CIE D50 white point of the ColorSpace.CS_CIEXYZ color space. Integral data will be normalized according to the number of bits specified for the respective component; floating point data should be between 0.0 and 1.0. All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

The exact sequence of transformations applied is as follows:

  1. If the source data are integral, convert the digital codes to non-linear sRGB values in the range [0.0, 1.0] as:
     C'sRGB = Isrc / 2Msrc
     
    where
     Isrc is the digital code of a source color component
     Msrc is the number of significant bits per source color
     component
     C'sRGB is the corresponding sR'G'B' value
     
    If the source data are floating point no scaling is performed and it is assumed that the data are already clipped to the range [0.0, 1.0].
  2. Transform non-linear sR'G'B' values to sRGB tristimulus values as:
     CsRGB = C'sRGB/12.92 if C'sRGB <= 0.04045
     CsRGB = [(C'sRGB + 0.055)/1.055]2.4 if C'sRGB > 0.04045
     
    where
     C'sRGB is a non-linear sR'G'B' value
     CsRGB is the corresponding sRGB tristimulus value
     
  3. Calculate CIE XYZ D65-relative values as:
     [ Xd65 ]   [ 0.4124 0.3576 0.1805 ] [ RsRGB ]
     [ Yd65 ] = [ 0.2126 0.7152 0.0722 ] [ GsRGB ]
     [ Zd65 ]   [ 0.0193 0.1192 0.9505 ] [ BsRGB ]
     
  4. Perform chromatic adaptation from the CIE D65 white point to the CIE D50 white point as described in ICC_ColorSpace.toCIEXYZ(float[]):
     Xd50 = Xd65 * (Xwd50 / Xwd65)
     Yd50 = Yd65 * (Ywd50 / Ywd65)
     Zd50 = Zd65 * (Zwd50 / Zwd65)
     
    where
     Xd65, Yd65, Zd65 are the XYZ values relative to CIE D65
     Xwd50, Ywd50, Zwd50 are the CIE D50 white point values
     Xwd65, Ywd65, Zwd65 are the CIE D65 white point values
     Xd50, Yd50, Zd50 are the XYZ values relative to CIE D50
     
    Substituting the actual CIE D50 and D65 white point values in the above gives:
     Xd50 = Xd65 * (0.3457/0.3127)
     Yd50 = Yd65 * (0.3585/0.3291)
     Zd50 = Zd65 * (0.2958/0.3582)
     
  5. If the destination data are integral, convert the CIE XYZ values to digital codes as:
     Idest = round(Fd50 * 2Mdest / Fmax)
     
    where
     Fd50 is a CIE XYZ value relative to CIE D50
     Mdest is the number of significant bits per destination color
     component
     Fmax is 1.0 + (32767.0 / 32768.0)
     Idest is the digital code of a destination color component
     
    If the destination data are floating point neither scaling nor rounding is performed.

If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

This method is provided for the convenience of extenders defining a color space for which the conversion is defined with respect to sRGB.

It should be noted that there is no official specification of sRGB with respect to digital codes of depths other than 8 bits. The present implementation for other bit depths is provided as an extrapolation of the 8-bit sRGB standard and its use should be recognized as such. The extrapolation is implemented by replacing the white digital count (WDC) and black digital count (KDC) in the 8-bit sRGB specification with values corresponding to the extrema of the data type in question when treated as unsigned. For all data types KDC is zero and WDC is specified by the component size parameters.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands is not 3, or either component size array is non-null and has length not equal to 3.

isRGBPreferredIntermediary

public boolean isRGBPreferredIntermediary()
Whether sRGB is the preferred intermediary color space when converting to another color space which is neither sRGB nor CIEXYZ. This serves to indicate the more efficient conversion pathway.

Returns:
true if sRGB is preferred, or false if CIEXYZ is preferred.

fromCIEXYZ

public abstract WritableRaster fromCIEXYZ(Raster src,
                                          int[] srcComponentSize,
                                          WritableRaster dest,
                                          int[] destComponentSize)
Transforms the pixel data in the source Raster from CIEXYZ values with respect to the CIE D50 white point to the color space represented by this class. If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

If required by the underlying transformation, integral data will be normalized according to the number of bits of the respective component; floating point data should be between 0.0 and 1.0 + (32767.0 / 32768.0). All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands does not equal the number of components of the respective color space, or either component size array is non-null and has length not equal to the number of bands in the respective Raster.

fromRGB

public abstract WritableRaster fromRGB(Raster src,
                                       int[] srcComponentSize,
                                       WritableRaster dest,
                                       int[] destComponentSize)
Transforms the pixel data in the source Raster from sRGB to the color space represented by this class. If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

If required by the underlying transformation, integral data will be normalized according to the number of bits of the respective component; floating point data should be between 0.0 and 1.0. All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands does not equal the number of components of the respective color space, or either component size array is non-null and has length not equal to the number of bands in the respective Raster.

toCIEXYZ

public abstract WritableRaster toCIEXYZ(Raster src,
                                        int[] srcComponentSize,
                                        WritableRaster dest,
                                        int[] destComponentSize)
Transforms the pixel data in the source Raster from the color space represented by this class to CIEXYZ values with respect to the CIE D50 white point. If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

If required by the underlying transformation, integral data will be normalized according to the number of bits of the respective component; floating point data should be between 0.0 and 1.0. All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands does not equal the number of components of the respective color space, or either component size array is non-null and has length not equal to the number of bands in the respective Raster.

toRGB

public abstract WritableRaster toRGB(Raster src,
                                     int[] srcComponentSize,
                                     WritableRaster dest,
                                     int[] destComponentSize)
Transforms the pixel data in the source Raster from the color space represented by this class to sRGB. If the destination WritableRaster is null, a new WritableRaster will be created. The Rasters are treated as having no alpha channel, i.e., all bands are color bands.

If required by the underlying transformation, integral data will be normalized according to the number of bits of the respective component; floating point data should be between 0.0 and 1.0. All integral data are assumed to be unsigned; signed data should be shifted by the caller before invoking this method.

Parameters:
src - the source Raster to be converted.
srcComponentSize - array that specifies the number of significant bits per source color component; ignored for floating point data. If null defaults to the value returned by src.getSampleModel().getSampleSize().
dest - the destination WritableRaster, or null.
destComponentSize - array that specifies the number of significant bits per destination color component; ignored for floating point data. If null, defaults to the value returned by dest.getSampleModel().getSampleSize(), or the sample size of the newly created destination WritableRaster if dest is null.
Returns:
dest color converted from src or a new, WritableRaster containing the converted pixels if dest is null.
Throws:
IllegalArgumentException - if src is null, the number of source or destination bands does not equal the number of components of the respective color space, or either component size array is non-null and has length not equal to the number of bands in the respective Raster.