home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / image / ConvolveOp.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  7.7 KB  |  247 lines

  1. /*
  2.  * @(#)ConvolveOp.java    1.32 98/03/18
  3.  *
  4.  * Copyright 1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt.image;
  16.  
  17. import java.awt.GraphicsEnvironment;
  18. import java.awt.color.ICC_Profile;
  19. import java.awt.geom.Rectangle2D;
  20. import java.awt.Rectangle;
  21. import java.awt.geom.Point2D;
  22.  
  23. /**
  24.  * This class implements a convolution from the source
  25.  * to the destination.
  26.  * Convolution using a convolution kernel is a spatial operation that 
  27.  * computes the output pixel from an input pixel by multiplying the kernel
  28.  * with the surround of the input pixel.
  29.  * This allows the output pixel to be affected by the immediate neighborhood
  30.  * in a way that can be mathematically specified with a kernel.
  31.  *<p>
  32.  * This class operates with BufferedImage data that are premultiplied with
  33.  * alpha.  If the Source BufferedImage has an alpha component, and the
  34.  * color components are not premultiplied with the alpha component, then
  35.  * the data are premultiplied before being convolved.  If the Destination
  36.  * has alpha components which are not premultiplied, then alpha is divided
  37.  * out before storing into the Destination.  If the Destination has no
  38.  * alpha component, then the resulting alpha is discarded after first
  39.  * dividing it out of the color components.
  40.  * <p>
  41.  * Rasters are treated as having no alpha channel.
  42.  *<p>
  43.  * Note that the Source and the Destination may not be the same object.
  44.  * @version 10 Feb 1997
  45.  * @see Kernel
  46.  */
  47. public class ConvolveOp implements BufferedImageOp, RasterOp {
  48.     Kernel kernel;
  49.     int edgeHint;
  50.  
  51.     /**
  52.      * Edge condition constants
  53.      */
  54.     
  55.     /**
  56.      * Pixels at the edge of the destination image are set to zero.  This
  57.      * is the default.
  58.      */
  59.     
  60.     public static final int EDGE_ZERO_FILL = 0;
  61.  
  62.     /**
  63.      * Pixels at the edge of the source image are copied to
  64.      * the corresponding pixels in the destination without modification.
  65.      */
  66.     public static final int EDGE_NO_OP     = 1;
  67.  
  68.     /**
  69.      * Constructs a ConvolveOp given a Kernel and an edge hint.  
  70.      * @see Kernel
  71.      * @see #EDGE_NO_OP
  72.      * @see #EDGE_ZERO_FILL
  73.      */
  74.     public ConvolveOp(Kernel kernel, int edgeHint) {
  75.         this.kernel   = kernel;
  76.         this.edgeHint = edgeHint;
  77.     }
  78.  
  79.     /**
  80.      * Constructs a ConvolveOp given a Kernel.  The edge hint
  81.      * will be EDGE_ZERO_FILL.
  82.      * @see Kernel
  83.      * @see #EDGE_ZERO_FILL
  84.      */
  85.     public ConvolveOp(Kernel kernel) {
  86.         this.kernel   = kernel;
  87.         this.edgeHint = EDGE_ZERO_FILL;
  88.     }
  89.  
  90.     /**
  91.      * Return the edge hint.
  92.      * @see #EDGE_NO_OP
  93.      * @see #EDGE_ZERO_FILL
  94.      */
  95.     public int getEdgeHint() {
  96.         return edgeHint;
  97.     }
  98.  
  99.     /**
  100.      * Return the Kernel.
  101.      */
  102.     public Kernel getKernel() {
  103.         return kernel;
  104.     }
  105.  
  106.     /**
  107.      * Perform a convolution on BufferedImages.  Each component of the
  108.      * source image will be convolved.
  109.      * If the color model in the source image is not the same as that
  110.      * in the destination image, the pixels will be converted
  111.      * in the destination.  If the destination image is null,
  112.      * a BufferedImage will be created with the source ColorModel.
  113.      * The IllegalArgumentException may be thrown if the source is the
  114.      * same as the destination.
  115.      */
  116.     public BufferedImage filter (BufferedImage src, BufferedImage dst) {
  117.         BufferedImage tmpDst = null;
  118.         ColorModel srcCM = src.getColorModel();
  119.  
  120.         if (src == null) {
  121.             throw new NullPointerException("src image is null");
  122.         }
  123.         if (dst == null) {
  124.             dst = createCompatibleDestImage(src, null);
  125.         }
  126.         else {
  127.             ColorModel dstCM = dst.getColorModel();
  128.             if (! srcCM.equals(dstCM)) {
  129.                 tmpDst = dst;
  130.                 dst = createCompatibleDestImage(src, null);
  131.             }
  132.         }
  133.  
  134.         GraphicsEnvironment ge =
  135.             GraphicsEnvironment.getLocalGraphicsEnvironment();
  136.         ImagingLib imlib = ge.getImagingLib();
  137.  
  138.         if (imlib.filter(this, src, dst) == null) {
  139.             throw new ImagingOpException ("Unable to convolve src image");
  140.         }
  141.         
  142.         if (tmpDst != null) {
  143.             // It worked so now convert it to the real destination
  144.             ColorConvertOp cop = new ColorConvertOp((ICC_Profile[])null);
  145.             cop.filter(tmpDst, dst);
  146.         }
  147.             
  148.         return dst;
  149.     }
  150.  
  151.     /**
  152.      * Perform a convolution on Rasters.  Each channel of the source Raster
  153.      * will be convolved.
  154.      * The source and destination must have the same number of channels.
  155.      * If the destination Raster is null, a new Raster will be created.
  156.      * The IllegalArgumentException may be thrown if the source is
  157.      * the same as the destination.
  158.      */
  159.     public WritableRaster filter (Raster src, WritableRaster dst) {
  160.         if (dst == null) {
  161.             dst = createCompatibleDestRaster(src);
  162.         }
  163.         GraphicsEnvironment ge =
  164.             GraphicsEnvironment.getLocalGraphicsEnvironment();
  165.         ImagingLib imlib = ge.getImagingLib();
  166.  
  167.         if (imlib.filter(this, src, dst) == null) {
  168.             throw new ImagingOpException ("Unable to convolve src image");
  169.         }
  170.  
  171.         return dst;
  172.     }
  173.  
  174.     /**
  175.      * Creates an empty destination image with the correct size and number 
  176.      * of channels.
  177.      * @param src       Source image for the filter operation
  178.      * @param destCM    ColorModel of the destination.  Can be null.
  179.      */
  180.     public BufferedImage createCompatibleDestImage(BufferedImage src,
  181.                                                    ColorModel destCM) {
  182.         BufferedImage image;
  183.         if (destCM == null) {
  184.             destCM = src.getColorModel();
  185.             // Not much support for ICM
  186.             if (destCM instanceof IndexColorModel) {
  187.                 destCM = ColorModel.getRGBdefault();
  188.             }
  189.         }
  190.  
  191.         int w = src.getWidth();
  192.         int h = src.getHeight();
  193.         image = new BufferedImage (destCM,
  194.                                    destCM.createCompatibleWritableRaster(w, h),
  195.                                    destCM.isAlphaPremultiplied());
  196.  
  197.         return image;
  198.     }
  199.     
  200.     /**
  201.      * Creates an empty destination Raster with the correct size and number 
  202.      * of channels.
  203.      */
  204.     public WritableRaster createCompatibleDestRaster(Raster src) {
  205.         return src.createCompatibleWritableRaster();
  206.     }
  207.     
  208.     /**
  209.      * Returns the bounding box of the filtered destination image.  Since
  210.      * this is not a geometric operation, the bounding box does not
  211.      * change.
  212.      */
  213.     public Rectangle2D getDestBounds(BufferedImage src) {
  214.     return getDestBounds(src.getRaster());
  215.     }
  216.  
  217.     /**
  218.      * Returns the bounding box of the filtered destination Raster.  Since
  219.      * this is not a geometric operation, the bounding box does not
  220.      * change.
  221.      */
  222.     public Rectangle2D getDestBounds(Raster src) {
  223.     //    return new Rectangle (src.getXOffset(),
  224.     //          src.getYOffset(),
  225.     //          src.getWidth(), src.getHeight());
  226.     return src.getBounds();
  227.     }
  228.  
  229.     /**
  230.      * Returns the location of the destination point given a
  231.      * point in the source image.  If dstPt is non-null, it will
  232.      * be used to hold the return value.  Since this is not a geometric
  233.      * operation, the srcPt will equal the dstPt.
  234.      */
  235.     public Point2D getDestPoint(Point2D srcPt, Point2D dstPt) {
  236.         if (dstPt == null) {
  237.             dstPt = new Point2D.Float();
  238.         }
  239.     dstPt.setLocation(srcPt.getX(), srcPt.getY());
  240.  
  241.         return dstPt;
  242.     }
  243.  
  244. }
  245.  
  246.  
  247.