/*
 * 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.image;

import java.awt.Point;
import java.awt.Graphics2D;
import java.awt.color.*;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.PCMM;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Point2D;
import java.awt.RenderingHints;

/**
 * This class performs a pixel-by-pixel color conversion of the data in
 * the source image.  The resulting color values are scaled to the precision
 * of the destination image.  Color conversion can be specified
 * via an array of ColorSpace objects or an array of ICC_Profile objects.
 * <p>
 * If the source is a BufferedImage with premultiplied alpha, the
 * color components are divided by the alpha component before color conversion.
 * If the destination is a BufferedImage with premultiplied alpha, the
 * color components are multiplied by the alpha component after conversion.
 * Rasters are treated as having no alpha channel, i.e. all bands are
 * color bands.
 * <p>
 * If a RenderingHints object is specified in the constructor, the
 * color rendering hint and the dithering hint may be used to control
 * color conversion.
 * <p>
 * Note that Source and Destination may be the same object.
 * <p>
 * @see java.awt.RenderingHints#KEY_COLOR_RENDERING
 * @see java.awt.RenderingHints#KEY_DITHERING
 */
public class ColorConvertOp implements BufferedImageOp, RasterOp {
    ICC_Profile[]    profileList;
    ColorSpace[]     CSList;
    ColorTransform    thisTransform, thisRasterTransform;
    ICC_Profile      thisSrcProfile, thisDestProfile;
    RenderingHints   hints;
    boolean          gotProfiles;
    float[]          srcMinVals, srcMaxVals, dstMinVals, dstMaxVals;

    /* the class initializer */
    static {
        if (ProfileDeferralMgr.deferring) {
            ProfileDeferralMgr.activateProfiles();
        }
    }

    /**
     * Constructs a new ColorConvertOp which will convert
     * from a source color space to a destination color space.
     * The RenderingHints argument may be null.
     * This Op can be used only with BufferedImages, and will convert
     * directly from the ColorSpace of the source image to that of the
     * destination.  The destination argument of the filter method
     * cannot be specified as null.
     * @param hints the <code>RenderingHints</code> object used to control
     *        the color conversion, or <code>null</code>
     */
    public ColorConvertOp (RenderingHints hints)
    {
        profileList = new ICC_Profile [0];    /* 0 length list */
        this.hints  = hints;
    }

    /**
     * Constructs a new ColorConvertOp from a ColorSpace object.
     * The RenderingHints argument may be null.  This
     * Op can be used only with BufferedImages, and is primarily useful
     * when the {@link #filter(BufferedImage, BufferedImage) filter}
     * method is invoked with a destination argument of null.
     * In that case, the ColorSpace defines the destination color space
     * for the destination created by the filter method.  Otherwise, the
     * ColorSpace defines an intermediate space to which the source is
     * converted before being converted to the destination space.
     * @param cspace defines the destination <code>ColorSpace</code> or an
     *        intermediate <code>ColorSpace</code>
     * @param hints the <code>RenderingHints</code> object used to control
     *        the color conversion, or <code>null</code>
     * @throws NullPointerException if cspace is null
     */
    public ColorConvertOp (ColorSpace cspace, RenderingHints hints)
    {
        if (cspace == null) {
            throw new NullPointerException("ColorSpace cannot be null");
        }
        if (cspace instanceof ICC_ColorSpace) {
            profileList = new ICC_Profile [1];    /* 1 profile in the list */

            profileList [0] = ((ICC_ColorSpace) cspace).getProfile();
        }
        else {
            CSList = new ColorSpace[1]; /* non-ICC case: 1 ColorSpace in list */
            CSList[0] = cspace;
        }
        this.hints  = hints;
    }


