Search in sources :

Example 1 with ColorTransform

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;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) PCMM(sun.java2d.cmm.PCMM)

Example 2 with ColorTransform

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;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) PCMM(sun.java2d.cmm.PCMM)

Example 3 with ColorTransform

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;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) PCMM(sun.java2d.cmm.PCMM)

Example 4 with ColorTransform

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;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) PCMM(sun.java2d.cmm.PCMM) Point(java.awt.Point)

Example 5 with ColorTransform

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;
}
Also used : ColorTransform(sun.java2d.cmm.ColorTransform) PCMM(sun.java2d.cmm.PCMM) Point(java.awt.Point)

Aggregations

ColorTransform (sun.java2d.cmm.ColorTransform)14 PCMM (sun.java2d.cmm.PCMM)14 ICC_ColorSpace (java.awt.color.ICC_ColorSpace)8 WeakHashMap (java.util.WeakHashMap)8 Point (java.awt.Point)2