/* AffineTransformOp.java --  This class performs affine 
   transformation between two images or rasters in 2 dimensions.
   Copyright (C) 2004, 2006 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.awt.image;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;

/**
 * AffineTransformOp performs matrix-based transformations (translations,
 * scales, flips, rotations, and shears).
 * 
 * If interpolation is required, nearest neighbour, bilinear, and bicubic
 * methods are available.
 *
 * @author Olga Rodimina (rodimina@redhat.com) 
 * @author Francis Kung (fkung@redhat.com)
 */
public class AffineTransformOp implements BufferedImageOp, RasterOp
{
    public static final int TYPE_NEAREST_NEIGHBOR = 1;
    
    public static final int TYPE_BILINEAR = 2;
    
    /**
     * @since 1.5.0
     */
    public static final int TYPE_BICUBIC = 3;

    private AffineTransform transform;
    private RenderingHints hints;
    
    /**
     * Construct AffineTransformOp with the given xform and interpolationType.
     * Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
     * TYPE_NEAREST_NEIGHBOR.
     *
     * @param xform AffineTransform that will applied to the source image 
     * @param interpolationType type of interpolation used
     * @throws ImagingOpException if the transform matrix is noninvertible
     */
    public AffineTransformOp (AffineTransform xform, int interpolationType)
    {
      this.transform = xform;
      if (xform.getDeterminant() == 0)
        throw new ImagingOpException(null);

      switch (interpolationType)
      {
      case TYPE_BILINEAR:
        hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION, 
                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        break;
      case TYPE_BICUBIC:
        hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION, 
				    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        break;
      default:
        hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
                                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
      }
    }

    /**
     * Construct AffineTransformOp with the given xform and rendering hints.
     * 
     * @param xform AffineTransform that will applied to the source image
     * @param hints rendering hints that will be used during transformation
     * @throws ImagingOpException if the transform matrix is noninvertible
     */
    public AffineTransformOp (AffineTransform xform, RenderingHints hints)
    {
      this.transform = xform;
      this.hints = hints;
      if (xform.getDeterminant() == 0)
        throw new ImagingOpException(null);
    }

    /**
     * Creates a new BufferedImage with the size equal to that of the 
     * transformed image and the correct number of bands. The newly created 
     * image is created with the specified ColorModel. 
     * If a ColorModel is not specified, an appropriate ColorModel is used.
     *
     * @param src the source image.
     * @param destCM color model for the destination image (can be null).
     * @return a new compatible destination image.
     */
    public BufferedImage createCompatibleDestImage (BufferedImage src,
                                                    ColorModel destCM)
    {
      if (destCM != null)
        return new BufferedImage(destCM,
                                 createCompatibleDestRaster(src.getRaster()),
                                 src.isAlphaPremultiplied(), null);

      // This behaviour was determined by Mauve testcases, and is compatible
      // with the reference implementation
      if (src.getType() == BufferedImage.TYPE_INT_ARGB_PRE
          || src.getType() == BufferedImage.TYPE_4BYTE_ABGR
          || src.getType() == BufferedImage.TYPE_4BYTE_ABGR_PRE)
        return new BufferedImage(src.getWidth(), src.getHeight(), src.getType());

      else
        return new BufferedImage(src.getWidth(), src.getHeight(),
                                 BufferedImage.TYPE_INT_ARGB);
    }

    /**
     * Creates a new WritableRaster with the size equal to the transformed 
     * source raster and correct number of bands .
     *
     * @param src the source raster.
     * @throws RasterFormatException if resulting width or height of raster is 0.
     * @return a new compatible raster.
     */
    public WritableRaster createCompatibleDestRaster (Raster src)
    {
      Rectangle2D rect = getBounds2D(src);
      
      if (rect.getWidth() == 0 || rect.getHeight() == 0) 
        throw new RasterFormatException("width or height is 0");

      return src.createCompatibleWritableRaster((int) rect.getWidth(), 
                                                (int) rect.getHeight());
    }

    /**
     * Transforms source image using transform specified at the constructor.
     * The resulting transformed image is stored in the destination image if one
     * is provided; otherwise a new BufferedImage is created and returned. 
     *
     * @param src source image
     * @param dst destination image
     * @throws IllegalArgumentException if the source and destination image are
     *          the same
     * @return transformed source image.
     */
    public final BufferedImage filter (BufferedImage src, BufferedImage dst)
    {
      if (dst == src)
        throw new IllegalArgumentException("src image cannot be the same as "
                                         + "the dst image");

      // If the destination image is null, then use a compatible BufferedImage
      if (dst == null)
        dst = createCompatibleDestImage(src, null);

      Graphics2D gr = dst.createGraphics();
      gr.setRenderingHints(hints);
      gr.drawImage(src, transform, null);
      return dst;
    }