    /**
     * Constructs a new ColorConvertOp from two ColorSpace objects.
     * The RenderingHints argument may be null.
     * This Op is primarily useful for calling the filter method on
     * Rasters, in which case the two ColorSpaces define the operation
     * to be performed on the Rasters.  In that case, the number of bands
     * in the source Raster must match the number of components in
     * srcCspace, and the number of bands in the destination Raster
     * must match the number of components in dstCspace.  For BufferedImages,
     * the two ColorSpaces define intermediate spaces through which the
     * source is converted before being converted to the destination space.
     * @param srcCspace the source <code>ColorSpace</code>
     * @param dstCspace the destination <code>ColorSpace</code>
     * @param hints the <code>RenderingHints</code> object used to control
     *        the color conversion, or <code>null</code>
     * @throws NullPointerException if either srcCspace or dstCspace is null
     */
    public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
                           RenderingHints hints)
    {
        if ((srcCspace == null) || (dstCspace == null)) {
            throw new NullPointerException("ColorSpaces cannot be null");
        }
        if ((srcCspace instanceof ICC_ColorSpace) &&
            (dstCspace instanceof ICC_ColorSpace)) {
            profileList = new ICC_Profile [2];    /* 2 profiles in the list */

            profileList [0] = ((ICC_ColorSpace) srcCspace).getProfile();
            profileList [1] = ((ICC_ColorSpace) dstCspace).getProfile();

            getMinMaxValsFromColorSpaces(srcCspace, dstCspace);
        } else {
            /* non-ICC case: 2 ColorSpaces in list */
            CSList = new ColorSpace[2];
            CSList[0] = srcCspace;
            CSList[1] = dstCspace;
        }
        this.hints  = hints;
    }


     /**
     * Constructs a new ColorConvertOp from an array of ICC_Profiles.
     * The RenderingHints argument may be null.
     * The sequence of profiles may include profiles that represent color
     * spaces, profiles that represent effects, etc.  If the whole sequence
     * does not represent a well-defined color conversion, an exception is
     * thrown.
     * <p>For BufferedImages, if the ColorSpace
     * of the source BufferedImage does not match the requirements of the
     * first profile in the array,
     * the first conversion is to an appropriate ColorSpace.
     * If the requirements of the last profile in the array are not met
     * by the ColorSpace of the destination BufferedImage,
     * the last conversion is to the destination's ColorSpace.
     * <p>For Rasters, the number of bands in the source Raster must match
     * the requirements of the first profile in the array, and the
     * number of bands in the destination Raster must match the requirements
     * of the last profile in the array.  The array must have at least two
     * elements or calling the filter method for Rasters will throw an
     * IllegalArgumentException.
     * @param profiles the array of <code>ICC_Profile</code> objects
     * @param hints the <code>RenderingHints</code> object used to control
     *        the color conversion, or <code>null</code>
     * @exception IllegalArgumentException when the profile sequence does not
     *             specify a well-defined color conversion
     * @exception NullPointerException if profiles is null
     */
    public ColorConvertOp (ICC_Profile[] profiles, RenderingHints hints)
    {
        if (profiles == null) {
            throw new NullPointerException("Profiles cannot be null");
        }
        gotProfiles = true;
        profileList = new ICC_Profile[profiles.length];
        for (int i1 = 0; i1 < profiles.length; i1++) {
            profileList[i1] = profiles[i1];
        }
        this.hints  = hints;
    }


    /**
     * Returns the array of ICC_Profiles used to construct this ColorConvertOp.
     * Returns null if the ColorConvertOp was not constructed from such an
     * array.
     * @return the array of <code>ICC_Profile</code> objects of this
     *         <code>ColorConvertOp</code>, or <code>null</code> if this
     *         <code>ColorConvertOp</code> was not constructed with an
     *         array of <code>ICC_Profile</code> objects.
     */
    public final ICC_Profile[] getICC_Profiles() {
        if (gotProfiles) {
            ICC_Profile[] profiles = new ICC_Profile[profileList.length];
            for (int i1 = 0; i1 < profileList.length; i1++) {
                profiles[i1] = profileList[i1];
            }
            return profiles;
        }
        return null;
    }

    /**
     * ColorConverts the source BufferedImage.
     * If the destination image is null,
     * a BufferedImage will be created with an appropriate ColorModel.
     * @param src the source <code>BufferedImage</code> to be converted
     * @param dest the destination <code>BufferedImage</code>,
     *        or <code>null</code>
     * @return <code>dest</code> color converted from <code>src</code>
     *         or a new, converted <code>BufferedImage</code>
     *         if <code>dest</code> is <code>null</code>
     * @exception IllegalArgumentException if dest is null and this op was
     *             constructed using the constructor which takes only a
     *             RenderingHints argument, since the operation is ill defined.
     */
    public final BufferedImage filter(BufferedImage src, BufferedImage dest) {
        ColorSpace srcColorSpace, destColorSpace;
        BufferedImage savdest = null;

        if (src.getColorModel() instanceof IndexColorModel) {
            IndexColorModel icm = (IndexColorModel) src.getColorModel();
            src = icm.convertToIntDiscrete(src.getRaster(), true);
        }
        srcColorSpace = src.getColorModel().getColorSpace();
        if (dest != null) {
            if (dest.getColorModel() instanceof IndexColorModel) {
                savdest = dest;
                dest = null;
                destColorSpace = null;
            } else {
                destColorSpace = dest.getColorModel().getColorSpace();
            }
        } else {
            destColorSpace = null;
        }

        if ((CSList != null) ||
            (!(srcColorSpace instanceof ICC_ColorSpace)) ||
            ((dest != null) &&
             (!(destColorSpace instanceof ICC_ColorSpace)))) {
            /* non-ICC case */
            dest = nonICCBIFilter(src, srcColorSpace, dest, destColorSpace);
        } else {
            dest = ICCBIFilter(src, srcColorSpace, dest, destColorSpace);
        }

        if (savdest != null) {
            Graphics2D big = savdest.createGraphics();
            try {
                big.drawImage(dest, 0, 0, null);
            } finally {
                big.dispose();
            }
            return savdest;
        } else {
            return dest;
        }
    }

    private final BufferedImage ICCBIFilter(BufferedImage src,
                                            ColorSpace srcColorSpace,
                                            BufferedImage dest,
                                            ColorSpace destColorSpace) {
    int              nProfiles = profileList.length;
    ICC_Profile      srcProfile = null, destProfile = null;

        srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();

        if (dest == null) {        /* last profile in the list defines
                                      the output color space */
            if (nProfiles == 0) {
                throw new IllegalArgumentException(
                    "Destination ColorSpace is undefined");
            }
            destProfile = profileList [nProfiles - 1];
            dest = createCompatibleDestImage(src, null);
        }
        else {
            if (src.getHeight() != dest.getHeight() ||
                src.getWidth() != dest.getWidth()) {
                throw new IllegalArgumentException(
                    "Width or height of BufferedImages do not match");
            }
            destProfile = ((ICC_ColorSpace) destColorSpace).getProfile();
        }

        /* Checking if all profiles in the transform sequence are the same.
         * If so, performing just copying the data.
         */
        if (srcProfile == destProfile) {
            boolean noTrans = true;
            for (int i = 0; i < nProfiles; i++) {
                if (srcProfile != profileList[i]) {
                    noTrans = false;
                    break;
                }
            }
            if (noTrans) {
                Graphics2D g = dest.createGraphics();
                try {
                    g.drawImage(src, 0, 0, null);
                } finally {
                    g.dispose();
                }

                return dest;
            }
        }

        /* make a new transform if needed */
        if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
            (thisDestProfile != destProfile) ) {
            updateBITransform(srcProfile, destProfile);
        }

        /* color convert the image */
        thisTransform.colorConvert(src, dest);

        return dest;
    }

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

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

    /**
     * Returns the bounding box of the destination, given this source.
     * Note that this will be the same as the the bounding box of the
     * source.
     * @param src the source <code>BufferedImage</code>
     * @return a <code>Rectangle2D</code> that is the bounding box
     *         of the destination, given the specified <code>src</code>
     */
    public final Rectangle2D getBounds2D (BufferedImage src) {
        return getBounds2D(src.getRaster());
    }

    /**
     * Returns the bounding box of the destination, given this source.
     * Note that this will be the same as the the bounding box of the
     * source.
     * @param src the source <code>Raster</code>
     * @return a <code>Rectangle2D</code> that is the bounding box
     *         of the destination, given the specified <code>src</code>
     */
    public final Rectangle2D getBounds2D (Raster src) {
        /*        return new Rectangle (src.getXOffset(),
                              src.getYOffset(),
                              src.getWidth(), src.getHeight()); */
        return src.getBounds();
    }

    /**
     * Creates a zeroed destination image with the correct size and number of
     * bands, given this source.
     * @param src       Source image for the filter operation.
     * @param destCM    ColorModel of the destination.  If null, an
     *                  appropriate ColorModel will be used.
     * @return a <code>BufferedImage</code> with the correct size and
     * number of bands from the specified <code>src</code>.
     * @throws IllegalArgumentException if <code>destCM</code> is
     *         <code>null</code> and this <code>ColorConvertOp</code> was
     *         created without any <code>ICC_Profile</code> or
     *         <code>ColorSpace</code> defined for the destination
     */
    public BufferedImage createCompatibleDestImage (BufferedImage src,
                                                    ColorModel destCM) {
        ColorSpace cs = null;;
        if (destCM == null) {
            if (CSList == null) {
                /* ICC case */
                int nProfiles = profileList.length;
                if (nProfiles == 0) {
                    throw new IllegalArgumentException(
                        "Destination ColorSpace is undefined");
                }
                ICC_Profile destProfile = profileList[nProfiles - 1];
                cs = new ICC_ColorSpace(destProfile);
            } else {
                /* non-ICC case */
                int nSpaces = CSList.length;
                cs = CSList[nSpaces - 1];
            }
        }
        return createCompatibleDestImage(src, destCM, cs);
    }

    private BufferedImage createCompatibleDestImage(BufferedImage src,
                                                    ColorModel destCM,
                                                    ColorSpace destCS) {
        BufferedImage image;
        if (destCM == null) {
            ColorModel srcCM = src.getColorModel();
            int nbands = destCS.getNumComponents();
            boolean hasAlpha = srcCM.hasAlpha();
            if (hasAlpha) {
               nbands += 1;
            }
            int[] nbits = new int[nbands];
            for (int i = 0; i < nbands; i++) {
                nbits[i] = 8;
            }
            destCM = new ComponentColorModel(destCS, nbits, hasAlpha,
                                             srcCM.isAlphaPremultiplied(),
                                             srcCM.getTransparency(),
                                             DataBuffer.TYPE_BYTE);
        }
        int w = src.getWidth();
        int h = src.getHeight();
        image = new BufferedImage(destCM,
                                  destCM.createCompatibleWritableRaster(w, h),
                                  destCM.isAlphaPremultiplied(), null);
        return image;
    }


    /**
     * Creates a zeroed destination Raster with the correct size and number of
     * bands, given this source.
     * @param src the specified <code>Raster</code>
     * @return a <code>WritableRaster</code> with the correct size and number
     *         of bands from the specified <code>src</code>
     * @throws IllegalArgumentException if this <code>ColorConvertOp</code>
     *         was created without sufficient information to define the
     *         <code>dst</code> and <code>src</code> color spaces
     */
    public WritableRaster createCompatibleDestRaster (Raster src) {
        int ncomponents;

        if (CSList != null) {
            /* non-ICC case */
            if (CSList.length != 2) {
                throw new IllegalArgumentException(
                    "Destination ColorSpace is undefined");
            }
            ncomponents = CSList[1].getNumComponents();
        } else {
            /* ICC case */
            int nProfiles = profileList.length;
            if (nProfiles < 2) {
                throw new IllegalArgumentException(
                    "Destination ColorSpace is undefined");
            }
            ncomponents = profileList[nProfiles-1].getNumComponents();
        }

        WritableRaster dest =
            Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                                  src.getWidth(),
                                  src.getHeight(),
                                  ncomponents,
                                  new Point(src.getMinX(), src.getMinY()));
        return dest;
    }

    /**
     * Returns the location of the destination point given a
     * point in the source.  If <code>dstPt</code> is non-null,
     * it will be used to hold the return value.  Note that
     * for this class, the destination point will be the same
     * as the source point.
     * @param srcPt the specified source <code>Point2D</code>
     * @param dstPt the destination <code>Point2D</code>
     * @return <code>dstPt</code> after setting its location to be
     *         the same as <code>srcPt</code>
     */
    public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
        if (dstPt == null) {
            dstPt = new Point2D.Float();
        }
        dstPt.setLocation(srcPt.getX(), srcPt.getY());

        return dstPt;
    }


    /**
     * Returns the RenderingIntent from the specified ICC Profile.
     */
    private int getRenderingIntent (ICC_Profile profile) {
        byte[] header = profile.getData(ICC_Profile.icSigHead);
        int index = ICC_Profile.icHdrRenderingIntent;
        return (((header[index]   & 0xff) << 24) |
                ((header[index+1] & 0xff) << 16) |
                ((header[index+2] & 0xff) <<  8) |
                 (header[index+3] & 0xff));
    }

    /**
     * Returns the rendering hints used by this op.
     * @return the <code>RenderingHints</code> object of this
     *         <code>ColorConvertOp</code>
     */
    public final RenderingHints getRenderingHints() {
        return hints;
    }

    private final BufferedImage nonICCBIFilter(BufferedImage src,
                                               ColorSpace srcColorSpace,
                                               BufferedImage dst,
                                               ColorSpace dstColorSpace) {

        int w = src.getWidth();
        int h = src.getHeight();
        ICC_ColorSpace ciespace =
            (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
        if (dst == null) {
            dst = createCompatibleDestImage(src, null);
            dstColorSpace = dst.getColorModel().getColorSpace();
        } else {
            if ((h != dst.getHeight()) || (w != dst.getWidth())) {
                throw new IllegalArgumentException(
                    "Width or height of BufferedImages do not match");
            }
        }
        Raster srcRas = src.getRaster();
        WritableRaster dstRas = dst.getRaster();
        ColorModel srcCM = src.getColorModel();
        ColorModel dstCM = dst.getColorModel();
        int srcNumComp = srcCM.getNumColorComponents();
        int dstNumComp = dstCM.getNumColorComponents();
        boolean dstHasAlpha = dstCM.hasAlpha();
        boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
        ColorSpace[] list;
        if ((CSList == null) && (profileList.length != 0)) {
            /* possible non-ICC src, some profiles, possible non-ICC dst */
            boolean nonICCSrc, nonICCDst;
            ICC_Profile srcProfile, dstProfile;
            if (!(srcColorSpace instanceof ICC_ColorSpace)) {
                nonICCSrc = true;
                srcProfile = ciespace.getProfile();
            } else {
                nonICCSrc = false;
                srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();
            }
            if (!(dstColorSpace instanceof ICC_ColorSpace)) {
                nonICCDst = true;
                dstProfile = ciespace.getProfile();
            } else {
                nonICCDst = false;
                dstProfile = ((ICC_ColorSpace) dstColorSpace).getProfile();
            }
            /* make a new transform if needed */
            if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
                (thisDestProfile != dstProfile) ) {
                updateBITransform(srcProfile, dstProfile);
            }
            // process per scanline
            float maxNum = 65535.0f; // use 16-bit precision in CMM
            ColorSpace cs;
            int iccSrcNumComp;
            if (nonICCSrc) {
                cs = ciespace;
                iccSrcNumComp = 3;
            } else {
                cs = srcColorSpace;
                iccSrcNumComp = srcNumComp;
            }
            float[] srcMinVal = new float[iccSrcNumComp];
            float[] srcInvDiffMinMax = new float[iccSrcNumComp];
            for (int i = 0; i < srcNumComp; i++) {
                srcMinVal[i] = cs.getMinValue(i);
                srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
            }
            int iccDstNumComp;
            if (nonICCDst) {
                cs = ciespace;
                iccDstNumComp = 3;
            } else {
                cs = dstColorSpace;
                iccDstNumComp = dstNumComp;
            }
            float[] dstMinVal = new float[iccDstNumComp];
            float[] dstDiffMinMax = new float[iccDstNumComp];
            for (int i = 0; i < dstNumComp; i++) {
                dstMinVal[i] = cs.getMinValue(i);
                dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
            }
            float[] dstColor;
            if (dstHasAlpha) {
                int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3;
                dstColor = new float[size];
            } else {
                int size = (dstNumComp  > 3) ? dstNumComp : 3;
                dstColor = new float[size];
            }
            short[] srcLine = new short[w * iccSrcNumComp];
            short[] dstLine = new short[w * iccDstNumComp];
            Object pixel;
            float[] color;
            float[] alpha = null;
            if (needSrcAlpha) {
                alpha = new float[w];
            }
            int idx;
            // process each scanline
            for (int y = 0; y < h; y++) {
                // convert src scanline
                pixel = null;
                color = null;
                idx = 0;
                for (int x = 0; x < w; x++) {
                    pixel = srcRas.getDataElements(x, y, pixel);
                    color = srcCM.getNormalizedComponents(pixel, color, 0);
                    if (needSrcAlpha) {
                        alpha[x] = color[srcNumComp];
                    }
                    if (nonICCSrc) {
                        color = srcColorSpace.toCIEXYZ(color);
                    }
                    for (int i = 0; i < iccSrcNumComp; i++) {
                        srcLine[idx++] = (short)
                            ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
                             0.5f);
                    }
                }
                // color convert srcLine to dstLine
                thisTransform.colorConvert(srcLine, dstLine);
                // convert dst scanline
                pixel = null;
                idx = 0;
                for (int x = 0; x < w; x++) {
                    for (int i = 0; i < iccDstNumComp; i++) {
                        dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
                                      dstDiffMinMax[i] + dstMinVal[i];
                    }
                    if (nonICCDst) {
                        color = srcColorSpace.fromCIEXYZ(dstColor);
                        for (int i = 0; i < dstNumComp; i++) {
                            dstColor[i] = color[i];
                        }
                    }
                    if (needSrcAlpha) {
                        dstColor[dstNumComp] = alpha[x];
                    } else if (dstHasAlpha) {
                        dstColor[dstNumComp] = 1.0f;
                    }
                    pixel = dstCM.getDataElements(dstColor, 0, pixel);
                    dstRas.setDataElements(x, y, pixel);
                }
            }
        } else {
            /* possible non-ICC src, possible CSList, possible non-ICC dst */
            // process per pixel
            int numCS;
            if (CSList == null) {
                numCS = 0;
            } else {
                numCS = CSList.length;
            }
            float[] dstColor;
            if (dstHasAlpha) {
                dstColor = new float[dstNumComp + 1];
            } else {
                dstColor = new float[dstNumComp];
            }
            Object spixel = null;
            Object dpixel = null;
            float[] color = null;
            float[] tmpColor;
            // process each pixel
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    spixel = srcRas.getDataElements(x, y, spixel);
                    color = srcCM.getNormalizedComponents(spixel, color, 0);
                    tmpColor = srcColorSpace.toCIEXYZ(color);
                    for (int i = 0; i < numCS; i++) {
                        tmpColor = CSList[i].fromCIEXYZ(tmpColor);
                        tmpColor = CSList[i].toCIEXYZ(tmpColor);
                    }
                    tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
                    for (int i = 0; i < dstNumComp; i++) {
                        dstColor[i] = tmpColor[i];
                    }
                    if (needSrcAlpha) {
                        dstColor[dstNumComp] = color[srcNumComp];
                    } else if (dstHasAlpha) {
                        dstColor[dstNumComp] = 1.0f;
                    }
                    dpixel = dstCM.getDataElements(dstColor, 0, dpixel);
                    dstRas.setDataElements(x, y, dpixel);

                }
            }
        }

        return dst;
    }

    /* color convert a Raster - handles byte, ushort, int, short, float,
       or double transferTypes */
    private final WritableRaster nonICCRasterFilter(Raster src,
                                                    WritableRaster dst)  {

        if (CSList.length != 2) {
            throw new IllegalArgumentException(
                "Destination ColorSpace is undefined");
        }
        if (src.getNumBands() != CSList[0].getNumComponents()) {
            throw new IllegalArgumentException(
                "Numbers of source Raster bands and source color space " +
                "components do not match");
        }
        if (dst == null) {
            dst = createCompatibleDestRaster(src);
        } else {
            if (src.getHeight() != dst.getHeight() ||
                src.getWidth() != dst.getWidth()) {
                throw new IllegalArgumentException(
                    "Width or height of Rasters do not match");
            }
            if (dst.getNumBands() != CSList[1].getNumComponents()) {
                throw new IllegalArgumentException(
                    "Numbers of destination Raster bands and destination " +
                    "color space components do not match");
            }
        }

        if (srcMinVals == null) {
            getMinMaxValsFromColorSpaces(CSList[0], CSList[1]);
        }

        SampleModel srcSM = src.getSampleModel();
        SampleModel dstSM = dst.getSampleModel();
        boolean srcIsFloat, dstIsFloat;
        int srcTransferType = src.getTransferType();
        int dstTransferType = dst.getTransferType();
        if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
            (srcTransferType == DataBuffer.TYPE_DOUBLE)) {
            srcIsFloat = true;
        } else {
            srcIsFloat = false;
        }
        if ((dstTransferType == DataBuffer.TYPE_FLOAT) ||
            (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
            dstIsFloat = true;
        } else {
            dstIsFloat = false;
        }
        int w = src.getWidth();
        int h = src.getHeight();
        int srcNumBands = src.getNumBands();
        int dstNumBands = dst.getNumBands();
        float[] srcScaleFactor = null;
        float[] dstScaleFactor = null;
        if (!srcIsFloat) {
            srcScaleFactor = new float[srcNumBands];
            for (int i = 0; i < srcNumBands; i++) {
                if (srcTransferType == DataBuffer.TYPE_SHORT) {
                    srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
                                        32767.0f;
                } else {
                    srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
                        ((float) ((1 << srcSM.getSampleSize(i)) - 1));
                }
            }
        }
        if (!dstIsFloat) {
            dstScaleFactor = new float[dstNumBands];
            for (int i = 0; i < dstNumBands; i++) {
                if (dstTransferType == DataBuffer.TYPE_SHORT) {
                    dstScaleFactor[i] = 32767.0f /
                                        (dstMaxVals[i] - dstMinVals[i]);
                } else {
                    dstScaleFactor[i] =
                        ((float) ((1 << dstSM.getSampleSize(i)) - 1)) /
                        (dstMaxVals[i] - dstMinVals[i]);
                }
            }
        }
        int ys = src.getMinY();
        int yd = dst.getMinY();
        int xs, xd;
        float sample;
        float[] color = new float[srcNumBands];
        float[] tmpColor;
        ColorSpace srcColorSpace = CSList[0];
        ColorSpace dstColorSpace = CSList[1];
        // process each pixel
        for (int y = 0; y < h; y++, ys++, yd++) {
            // get src scanline
            xs = src.getMinX();
            xd = dst.getMinX();
            for (int x = 0; x < w; x++, xs++, xd++) {
                for (int i = 0; i < srcNumBands; i++) {
                    sample = src.getSampleFloat(xs, ys, i);
                    if (!srcIsFloat) {
                        sample = sample * srcScaleFactor[i] + srcMinVals[i];
                    }
                    color[i] = sample;
                }
                tmpColor = srcColorSpace.toCIEXYZ(color);
                tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
                for (int i = 0; i < dstNumBands; i++) {
                    sample = tmpColor[i];
                    if (!dstIsFloat) {
                        sample = (sample - dstMinVals[i]) * dstScaleFactor[i];
                    }
                    dst.setSample(xd, yd, i, sample);
                }
            }
        }
        return dst;
    }

    private void getMinMaxValsFromProfiles(ICC_Profile srcProfile,
                                           ICC_Profile dstProfile) {
        int type = srcProfile.getColorSpaceType();
        int nc = srcProfile.getNumComponents();
        srcMinVals = new float[nc];
        srcMaxVals = new float[nc];
        setMinMax(type, nc, srcMinVals, srcMaxVals);
        type = dstProfile.getColorSpaceType();
        nc = dstProfile.getNumComponents();
        dstMinVals = new float[nc];
        dstMaxVals = new float[nc];
        setMinMax(type, nc, dstMinVals, dstMaxVals);
    }

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

    private void getMinMaxValsFromColorSpaces(ColorSpace srcCspace,
                                              ColorSpace dstCspace) {
        int nc = srcCspace.getNumComponents();
        srcMinVals = new float[nc];
        srcMaxVals = new float[nc];
        for (int i = 0; i < nc; i++) {
            srcMinVals[i] = srcCspace.getMinValue(i);
            srcMaxVals[i] = srcCspace.getMaxValue(i);
        }
        nc = dstCspace.getNumComponents();
        dstMinVals = new float[nc];
        dstMaxVals = new float[nc];
        for (int i = 0; i < nc; i++) {
            dstMinVals[i] = dstCspace.getMinValue(i);
            dstMaxVals[i] = dstCspace.getMaxValue(i);
        }
    }

}
