use of sun.java2d.cmm.ColorTransform in project jdk8u_jdk by JetBrains.
the class ICC_ColorSpace method toCIEXYZ.
/**
* 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 ICC Specification. 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.
* The paragraphs below explain this in more detail.
* <p>
* The ICC standard uses a device independent color space (DICS) as the
* mechanism for converting color from one device to another device. In
* this architecture, colors are converted from the source device's color
* space to the ICC DICS and then from the ICC DICS to the destination
* device's color space. The ICC standard defines device profiles which
* contain transforms which will convert between a device's color space
* and the ICC DICS. The overall conversion of colors from a source
* device to colors of a destination device is done by connecting the
* device-to-DICS transform of the profile for the source device to the
* DICS-to-device transform of the profile for the destination device.
* For this reason, the ICC DICS is commonly referred to as the profile
* connection space (PCS). The color space used in the methods
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
* Specification. This is also the color space represented by
* ColorSpace.CS_CIEXYZ.
* <p>
* The XYZ values of a color are often represented as relative to some
* white point, so the actual meaning of the XYZ values cannot be known
* without knowing the white point of those values. This is known as
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
* values of the PCS are relative to D50. For example, white in the PCS
* will have the XYZ values of D50, which is defined to be X=.9642,
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
* arts applications, but others are often used in other applications.
* <p>
* To quantify the color characteristics of a device such as a printer
* or monitor, measurements of XYZ values for particular device colors
* are typically made. For purposes of this discussion, the term
* device XYZ values is used to mean the XYZ values that would be
* measured from device colors using current CIE recommended practices.
* <p>
* Converting between device XYZ values and the PCS XYZ values returned
* by this method corresponds to converting between the device's color
* space, as represented by CIE colorimetric values, and the PCS. There
* are many factors involved in this process, some of which are quite
* subtle. The most important, however, is the adjustment made to account
* for differences between the device's white point and the white point of
* the PCS. There are many techniques for doing this and it is the
* subject of much current research and controversy. Some commonly used
* methods are XYZ scaling, the von Kries transform, and the Bradford
* transform. The proper method to use depends upon each particular
* application.
* <p>
* The simplest method is XYZ scaling. In this method each device XYZ
* value is converted to a PCS XYZ value by multiplying it by the ratio
* of the PCS white point (D50) to the device white point.
* <pre>
*
* Xd, Yd, Zd are the device XYZ values
* Xdw, Ydw, Zdw are the device XYZ white point values
* Xp, Yp, Zp are the PCS XYZ values
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
*
* Xp = Xd * (Xd50 / Xdw)
* Yp = Yd * (Yd50 / Ydw)
* Zp = Zd * (Zd50 / Zdw)
*
* </pre>
* <p>
* Conversion from the PCS to the device would be done by inverting these
* equations:
* <pre>
*
* Xd = Xp * (Xdw / Xd50)
* Yd = Yp * (Ydw / Yd50)
* Zd = Zp * (Zdw / Zd50)
*
* </pre>
* <p>
* Note that the media white point tag in an ICC profile is not the same
* as the device white point. The media white point tag is expressed in
* PCS values and is used to represent the difference between the XYZ of
* device illuminant and the XYZ of the device media when measured under
* that illuminant. The device white point is expressed as the device
* XYZ values corresponding to white displayed on the device. For
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
* will result in a measured device XYZ value of D65. This will not
* be the same as the media white point tag XYZ value in the ICC
* profile for an sRGB device.
* <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 float[] toCIEXYZ(float[] colorvalue) {
if (this2xyz == null) {
ColorTransform[] transformList = new ColorTransform[2];
ICC_ColorSpace xyzCS = (ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ);
PCMM mdl = CMSManager.getModule();
try {
transformList[0] = mdl.createTransform(thisProfile, ICC_Profile.icRelativeColorimetric, ColorTransform.In);
} catch (CMMException e) {
transformList[0] = mdl.createTransform(thisProfile, ColorTransform.Any, ColorTransform.In);
}
transformList[1] = mdl.createTransform(xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
this2xyz = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
int nc = this.getNumComponents();
short[] tmp = new short[nc];
for (int i = 0; i < nc; i++) {
tmp[i] = (short) ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
}
tmp = this2xyz.colorConvert(tmp, null);
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
float[] result = new float[3];
for (int i = 0; i < 3; i++) {
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
}
return result;
}
use of sun.java2d.cmm.ColorTransform in project jdk8u_jdk by JetBrains.
the class ICC_ColorSpace method toRGB.
/**
* 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 float[] toRGB(float[] colorvalue) {
if (this2srgb == null) {
ColorTransform[] transformList = new ColorTransform[2];
ICC_ColorSpace srgbCS = (ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB);
PCMM mdl = CMSManager.getModule();
transformList[0] = mdl.createTransform(thisProfile, ColorTransform.Any, ColorTransform.In);
transformList[1] = mdl.createTransform(srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
this2srgb = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
int nc = this.getNumComponents();
short[] tmp = new short[nc];
for (int i = 0; i < nc; i++) {
tmp[i] = (short) ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
}
tmp = this2srgb.colorConvert(tmp, null);
float[] result = new float[3];
for (int i = 0; i < 3; i++) {
result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
}
return result;
}
use of sun.java2d.cmm.ColorTransform in project jdk8u_jdk by JetBrains.
the class ICC_ColorSpace method fromRGB.
/**
* 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 float[] fromRGB(float[] rgbvalue) {
if (srgb2this == null) {
ColorTransform[] transformList = new ColorTransform[2];
ICC_ColorSpace srgbCS = (ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB);
PCMM mdl = CMSManager.getModule();
transformList[0] = mdl.createTransform(srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
transformList[1] = mdl.createTransform(thisProfile, ColorTransform.Any, ColorTransform.Out);
srgb2this = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
short[] tmp = new short[3];
for (int i = 0; i < 3; i++) {
tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
}
tmp = srgb2this.colorConvert(tmp, null);
int nc = this.getNumComponents();
float[] result = new float[nc];
for (int i = 0; i < nc; i++) {
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * diffMinMax[i] + minVal[i];
}
return result;
}
use of sun.java2d.cmm.ColorTransform in project jdk8u_jdk by JetBrains.
the class ColorConvertOp method filter.
/**
* ColorConverts the image data in the source Raster.
* If the destination Raster is null, a new Raster will be created.
* The number of bands in the source and destination Rasters must
* meet the requirements explained above. The constructor used to
* create this ColorConvertOp must have provided enough information
* to define both source and destination color spaces. See above.
* Otherwise, an exception is thrown.
* @param src the source <code>Raster</code> to be converted
* @param dest the destination <code>WritableRaster</code>,
* or <code>null</code>
* @return <code>dest</code> color converted from <code>src</code>
* or a new, converted <code>WritableRaster</code>
* if <code>dest</code> is <code>null</code>
* @exception IllegalArgumentException if the number of source or
* destination bands is incorrect, the source or destination
* color spaces are undefined, or this op was constructed
* with one of the constructors that applies only to
* operations on BufferedImages.
*/
public final WritableRaster filter(Raster src, WritableRaster dest) {
if (CSList != null) {
/* non-ICC case */
return nonICCRasterFilter(src, dest);
}
int nProfiles = profileList.length;
if (nProfiles < 2) {
throw new IllegalArgumentException("Source or Destination ColorSpace is undefined");
}
if (src.getNumBands() != profileList[0].getNumComponents()) {
throw new IllegalArgumentException("Numbers of source Raster bands and source color space " + "components do not match");
}
if (dest == null) {
dest = createCompatibleDestRaster(src);
} else {
if (src.getHeight() != dest.getHeight() || src.getWidth() != dest.getWidth()) {
throw new IllegalArgumentException("Width or height of Rasters do not match");
}
if (dest.getNumBands() != profileList[nProfiles - 1].getNumComponents()) {
throw new IllegalArgumentException("Numbers of destination Raster bands and destination " + "color space components do not match");
}
}
/* make a new transform if needed */
if (thisRasterTransform == null) {
int i1, whichTrans, renderState;
ColorTransform[] theTransforms;
/* make the transform list */
theTransforms = new ColorTransform[nProfiles];
/* initialize transform get loop */
if (profileList[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
/* if first profile is a printer
render as colorimetric */
renderState = ICC_Profile.icRelativeColorimetric;
} else {
renderState = ICC_Profile.icPerceptual;
/* render any other
class perceptually */
}
whichTrans = ColorTransform.In;
PCMM mdl = CMSManager.getModule();
/* get the transforms from each profile */
for (i1 = 0; i1 < nProfiles; i1++) {
if (i1 == nProfiles - 1) {
/* last profile? */
whichTrans = ColorTransform.Out;
/* get output transform */
} else {
/* check for abstract profile */
if ((whichTrans == ColorTransform.Simulation) && (profileList[i1].getProfileClass() == ICC_Profile.CLASS_ABSTRACT)) {
renderState = ICC_Profile.icPerceptual;
whichTrans = ColorTransform.In;
}
}
theTransforms[i1] = mdl.createTransform(profileList[i1], renderState, whichTrans);
/* get this profile's rendering intent to select transform
from next profile */
renderState = getRenderingIntent(profileList[i1]);
/* "middle" profiles use simulation transform */
whichTrans = ColorTransform.Simulation;
}
/* make the net transform */
thisRasterTransform = mdl.createTransform(theTransforms);
}
int srcTransferType = src.getTransferType();
int dstTransferType = dest.getTransferType();
if ((srcTransferType == DataBuffer.TYPE_FLOAT) || (srcTransferType == DataBuffer.TYPE_DOUBLE) || (dstTransferType == DataBuffer.TYPE_FLOAT) || (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
if (srcMinVals == null) {
getMinMaxValsFromProfiles(profileList[0], profileList[nProfiles - 1]);
}
/* color convert the raster */
thisRasterTransform.colorConvert(src, dest, srcMinVals, srcMaxVals, dstMinVals, dstMaxVals);
} else {
/* color convert the raster */
thisRasterTransform.colorConvert(src, dest);
}
return dest;
}
use of sun.java2d.cmm.ColorTransform in project jdk8u_jdk by JetBrains.
the class ColorConvertOp method updateBITransform.
private void updateBITransform(ICC_Profile srcProfile, ICC_Profile destProfile) {
ICC_Profile[] theProfiles;
int i1, nProfiles, nTransforms, whichTrans, renderState;
ColorTransform[] theTransforms;
boolean useSrc = false, useDest = false;
nProfiles = profileList.length;
nTransforms = nProfiles;
if ((nProfiles == 0) || (srcProfile != profileList[0])) {
nTransforms += 1;
useSrc = true;
}
if ((nProfiles == 0) || (destProfile != profileList[nProfiles - 1]) || (nTransforms < 2)) {
nTransforms += 1;
useDest = true;
}
/* make the profile list */
theProfiles = new ICC_Profile[nTransforms];
/* the list of profiles
for this Op */
int idx = 0;
if (useSrc) {
/* insert source as first profile */
theProfiles[idx++] = srcProfile;
}
for (i1 = 0; i1 < nProfiles; i1++) {
/* insert profiles defined in this Op */
theProfiles[idx++] = profileList[i1];
}
if (useDest) {
/* insert dest as last profile */
theProfiles[idx] = destProfile;
}
/* make the transform list */
theTransforms = new ColorTransform[nTransforms];
/* initialize transform get loop */
if (theProfiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
/* if first profile is a printer
render as colorimetric */
renderState = ICC_Profile.icRelativeColorimetric;
} else {
renderState = ICC_Profile.icPerceptual;
/* render any other
class perceptually */
}
whichTrans = ColorTransform.In;
PCMM mdl = CMSManager.getModule();
/* get the transforms from each profile */
for (i1 = 0; i1 < nTransforms; i1++) {
if (i1 == nTransforms - 1) {
/* last profile? */
whichTrans = ColorTransform.Out;
/* get output transform */
} else {
/* check for abstract profile */
if ((whichTrans == ColorTransform.Simulation) && (theProfiles[i1].getProfileClass() == ICC_Profile.CLASS_ABSTRACT)) {
renderState = ICC_Profile.icPerceptual;
whichTrans = ColorTransform.In;
}
}
theTransforms[i1] = mdl.createTransform(theProfiles[i1], renderState, whichTrans);
/* get this profile's rendering intent to select transform
from next profile */
renderState = getRenderingIntent(theProfiles[i1]);
/* "middle" profiles use simulation transform */
whichTrans = ColorTransform.Simulation;
}
/* make the net transform */
thisTransform = mdl.createTransform(theTransforms);
/* update corresponding source and dest profiles */
thisSrcProfile = srcProfile;
thisDestProfile = destProfile;
}
Aggregations