/*
 * Copyright (c) 1997, 2005, 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.
 */

package java.awt.image;

import java.awt.GraphicsEnvironment;
import java.awt.color.ICC_Profile;
import java.awt.geom.Rectangle2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.RenderingHints;
import sun.awt.image.ImagingLib;
import java.util.Arrays;

/**
 * This class performs an arbitrary linear combination of the bands
 * in a <CODE>Raster</CODE>, using a specified matrix.
 * <p>
 * The width of the matrix must be equal to the number of bands in the
 * source <CODE>Raster</CODE>, optionally plus one.  If there is one more
 * column in the matrix than the number of bands, there is an implied 1 at the
 * end of the vector of band samples representing a pixel.  The height
 * of the matrix must be equal to the number of bands in the destination.
 * <p>
 * For example, a 3-banded <CODE>Raster</CODE> might have the following
 * transformation applied to each pixel in order to invert the second band of
 * the <CODE>Raster</CODE>.
 * <pre>
 *   [ 1.0   0.0   0.0    0.0  ]     [ b1 ]
 *   [ 0.0  -1.0   0.0  255.0  ]  x  [ b2 ]
 *   [ 0.0   0.0   1.0    0.0  ]     [ b3 ]
 *                                   [ 1 ]
 * </pre>
 *
 * <p>
 * Note that the source and destination can be the same object.
 */
public class BandCombineOp implements  RasterOp {
    float[][] matrix;
    int nrows = 0;
    int ncols = 0;
    RenderingHints hints;

    /**
     * Constructs a <CODE>BandCombineOp</CODE> with the specified matrix.
     * The width of the matrix must be equal to the number of bands in
     * the source <CODE>Raster</CODE>, optionally plus one.  If there is one
     * more column in the matrix than the number of bands, there is an implied
     * 1 at the end of the vector of band samples representing a pixel.  The
     * height of the matrix must be equal to the number of bands in the
     * destination.
     * <p>
     * The first subscript is the row index and the second
     * is the column index.  This operation uses none of the currently
     * defined rendering hints; the <CODE>RenderingHints</CODE> argument can be
     * null.
     *
     * @param matrix The matrix to use for the band combine operation.
     * @param hints The <CODE>RenderingHints</CODE> object for this operation.
     * Not currently used so it can be null.
     */
    public BandCombineOp (float[][] matrix, RenderingHints hints) {
        nrows = matrix.length;
        ncols = matrix[0].length;
        this.matrix = new float[nrows][];
        for (int i=0; i < nrows; i++) {
            /* Arrays.copyOf is forgiving of the source array being
             * too short, but it is also faster than other cloning
             * methods, so we provide our own protection for short
             * matrix rows.
             */
            if (ncols > matrix[i].length) {
                throw new IndexOutOfBoundsException("row "+i+" too short");
            }
            this.matrix[i] = Arrays.copyOf(matrix[i], ncols);
        }
        this.hints  = hints;
    }

    /**
     * Returns a copy of the linear combination matrix.
     *
     * @return The matrix associated with this band combine operation.
     */
    public final float[][] getMatrix() {
        float[][] ret = new float[nrows][];
        for (int i = 0; i < nrows; i++) {
            ret[i] = Arrays.copyOf(matrix[i], ncols);
        }
        return ret;
    }