    /**
     * Transforms source raster using transform specified at the constructor.
     * The resulting raster is stored in the destination raster if it is not
     * null, otherwise a new raster is created and returned.
     *
     * @param src source raster
     * @param dst destination raster
     * @throws IllegalArgumentException if the source and destination are not
     *          compatible
     * @return transformed raster.
     */
    public final WritableRaster filter(Raster src, WritableRaster dst)
    {
      // Initial checks
      if (dst == src)
        throw new IllegalArgumentException("src image cannot be the same as"
                                           + " the dst image");

      if (dst == null)
        dst = createCompatibleDestRaster(src);

      if (src.getNumBands() != dst.getNumBands())
        throw new IllegalArgumentException("src and dst must have same number"
                                           + " of bands");
      
      // Optimization for rasters that can be represented in the RGB colormodel:
      // wrap the rasters in images, and let Cairo do the transformation
      if (ColorModel.getRGBdefault().isCompatibleSampleModel(src.getSampleModel())
          && ColorModel.getRGBdefault().isCompatibleSampleModel(dst.getSampleModel()))
        {
          WritableRaster src2 = Raster.createWritableRaster(src.getSampleModel(),
                                                            src.getDataBuffer(),
                                                            new Point(src.getMinX(),
                                                                      src.getMinY()));
          BufferedImage iSrc = new BufferedImage(ColorModel.getRGBdefault(),
                                                 src2, false, null);
          BufferedImage iDst = new BufferedImage(ColorModel.getRGBdefault(), dst,
                                                 false, null);
  
          return filter(iSrc, iDst).getRaster();
        }

      // Otherwise, we need to do the transformation in java code...
      // Create arrays to hold all the points
      double[] dstPts = new double[dst.getHeight() * dst.getWidth() * 2];
      double[] srcPts = new double[dst.getHeight() * dst.getWidth() * 2];

      // Populate array with all points in the *destination* raster
      int i = 0;
      for (int x = 0; x < dst.getWidth(); x++)
        {
          for (int y = 0; y < dst.getHeight(); y++)
            {
              dstPts[i++] = x;
              dstPts[i++] = y;
            }
        }
      Rectangle srcbounds = src.getBounds();

      // Use an inverse transform to map each point in the destination to
      // a point in the source.  Note that, while all points in the destination
      // matrix are integers, this is not necessarily true for points in the
      // source (hence why interpolation is required) 
      try
        {
          AffineTransform inverseTx = transform.createInverse();
          inverseTx.transform(dstPts, 0, srcPts, 0, dstPts.length / 2);
        }
      catch (NoninvertibleTransformException e)
        {
          // Shouldn't happen since the constructor traps this
          throw new ImagingOpException(e.getMessage());
        }

      // Different interpolation methods...
      if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
        filterNearest(src, dst, dstPts, srcPts);
      
      else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
        filterBilinear(src, dst, dstPts, srcPts);
    
      else          // bicubic
        filterBicubic(src, dst, dstPts, srcPts);

      return dst;  
    }

    /**
     * Transforms source image using transform specified at the constructor and 
     * returns bounds of the transformed image.
     *
     * @param src image to be transformed
     * @return bounds of the transformed image.
     */
    public final Rectangle2D getBounds2D (BufferedImage src)
    {
      return getBounds2D (src.getRaster());
    }
   
    /**
     * Returns bounds of the transformed raster.
     *
     * @param src raster to be transformed
     * @return bounds of the transformed raster.
     */
    public final Rectangle2D getBounds2D (Raster src)
    {
      return transform.createTransformedShape(src.getBounds()).getBounds2D();
    }

