/*
 * @(#) JAIOpUtil.java 1.0 2000/10/4
 * Copyright (c) 2000 Larry Rodrigues
 */
package com.vistech.jai.util;
import java.awt.image.renderable.*;
import java.awt.image.RenderedImage;
import java.awt.*;
import java.awt.geom.*;
import javax.media.jai.*;

/** A utility class that provides a number of static methods, each of which
  * applys a JAI operator.
  * @version 1.0 4 October 2000
  * @author Lawrence Rodrigues
  */

public class JAIOpUtil {
   public static RenderedOp addImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("add", pb);
   }

   public static RenderedOp subtractImages(PlanarImage image1,
                                           PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("subtract", pb);
   }

   public static RenderedOp multiplyImages(PlanarImage image1,
                                           PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("multiply", pb);
   }

   public static RenderedOp divideImages(PlanarImage image1,
                                           PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("divide", pb);
   }

   public static RenderedOp andImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("and", pb);
   }

   public static RenderedOp orImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("or", pb);
   }

   public static RenderedOp xorImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("xor", pb);
   }

   public static RenderedOp notImage(PlanarImage image1) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      return JAI.create("not", pb);
   }

   public static RenderedOp minImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("min", pb);
   }

   public static RenderedOp maxImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("max", pb);
   }

   public static RenderedOp overlayImages(PlanarImage image1,
                                      PlanarImage image2 ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image1);
      pb.addSource(image2);
      return JAI.create("overlay", pb);
   }

   public static RenderedOp compositeImages(PlanarImage sourceImage1,
                                      PlanarImage sourceImage2,
                                      boolean alphaPremultiplied,
                                      int destAlpha ) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(sourceImage1);
      pb.addSource(sourceImage2);
      pb.add(sourceImage1);
      pb.add(sourceImage2);
      pb.add(new Boolean(alphaPremultiplied));
      pb.add(destAlpha);
      return JAI.create("composite", pb);
   }

    public static RenderedOp logImage(PlanarImage image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("log", pb);
   }

    public static RenderedOp expImage(PlanarImage image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("exp", pb);
   }

   public static RenderedOp cropImage(PlanarImage image, Rectangle rect){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add((float)rect.x);
      pb.add((float)rect.y);
      pb.add((float)rect.width);
      pb.add((float)rect.height);
      return JAI.create("crop", pb);
   }

   public static RenderedOp cropImage(PlanarImage image, Rectangle2D rect){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add((float)rect.getX());
      pb.add((float)rect.getY());
      pb.add((float)rect.getWidth());
      pb.add((float)rect.getHeight());
      return JAI.create("crop", pb);
   }

   public static RenderedOp boxFilterImage(PlanarImage image,
                                      int wid, int ht,
                                      Point pixelPos){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(wid);
      pb.add(ht);
      pb.add(pixelPos.x);
      pb.add(pixelPos.y);
      return JAI.create("BoxFilter", pb);
   }

   public static RenderedOp medianFilterImage(PlanarImage image,
                                         int maskShape,
                                         int maskSize){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(maskShape);
      pb.add(maskSize);
      return JAI.create("MedianFilter", pb);
   }


   public static RenderedOp DFTImage(PlanarImage image,
                                     Integer scalingType,
                                     Integer dataNature) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(scalingType).add(dataNature);
      return JAI.create("dft", pb);
   }

   public static RenderedOp inverseDFTImage(RenderedOp image,
                                     Integer scalingType,
                                     Integer dataNature) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(scalingType).add(dataNature);
      return JAI.create("idft", pb);
   }

   public static RenderedOp DCTImage(PlanarImage image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("dct", pb);
   }

   public static RenderedOp inverseDCTImage(RenderedOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("idct", pb);
  }

   public static RenderedOp magnitudeImage(RenderedOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("magnitude", pb);
   }

    public static RenderedOp magnitudeSquaredImage(RenderedOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("magnitudeSquared", pb);
   }

   public static RenderedOp phaseImage(RenderedOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.create("phase", pb);
   }

    public static RenderedOp periodicShiftImage(RenderedOp image,
                                     int shiftX,
                                     int shiftY) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(shiftX).add(shiftY);
      return JAI.create("idft", pb);
   }

   public static RenderedOp polarToComplexImage(RenderedOp mag,
                                                RenderedOp phase)  {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(mag);
      pb.addSource(phase);
      return JAI.create("polartocomplex", pb);
   }


   public static RenderableOp DFTImage(RenderableOp image,
                                     Integer scalingType,
                                     Integer dataNature) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(scalingType).add(dataNature);
      return JAI.createRenderable("dft", pb);
   }

   public static RenderableOp inverseDFTImage(RenderableOp image,
                                     Integer scalingType,
                                     Integer dataNature) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(scalingType).add(dataNature);
      return JAI.createRenderable("idft", pb);
   }

   public static RenderableOp DCTImage(RenderableOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.createRenderable("dct", pb);
   }

   public static RenderableOp InverseDCTImage(RenderableOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.createRenderable("idct", pb);
  }

   public static RenderableOp magnitudeImage(RenderableOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.createRenderable("magnitude", pb);
   }

    public static RenderableOp magnitudeSquaredImage(RenderableOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.createRenderable("magnitudeSquared", pb);
   }

   public static RenderableOp phaseImage(RenderableOp image){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      return JAI.createRenderable("phase", pb);
   }

   public static RenderableOp periodicShiftImage(RenderableOp image,
                                     int shiftX,
                                     int shiftY) {
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(shiftX).add(shiftY);
      return JAI.createRenderable("idft", pb);
   }
}