    /**
     * Transforms the <CODE>Raster</CODE> using the matrix specified in the
     * constructor. An <CODE>IllegalArgumentException</CODE> may be thrown if
     * the number of bands in the source or destination is incompatible with
     * the matrix.  See the class comments for more details.
     * <p>
     * If the destination is null, it will be created with a number of bands
     * equalling the number of rows in the matrix. No exception is thrown
     * if the operation causes a data overflow.
     *
     * @param src The <CODE>Raster</CODE> to be filtered.
     * @param dst The <CODE>Raster</CODE> in which to store the results
     * of the filter operation.
     *
     * @return The filtered <CODE>Raster</CODE>.
     *
     * @throws IllegalArgumentException If the number of bands in the
     * source or destination is incompatible with the matrix.
     */
    public WritableRaster filter(Raster src, WritableRaster dst) {
        int nBands = src.getNumBands();
        if (ncols != nBands && ncols != (nBands+1)) {
            throw new IllegalArgumentException("Number of columns in the "+
                                               "matrix ("+ncols+
                                               ") must be equal to the number"+
                                               " of bands ([+1]) in src ("+
                                               nBands+").");
        }
        if (dst == null) {
            dst = createCompatibleDestRaster(src);
        }
        else if (nrows != dst.getNumBands()) {
            throw new IllegalArgumentException("Number of rows in the "+
                                               "matrix ("+nrows+
                                               ") must be equal to the number"+
                                               " of bands ([+1]) in dst ("+
                                               nBands+").");
        }

        if (ImagingLib.filter(this, src, dst) != null) {
            return dst;
        }

        int[] pixel = null;
        int[] dstPixel = new int[dst.getNumBands()];
        float accum;
        int sminX = src.getMinX();
        int sY = src.getMinY();
        int dminX = dst.getMinX();
        int dY = dst.getMinY();
        int sX;
        int dX;
        if (ncols == nBands) {
            for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
                dX = dminX;
                sX = sminX;
                for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
                    pixel = src.getPixel(sX, sY, pixel);
                    for (int r=0; r < nrows; r++) {
                        accum = 0.f;
                        for (int c=0; c < ncols; c++) {
                            accum += matrix[r][c]*pixel[c];
                        }
                        dstPixel[r] = (int) accum;
                    }
                    dst.setPixel(dX, dY, dstPixel);
                }
            }
        }
        else {
            // Need to add constant
            for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
                dX = dminX;
                sX = sminX;
                for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
                    pixel = src.getPixel(sX, sY, pixel);
                    for (int r=0; r < nrows; r++) {
                        accum = 0.f;
                        for (int c=0; c < nBands; c++) {
                            accum += matrix[r][c]*pixel[c];
                        }
                        dstPixel[r] = (int) (accum+matrix[r][nBands]);
                    }
                    dst.setPixel(dX, dY, dstPixel);
                }
            }
        }

        return dst;
    }

    /**
     * Returns the bounding box of the transformed destination.  Since
     * this is not a geometric operation, the bounding box is the same for
     * the source and destination.
     * An <CODE>IllegalArgumentException</CODE> may be thrown if the number of
     * bands in the source is incompatible with the matrix.  See
     * the class comments for more details.
     *
     * @param src The <CODE>Raster</CODE> to be filtered.
     *
     * @return The <CODE>Rectangle2D</CODE> representing the destination
     * image's bounding box.
     *
     * @throws IllegalArgumentException If the number of bands in the source
     * is incompatible with the matrix.
     */
    public final Rectangle2D getBounds2D (Raster src) {
        return src.getBounds();
    }


    /**
     * Creates a zeroed destination <CODE>Raster</CODE> with the correct size
     * and number of bands.
     * An <CODE>IllegalArgumentException</CODE> may be thrown if the number of
     * bands in the source is incompatible with the matrix.  See
     * the class comments for more details.
     *
     * @param src The <CODE>Raster</CODE> to be filtered.
     *
     * @return The zeroed destination <CODE>Raster</CODE>.
     */
    public WritableRaster createCompatibleDestRaster (Raster src) {
        int nBands = src.getNumBands();
        if ((ncols != nBands) && (ncols != (nBands+1))) {
            throw new IllegalArgumentException("Number of columns in the "+
                                               "matrix ("+ncols+
                                               ") must be equal to the number"+
                                               " of bands ([+1]) in src ("+
                                               nBands+").");
        }
        if (src.getNumBands() == nrows) {
            return src.createCompatibleWritableRaster();
        }
        else {
            throw new IllegalArgumentException("Don't know how to create a "+
                                               " compatible Raster with "+
                                               nrows+" bands.");
        }
    }

    /**
     * Returns the location of the corresponding destination point given a
     * point in the source <CODE>Raster</CODE>.  If <CODE>dstPt</CODE> is
     * specified, it is used to hold the return value.
     * Since this is not a geometric operation, the point returned
     * is the same as the specified <CODE>srcPt</CODE>.
     *
     * @param srcPt The <code>Point2D</code> that represents the point in
     *              the source <code>Raster</code>
     * @param dstPt The <CODE>Point2D</CODE> in which to store the result.
     *
     * @return The <CODE>Point2D</CODE> in the destination image that
     * corresponds to the specified point in the source image.
     */
    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 rendering hints for this operation.
     *
     * @return The <CODE>RenderingHints</CODE> object associated with this
     * operation.  Returns null if no hints have been set.
     */
    public final RenderingHints getRenderingHints() {
        return hints;
    }
}