    /**
     * Returns interpolation type used during transformations.
     *
     * @return interpolation type
     */
    public final int getInterpolationType ()
    {
      if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
        return TYPE_BILINEAR;
      
      else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BICUBIC))
        return TYPE_BICUBIC;
      
      else 
        return TYPE_NEAREST_NEIGHBOR;
    }

    /** 
     * Returns location of the transformed source point. The resulting point 
     * is stored in the dstPt if one is specified.
     *  
     * @param srcPt point to be transformed
     * @param dstPt destination point
     * @return the location of the transformed source point.
     */
    public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt)
    {
      return transform.transform (srcPt, dstPt);
    }

    /**
     * Returns rendering hints that are used during transformation.
     *
     * @return the rendering hints used in this Op.
     */
    public final RenderingHints getRenderingHints ()
    {
      return hints;
    }

    /**
     * Returns transform used in transformation between source and destination
     * image.
     *
     * @return the transform used in this Op.
     */
    public final AffineTransform getTransform ()
    {
      return transform;
    }
    
    /**
     * Perform nearest-neighbour filtering
     * 
     * @param src the source raster
     * @param dst the destination raster
     * @param dpts array of points on the destination raster
     * @param pts array of corresponding points on the source raster
     */
    private void filterNearest(Raster src, WritableRaster dst, double[] dpts,
                               double[] pts)
    {
      Rectangle srcbounds = src.getBounds();
  
      // For all points on the destination raster, copy the value from the
      // corrosponding (rounded) source point
      for (int i = 0; i < dpts.length; i += 2)
        {
          int srcX = (int) Math.round(pts[i]) + src.getMinX();
          int srcY = (int) Math.round(pts[i + 1]) + src.getMinY();
          
          if (srcbounds.contains(srcX, srcY))
            dst.setDataElements((int) dpts[i] + dst.getMinX(),
                                (int) dpts[i + 1] + dst.getMinY(),
                                src.getDataElements(srcX, srcY, null));
        }
    }

    /**
     * Perform bilinear filtering
     * 
     * @param src the source raster
     * @param dst the destination raster
     * @param dpts array of points on the destination raster
     * @param pts array of corresponding points on the source raster
     */
    private void filterBilinear(Raster src, WritableRaster dst, double[] dpts,
                              double[] pts)
    {
      Rectangle srcbounds = src.getBounds();
  
      Object xyarr = null;
      Object xp1arr = null;
      Object yp1arr = null;
      Object xyp1arr = null;
      
      double xy;
      double xp1;
      double yp1;
      double xyp1;

      double[] result = new double[src.getNumBands()];
      
      // For all points in the destination raster, use bilinear interpolation
      // to find the value from the corrosponding source points
      for (int i = 0; i < dpts.length; i += 2)
        {
          int srcX = (int) Math.round(pts[i]) + src.getMinX();
          int srcY = (int) Math.round(pts[i + 1]) + src.getMinY();
          
          if (srcbounds.contains(srcX, srcY))
            {
              // Corner case at the bottom or right edge; use nearest neighbour
              if (pts[i] >= src.getWidth() - 1
                  || pts[i + 1] >= src.getHeight() - 1)
                dst.setDataElements((int) dpts[i] + dst.getMinX(),
                                    (int) dpts[i + 1] + dst.getMinY(),
                                    src.getDataElements(srcX, srcY, null));
  
              // Standard case, apply the bilinear formula
              else
                {
                  int x = (int) Math.floor(pts[i] + src.getMinX());
                  int y = (int) Math.floor(pts[i + 1] + src.getMinY());
                  double xdiff = pts[i] + src.getMinX() - x;
                  double ydiff = pts[i + 1] + src.getMinY() - y;

                  // Get surrounding pixels used in interpolation... optimized
                  // to use the smallest datatype possible.
                  if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
                      || src.getTransferType() == DataBuffer.TYPE_FLOAT)
                    {
                      xyarr = src.getPixel(x, y, (double[])xyarr);
                      xp1arr  = src.getPixel(x+1, y, (double[])xp1arr);
                      yp1arr = src.getPixel(x, y+1, (double[])yp1arr);
                      xyp1arr = src.getPixel(x+1, y+1, (double[])xyp1arr);
                    }
                  else
                    {
                      xyarr = src.getPixel(x, y, (int[])xyarr);
                      xp1arr  = src.getPixel(x+1, y, (int[])xp1arr);
                      yp1arr = src.getPixel(x, y+1, (int[])yp1arr);
                      xyp1arr = src.getPixel(x+1, y+1, (int[])xyp1arr);
                    }
                  // using 
                  // array[] pixels = src.getPixels(x, y, 2, 2, pixels);
                  // instead of doing four individual src.getPixel() calls
                  // should be faster, but benchmarking shows that it's not...
                  
                  // Run interpolation for each band
                  for (int j = 0; j < src.getNumBands(); j++)
                    {
                      // Pull individual sample values out of array
                      if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
                          || src.getTransferType() == DataBuffer.TYPE_FLOAT)
                        {
                          xy = ((double[])xyarr)[j];
                          xp1  = ((double[])xp1arr)[j];
                          yp1 = ((double[])yp1arr)[j];
                          xyp1 = ((double[])xyp1arr)[j];
                        }
                      else
                        {
                          xy = ((int[])xyarr)[j];
                          xp1  = ((int[])xp1arr)[j];
                          yp1 = ((int[])yp1arr)[j];
                          xyp1 = ((int[])xyp1arr)[j];
                        }
                      
                      // If all four samples are identical, there's no need to 
                      // calculate anything
                      if (xy == xp1 && xy == yp1 && xy == xyp1)
                        result[j] = xy;
                      
                      // Run bilinear interpolation formula
                      else
                        result[j] = (xy * (1-xdiff) + xp1 * xdiff) 
                                      * (1-ydiff) 
                                    + (yp1 * (1-xdiff) + xyp1 * xdiff)
                                      * ydiff;
                    }

                  dst.setPixel((int)dpts[i] + dst.getMinX(),
                               (int)dpts[i+1] + dst.getMinY(),
                               result);
                }
            }
        }
    }

    /**
     * Perform bicubic filtering
     * based on http://local.wasp.uwa.edu.au/~pbourke/colour/bicubic/
     * 
     * @param src the source raster
     * @param dst the destination raster
     * @param dpts array of points on the destination raster
     * @param pts array of corresponding points on the source raster
     */
    private void filterBicubic(Raster src, WritableRaster dst, double[] dpts,
                               double[] pts)
    {
      Rectangle srcbounds = src.getBounds();
      double[] result = new double[src.getNumBands()];
      Object pixels = null;

      // For all points on the destination raster, perform bicubic interpolation
      // from corrosponding source points
      for (int i = 0; i < dpts.length; i += 2)
        {
          if (srcbounds.contains((int) Math.round(pts[i]) + src.getMinX(),
                                 (int) Math.round(pts[i + 1]) + src.getMinY()))
            {
              int x = (int) Math.floor(pts[i] + src.getMinX());
              int y = (int) Math.floor(pts[i + 1] + src.getMinY());
              double dx = pts[i] + src.getMinX() - x;
              double dy = pts[i + 1] + src.getMinY() - y;
              Arrays.fill(result, 0);
  
              for (int m = - 1; m < 3; m++)
                for (int n = - 1; n < 3; n++)
                  {
                    // R(x) = ( P(x+2)^3 - 4 P(x+1)^3 + 6 P(x)^3 - 4 P(x-1)^3 ) / 6
                    double r1 = 0;
                    double r2 = 0;

                    // Calculate R(m - dx)
                    double rx = m - dx + 2;
                    r1 += rx * rx * rx;

                    rx = m - dx + 1;
                    if (rx > 0)
                      r1 -= 4 * rx * rx * rx;

                    rx = m - dx;
                    if (rx > 0)
                      r1 += 6 * rx * rx * rx;

                    rx = m - dx - 1;
                    if (rx > 0)
                      r1 -= 4 * rx * rx * rx;

                    r1 /= 6;

                    // Calculate R(dy - n);
                    rx = dy - n + 2;
                    if (rx > 0)
                      r2 += rx * rx * rx;

                    rx = dy - n + 1;
                    if (rx > 0)
                      r2 -= 4 * rx * rx * rx;

                    rx = dy - n;
                    if (rx > 0)
                      r2 += 6 * rx * rx * rx;

                    rx = dy - n - 1;
                    if (rx > 0)
                      r2 -= 4 * rx * rx * rx;

                    r2 /= 6;

                    // Calculate F(i+m, j+n) R(m - dx) R(dy - n)
                    // Check corner cases
                    int srcX = x + m;
                    if (srcX >= src.getMinX() + src.getWidth())
                      srcX = src.getMinX() + src.getWidth() - 1;
                    else if (srcX < src.getMinX())
                      srcX = src.getMinX();

                    int srcY = y + n;
                    if (srcY >= src.getMinY() + src.getHeight())
                      srcY = src.getMinY() + src.getHeight() - 1;
                    else if (srcY < src.getMinY())
                      srcY = src.getMinY();

                    // Calculate once for each band, using the smallest
                    // datatype possible
                    if (src.getTransferType() == DataBuffer.TYPE_DOUBLE
                        || src.getTransferType() == DataBuffer.TYPE_FLOAT)
                      {
                        pixels = src.getPixel(srcX, srcY, (double[])pixels);
                        for (int j = 0; j < result.length; j++)
                          result[j] += ((double[])pixels)[j] * r1 * r2;
                      }
                    else
                      {
                        pixels = src.getPixel(srcX, srcY, (int[])pixels);
                        for (int j = 0; j < result.length; j++)
                          result[j] += ((int[])pixels)[j] * r1 * r2;
                      }
                  }
  
              // Put it all together
              dst.setPixel((int)dpts[i] + dst.getMinX(),
                           (int)dpts[i+1] + dst.getMinY(),
                           result);
            }
        }
    }
}
