/*
 * Copyright 1997-2005 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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;
    }
}
