/*
 * Copyright (c) 1997, 2008, 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 sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.PCMM;


/**
 *
 * The ICC_ColorSpace class is an implementation of the abstract
 * ColorSpace class.  This representation of
 * device independent and device dependent color spaces is based on the
 * International Color Consortium Specification ICC.1:2001-12, File Format for
 * Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
 * <p>
 * Typically, a Color or ColorModel would be associated with an ICC
 * Profile which is either an input, display, or output profile (see
 * the ICC specification).  There are other types of ICC Profiles, e.g.
 * abstract profiles, device link profiles, and named color profiles,
 * which do not contain information appropriate for representing the color
 * space of a color, image, or device (see ICC_Profile).
 * Attempting to create an ICC_ColorSpace object from an inappropriate ICC
 * Profile is an error.
 * <p>
 * ICC Profiles represent transformations from the color space of
 * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
 * Profiles of interest for tagging images or colors have a
 * PCS which is one of the device independent
 * spaces (one CIEXYZ space and two CIELab spaces) defined in the
 * ICC Profile Format Specification.  Most profiles of interest
 * either have invertible transformations or explicitly specify
 * transformations going both directions.  Should an ICC_ColorSpace
 * object be used in a way requiring a conversion from PCS to
 * the profile's native space and there is inadequate data to
 * correctly perform the conversion, the ICC_ColorSpace object will
 * produce output in the specified type of color space (e.g. TYPE_RGB,
 * TYPE_CMYK, etc.), but the specific color values of the output data
 * will be undefined.
 * <p>
 * The details of this class are not important for simple applets,
 * which draw in a default color space or manipulate and display
 * imported images with a known color space.  At most, such applets
 * would need to get one of the default color spaces via
 * ColorSpace.getInstance().
 * <p>
 * @see ColorSpace
 * @see ICC_Profile
 */



public class ICC_ColorSpace extends ColorSpace {

    static final long serialVersionUID = 3455889114070431483L;

    private ICC_Profile    thisProfile;
    private float[] minVal;
    private float[] maxVal;
    private float[] diffMinMax;
    private float[] invDiffMinMax;
    private boolean needScaleInit = true;

    // {to,from}{RGB,CIEXYZ} methods create and cache these when needed
    private transient ColorTransform this2srgb;
    private transient ColorTransform srgb2this;
    private transient ColorTransform this2xyz;
    private transient ColorTransform xyz2this;


    /**
    * Constructs a new ICC_ColorSpace from an ICC_Profile object.
    * @param profile the specified ICC_Profile object
    * @exception IllegalArgumentException if profile is inappropriate for
    *            representing a ColorSpace.
    */
    public ICC_ColorSpace (ICC_Profile profile) {
        super (profile.getColorSpaceType(), profile.getNumComponents());

        int profileClass = profile.getProfileClass();

        /* REMIND - is NAMEDCOLOR OK? */
        if ((profileClass != ICC_Profile.CLASS_INPUT) &&
            (profileClass != ICC_Profile.CLASS_DISPLAY) &&
            (profileClass != ICC_Profile.CLASS_OUTPUT) &&
            (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
            (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
            (profileClass != ICC_Profile.CLASS_ABSTRACT)) {
            throw new IllegalArgumentException("Invalid profile type");
        }

        thisProfile = profile;
        setMinMax();
    }

    /**
    * Returns the ICC_Profile for this ICC_ColorSpace.
    * @return the ICC_Profile for this ICC_ColorSpace.
    */
    public ICC_Profile getProfile() {
        return thisProfile;
    }

    /**
     * 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;
    }

    /**
     * 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;
    }


    /**
     * 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;
    }


    /**
     * 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 ICC Specification.  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.
     * 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 taken as
     * arguments 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>
     * <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 float[]    fromCIEXYZ(float[] colorvalue) {

        if (xyz2this == null) {
            ColorTransform[] transformList = new ColorTransform [2];
            ICC_ColorSpace xyzCS =
                (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
            PCMM mdl = CMSManager.getModule();
            transformList[0] = mdl.createTransform (
                xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
            try {
                transformList[1] = mdl.createTransform(
                    thisProfile, ICC_Profile.icRelativeColorimetric,
                    ColorTransform.Out);
            } catch (CMMException e) {
                transformList[1] = CMSManager.getModule().createTransform(
                thisProfile, ColorTransform.Any, ColorTransform.Out);
            }
            xyz2this = mdl.createTransform(transformList);
            if (needScaleInit) {
                setComponentScaling();
            }
        }

        short tmp[] = new short[3];
        float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
        float factor = 65535.0f / ALMOST_TWO;
        // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
        for (int i = 0; i < 3; i++) {
            tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
        }
        tmp = xyz2this.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;
    }

    /**
     * Returns the minimum normalized color component value for the
     * specified component.  For TYPE_XYZ spaces, this method returns
     * minimum values of 0.0 for all components.  For TYPE_Lab spaces,
     * this method returns 0.0 for L and -128.0 for a and b components.
     * This is consistent with the encoding of the XYZ and Lab Profile
     * Connection Spaces in the ICC specification.  For all other types, this
     * method returns 0.0 for all components.  When using an ICC_ColorSpace
     * with a profile that requires different minimum component values,
     * it is necessary to subclass this class and override this method.
     * @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 > this.getNumComponents() - 1)) {
            throw new IllegalArgumentException(
                "Component index out of range: + component");
        }
        return minVal[component];
    }

    /**
     * Returns the maximum normalized color component value for the
     * specified component.  For TYPE_XYZ spaces, this method returns
     * maximum values of 1.0 + (32767.0 / 32768.0) for all components.
     * For TYPE_Lab spaces,
     * this method returns 100.0 for L and 127.0 for a and b components.
     * This is consistent with the encoding of the XYZ and Lab Profile
     * Connection Spaces in the ICC specification.  For all other types, this
     * method returns 1.0 for all components.  When using an ICC_ColorSpace
     * with a profile that requires different maximum component values,
     * it is necessary to subclass this class and override this method.
     * @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 > this.getNumComponents() - 1)) {
            throw new IllegalArgumentException(
                "Component index out of range: + component");
        }
        return maxVal[component];
    }

    private void setMinMax() {
        int nc = this.getNumComponents();
        int type = this.getType();
        minVal = new float[nc];
        maxVal = new float[nc];
        if (type == ColorSpace.TYPE_Lab) {
            minVal[0] = 0.0f;    // L
            maxVal[0] = 100.0f;
            minVal[1] = -128.0f; // a
            maxVal[1] = 127.0f;
            minVal[2] = -128.0f; // b
            maxVal[2] = 127.0f;
        } else if (type == ColorSpace.TYPE_XYZ) {
            minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
            maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
        } else {
            for (int i = 0; i < nc; i++) {
                minVal[i] = 0.0f;
                maxVal[i] = 1.0f;
            }
        }
    }

    private void setComponentScaling() {
        int nc = this.getNumComponents();
        diffMinMax = new float[nc];
        invDiffMinMax = new float[nc];
        for (int i = 0; i < nc; i++) {
            minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
            maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
            diffMinMax[i] = maxVal[i] - minVal[i];
            invDiffMinMax[i] = 65535.0f / diffMinMax[i];
        }
        needScaleInit = false;
    }

}
