19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  this work for additional information regarding copyright ownership.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  the License.  You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @author Oleg V. Khaschansky
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @version $Revision$
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage java.awt.image;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.Graphics2D;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.Point;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.RenderingHints;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.color.ColorSpace;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.color.ICC_ColorSpace;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.color.ICC_Profile;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.geom.Point2D;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.geom.Rectangle2D;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.gl.color.ColorConverter;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.gl.color.ColorScaler;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.gl.color.ICC_Transform;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.awt.internal.nls.Messages;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ColorConvertOp class converts the pixels of the data in the source image
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the specified ColorSpace objects or an array of ICC_Profile objects. The
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * result pixels are scaled to the precision of the destination image.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @since Android 1.0
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorConvertOp implements BufferedImageOp, RasterOp {
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Unused but required by interfaces
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The rendering hints.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    RenderingHints renderingHints;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Sequence consisting of ColorSpace and ICC_Profile elements
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The conversion sequence.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // null
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Not null if ColorConvertOp is constructed from the array of ICC profiles
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The mid profiles.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ICC_Profile midProfiles[];
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The cc.
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ColorConverter cc = new ColorConverter();
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The t creator.
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The is icc.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean isICC = true;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Cached ICC_Transform
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The Class ICC_TransfomCreator.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ICC_TransfomCreator {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The transform.
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private ICC_Transform transform;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The max components.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private int maxComponents;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * For the full ICC case.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param src
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *            the src.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dst
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *            the dst.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param convSeq
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *            the conv seq.
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return the transform.
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (transform != null && src == transform.getSrc() && dst == transform.getDst()) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return transform;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int length = convSeq.length;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int srcFlg = 0, dstFlg = 0;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (length == 0 || src != convSeq[0]) {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (src != null) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    srcFlg = 1; // need src profile
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (length == 0 || dst != convSeq[length - 1]) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dst != null) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    dstFlg = 1; // need dst profile
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Profile profiles[];
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int nProfiles = length + srcFlg + dstFlg;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (nProfiles == length) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                profiles = convSeq;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                profiles = new ICC_Profile[nProfiles];
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int pos = 0;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (srcFlg != 0) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles[pos++] = src;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < length; i++) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles[pos++] = convSeq[i];
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dstFlg != 0) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles[pos++] = dst;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return transform = new ICC_Transform(profiles);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Used only when there are non-ICC color spaces. Returns sequence of
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * non-ICC color spaces and ICC transforms made from src, dst and
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * conversionSequence.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param src
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *            the src.
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param dst
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *            the dst.
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return the sequence.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Object[] getSequence(Object src, Object dst) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ArrayList<Object> profiles = new ArrayList<Object>(10);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ArrayList<Object> sequence = new ArrayList<Object>(10);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // We need this profile anyway
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object conversionFirst = null, conversionLast = null;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int conversionLength = conversionSequence.length;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (conversionLength > 0) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conversionFirst = conversionSequence[0];
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                conversionLast = conversionSequence[conversionLength - 1];
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean iccSequenceStarted = false;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (src != conversionFirst && src != null) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (src instanceof ICC_Profile) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(src);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iccSequenceStarted = true;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(xyzProfile);
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sequence.add(src); // Add non-ICC color space to the
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // sequence
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                profiles.add(xyzProfile);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < conversionLength; i++) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (conversionSequence[i] instanceof ICC_Profile) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(conversionSequence[i]);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iccSequenceStarted = true;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (iccSequenceStarted) {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(xyzProfile);
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Eliminate same profiles if there are any
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // (e.g. xyzProfile may occur several times)
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Object prev = profiles.get(0);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int k = 1; k < profiles.size(); k++) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (prev == profiles.get(k)) {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            k--;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            profiles.remove(k);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        prev = profiles.get(k);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // If only one profile left we skip the transform -
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // it can be only CIEXYZ
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (profiles.size() > 1) {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Add non-ICC color space to the sequence
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        sequence.add(conversionSequence[i]);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.clear();
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(xyzProfile);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iccSequenceStarted = false; // Sequence of ICC profiles is
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // processed
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else { // Add non-ICC color space to the sequence
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sequence.add(conversionSequence[i]);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (dst != conversionLast && dst != null) { // Add last profile if
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // needed
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dst instanceof ICC_Profile) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(dst);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iccSequenceStarted = true;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (iccSequenceStarted) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    profiles.add(xyzProfile);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sequence.add(dst); // Add last non-ICC color space to the
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // sequence
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (iccSequenceStarted) { // Make last transform if needed
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (dst != null && !(dst instanceof ICC_Profile)) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sequence.add(dst); // Add last non-ICC color space to the
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // sequence
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Calculate max number of components
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // This number will be used for memory allocation
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            maxComponents = 0;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object o;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0, size = sequence.size(); i < size; i++) {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                o = sequence.get(i);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (o instanceof ICC_Transform) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ICC_Transform t = (ICC_Transform)o;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    maxComponents = (maxComponents > t.getNumInputChannels() + 1) ? maxComponents
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            : t.getNumInputChannels() + 1;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    maxComponents = (maxComponents > t.getNumOutputChannels() + 1) ? maxComponents
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            : t.getNumOutputChannels() + 1;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ColorSpace cs = (ColorSpace)o;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    maxComponents = (maxComponents > cs.getNumComponents() + 1) ? maxComponents
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            : cs.getNumComponents() + 1;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return sequence.toArray();
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates a new ColorConvertOp object using two specified ColorSpace
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * objects.
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param srcCS
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the source ColorSpace.
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dstCS
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the destination ColorSpace.
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hints
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the RenderingHints object used for the color conversion, or
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            null.
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (srcCS == null || dstCS == null) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        renderingHints = hints;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean srcICC = srcCS instanceof ICC_ColorSpace;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean dstICC = dstCS instanceof ICC_ColorSpace;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (srcICC && dstICC) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence = new ICC_Profile[2];
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence = new Object[2];
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isICC = false;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (srcICC) {
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[0] = ((ICC_ColorSpace)srcCS).getProfile();
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[0] = srcCS;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dstICC) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[1] = ((ICC_ColorSpace)dstCS).getProfile();
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[1] = dstCS;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates a new ColorConvertOp object from the specified ICC_Profile
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * objects.
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param profiles
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the array of ICC_Profile objects.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hints
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the RenderingHints object used for the color conversion, or
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            null.
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (profiles == null) {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        renderingHints = hints;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This array is not used in the program logic, so don't need to copy it
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Store it only to return back
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        midProfiles = profiles;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        conversionSequence = new ICC_Profile[midProfiles.length];
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Add profiles to the conversion sequence
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0, length = midProfiles.length; i < length; i++) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[i] = midProfiles[i];
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates a new ColorConvertOp object using the specified ColorSpace
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * object.
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cs
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the destination ColorSpace or an intermediate ColorSpace.
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hints
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the RenderingHints object used for the color conversion, or
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            null.
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cs == null) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        renderingHints = hints;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cs instanceof ICC_ColorSpace) {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence = new ICC_Profile[1];
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[0] = ((ICC_ColorSpace)cs).getProfile();
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence = new Object[1];
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conversionSequence[0] = cs;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isICC = false;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates a new ColorConvertOp object which converts from a source
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * color space to a destination color space.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hints
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the RenderingHints object used for the color conversion, or
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            null.
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ColorConvertOp(RenderingHints hints) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        renderingHints = hints;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final WritableRaster filter(Raster src, WritableRaster dst) {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conversionSequence.length < 2) {
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nSrcColorComps, nDstColorComps;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object first = conversionSequence[0];
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object last = conversionSequence[conversionSequence.length - 1];
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the number of input/output color components
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isICC) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            srcPf = (ICC_Profile)first;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dstPf = (ICC_Profile)last;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nSrcColorComps = srcPf.getNumComponents();
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nDstColorComps = dstPf.getNumComponents();
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (first instanceof ICC_Profile) {
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                srcPf = (ICC_Profile)first;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                nSrcColorComps = srcPf.getNumComponents();
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                nSrcColorComps = ((ColorSpace)first).getNumComponents();
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (last instanceof ICC_Profile) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dstPf = (ICC_Profile)last;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                nDstColorComps = dstPf.getNumComponents();
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                nDstColorComps = ((ColorSpace)last).getNumComponents();
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Check that source and destination rasters are compatible with
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // transforms and with each other
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (src.getNumBands() != nSrcColorComps) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // awt.25E=Incorrect number of source raster bands. Should be equal
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to the number of color components of source colorspace.
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst != null) { // Check destination raster
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (dst.getNumBands() != nDstColorComps) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // awt.25F=Incorrect number of destination raster bands. Should
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // be equal to the number of color components of destination
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // colorspace.
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dst = createCompatibleDestRaster(src);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isICC) {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Create transform
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Transform t = tCreator
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cc.translateColor(t, src, dst);
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object[] sequence = tCreator.getSequence(null, null);
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Get data from the source raster
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ColorScaler scaler = new ColorScaler();
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            scaler.loadScalingData(src, null);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float tmpData[][] = scaler.scaleNormalize(src);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Get source and destination color spaces
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ColorSpace srcCS = (srcPf == null) ? (ColorSpace)first : new ICC_ColorSpace(srcPf);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ColorSpace dstCS = (dstPf == null) ? (ColorSpace)last : new ICC_ColorSpace(dstPf);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            applySequence(sequence, tmpData, srcCS, dstCS);
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            scaler.loadScalingData(dst, null);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            scaler.unscaleNormalized(dst, tmpData);
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return dst;
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If destination color model is passed only one line needed
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (destCM != null) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new BufferedImage(destCM, destCM.createCompatibleWritableRaster(src.getWidth(),
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    src.getHeight()), destCM.isAlphaPremultiplied(), null);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nSpaces = conversionSequence.length;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nSpaces < 1) {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get destination color space
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object destination = conversionSequence[nSpaces - 1];
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorSpace dstCS = (destination instanceof ColorSpace) ? (ColorSpace)destination
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                : new ICC_ColorSpace((ICC_Profile)destination);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorModel srcCM = src.getColorModel();
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorModel dstCM = new ComponentColorModel(dstCS, srcCM.hasAlpha(), srcCM
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .isAlphaPremultiplied(), srcCM.getTransparency(), srcCM.getTransferType());
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new BufferedImage(dstCM, destCM.createCompatibleWritableRaster(src.getWidth(), src
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .getHeight()), destCM.isAlphaPremultiplied(), null);
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst == null && conversionSequence.length < 1) {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorModel srcCM = src.getColorModel();
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // First handle index color model
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (srcCM instanceof IndexColorModel) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), false);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorSpace srcCS = srcCM.getColorSpace();
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        BufferedImage res;
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isDstIndex = false;
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst != null) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (src.getWidth() != dst.getWidth() || src.getHeight() != dst.getHeight()) {
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (dst.getColorModel() instanceof IndexColorModel) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                isDstIndex = true;
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res = createCompatibleDestImage(src, null);
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res = dst;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = createCompatibleDestImage(src, null);
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorModel dstCM = res.getColorModel();
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorSpace dstCS = dstCM.getColorSpace();
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ICC_Profile srcPf = null, dstPf = null;
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (srcCS instanceof ICC_ColorSpace) {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dstCS instanceof ICC_ColorSpace) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFullICC = isICC && srcPf != null && dstPf != null;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isFullICC) {
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Transform t = tCreator
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .getTransform(srcPf, dstPf, (ICC_Profile[])conversionSequence);
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cc.translateColor(t, src, res);
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else { // Perform non-ICC transform
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object sequence[] = tCreator.getSequence(srcPf == null ? (Object)srcCS : srcPf,
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    dstPf == null ? (Object)dstCS : dstPf);
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int srcW = src.getWidth();
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int srcH = src.getHeight();
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int numPixels = srcW * srcH;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Load all pixel data into array tmpData
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float tmpData[][] = new float[numPixels][tCreator.maxComponents];
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int row = 0, dataPos = 0; row < srcW; row++) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int col = 0; col < srcH; col++) {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    tmpData[dataPos] = srcCM.getNormalizedComponents(src.getRaster()
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .getDataElements(row, col, null), tmpData[dataPos], 0);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    dataPos++;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Copy alpha channel if needed
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float alpha[] = null;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int alphaIdx = srcCM.numComponents - 1;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                alpha = new float[numPixels];
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int i = 0; i < numPixels; i++) {
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    alpha[i] = tmpData[i][alphaIdx];
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Translate colors
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            applySequence(sequence, tmpData, srcCS, dstCS);
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Copy alpha if needed
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (dstCM.hasAlpha()) {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                alphaIdx = dstCM.numComponents - 1;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (alpha != null) {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int i = 0; i < numPixels; i++) {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tmpData[i][alphaIdx] = alpha[i];
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int i = 0; i < numPixels; i++) {
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        tmpData[i][alphaIdx] = 1f;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Store data back to the image
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int row = 0, dataPos = 0; row < srcW; row++) {
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int col = 0; col < srcH; col++) {
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    res.getRaster().setDataElements(row, col,
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            dstCM.getDataElements(tmpData[dataPos++], 0, null));
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isDstIndex) { // Convert image into indexed color
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Graphics2D g2d = dst.createGraphics();
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            g2d.drawImage(res, 0, 0, null);
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            g2d.dispose();
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return dst;
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return res;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Apply sequence.
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param sequence
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the sequence.
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param tmpData
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the tmp data.
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param srcCS
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the src cs.
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dstCS
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the dst cs.
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void applySequence(Object sequence[], float tmpData[][], ColorSpace srcCS,
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ColorSpace dstCS) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numPixels = tmpData.length;
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // First transform...
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sequence[0] instanceof ICC_Transform) { // ICC
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Transform t = (ICC_Transform)sequence[0];
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else { // non ICC
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int k = 0; k < numPixels; k++) {
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (Object element : sequence) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (element instanceof ICC_Transform) {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ICC_Transform t = (ICC_Transform)element;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cc.translateColor(t, tmpData, null, null, numPixels);
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ColorSpace cs = (ColorSpace)element;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (int k = 0; k < numPixels; k++) {
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    tmpData[k] = cs.toCIEXYZ(tmpData[k]);
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Last transform...
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sequence[sequence.length - 1] instanceof ICC_Transform) { // ICC
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ICC_Transform t = (ICC_Transform)sequence[sequence.length - 1];
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else { // non ICC
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int k = 0; k < numPixels; k++) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dstPt != null) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dstPt.setLocation(srcPt);
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return dstPt;
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new Point2D.Float((float)srcPt.getX(), (float)srcPt.getY());
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public WritableRaster createCompatibleDestRaster(Raster src) {
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nComps = 0;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nSpaces = conversionSequence.length;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nSpaces < 2) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object lastCS = conversionSequence[nSpaces - 1];
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (lastCS instanceof ColorSpace) {
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nComps = ((ColorSpace)lastCS).getNumComponents();
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nComps = ((ICC_Profile)lastCS).getNumComponents();
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Calculate correct data type
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dstDataType = src.getDataBuffer().getDataType();
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dstDataType != DataBuffer.TYPE_BYTE && dstDataType != DataBuffer.TYPE_SHORT) {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dstDataType = DataBuffer.TYPE_SHORT;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Raster.createInterleavedRaster(dstDataType, src.getWidth(), src.getHeight(), nComps,
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new Point(src.getMinX(), src.getMinY()));
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Rectangle2D getBounds2D(Raster src) {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return src.getBounds();
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Rectangle2D getBounds2D(BufferedImage src) {
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return src.getRaster().getBounds();
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets an array of ICC_Profiles objects which constructs this
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ColorConvertOp object or returns null if this ColorConvertOp is not
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * constructed from array of ICC_Profiles.
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an array of ICC_Profiles objects which constructs this
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         ColorConvertOp object or returns null if this ColorConvertOp is
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         not constructed from array of ICC_Profiles.
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final ICC_Profile[] getICC_Profiles() {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (midProfiles != null) {
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return midProfiles;
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final RenderingHints getRenderingHints() {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return renderingHints;
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
711