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 / BandCombineOp.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  8.5 KB  |  231 lines

  1. /*
  2.  * @(#)BandCombineOp.java    1.30 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 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 performs an arbitrary linear combination of bands 
  25.  * in a Raster, using a specified matrix.  
  26.  * <p>
  27.  * For operations with a Raster, the width of the matrix must be equal to 
  28.  * the number of bands, optionally plus one.  If there is one more column
  29.  * in the matrix than the number of bands, there is an implied 1 at the
  30.  * end of the pixel vector.  The height of the matrix must be equal to
  31.  * the number of bands in the destination.  For example, a 3-banded Raster
  32.  * might have the following transformation applied to
  33.  * each pixel in order to invert the second band of the Raster.
  34.  * <pre>
  35.  *   [ 1.0   0.0   0.0    0.0  ]     [ b1 ]    
  36.  *   [ 0.0  -1.0   0.0  255.0  ]  x  [ b2 ]
  37.  *   [ 0.0   0.0   1.0    0.0  ]     [ b3 ]
  38.  *                                   [ 1 ]
  39.  * </pre>
  40.  *
  41.  * <p>
  42.  * Note that the source and destination can be the same object.
  43.  * @version 10 Feb 1997
  44.  */
  45. public class BandCombineOp implements  RasterOp {
  46.     float[][] matrix;
  47.     int nrows = 0;
  48.     int ncols = 0;
  49.     
  50.     /**
  51.      * This constructs a BandCombineOp with the specified matrix.
  52.      * See the class comments for restrictions on the size of the
  53.      * matrix.  The first subscript is the row index and the second
  54.      * is the column index.
  55.      */
  56.     public BandCombineOp (float[][] matrix) {
  57.         nrows = matrix.length;
  58.         ncols = matrix[0].length;
  59.         this.matrix = new float[nrows+1][ncols+1];
  60.         for (int i=0; i < nrows; i++) {
  61.             System.arraycopy(matrix[i], 0, this.matrix[i], 0, ncols);
  62.         }
  63.     }
  64.  
  65.     /**
  66.      * Returns the matrix.
  67.      */
  68.     public float[][] getMatrix() {
  69.         return (float[][]) matrix.clone();
  70.     }
  71.     
  72.     /**
  73.      * Transforms the Raster using the matrix in the constructor.
  74.      * The IllegalArgumentException may be thrown if the number of
  75.      * bands in the source or destination is incompatible with the
  76.      * matrix.  See the class comments for more details.  If
  77.      * the destination
  78.      * is null, it will be created with a number of bands equalling
  79.      * the number of rows in the matrix.  No exception will be thrown
  80.      * if the operation causes a data overflow.
  81.      */
  82.     public WritableRaster filter(Raster src, WritableRaster dst) {
  83.         int nBands = src.getNumBands();
  84.         if (ncols != nBands && ncols != (nBands+1)) {
  85.             throw new IllegalArgumentException("Number of columns in the "+
  86.                                                "matrix ("+ncols+
  87.                                                ") must be equal to the number"+
  88.                                                " of bands ([+1]) in src ("+
  89.                                                nBands+").");
  90.         }
  91.         if (dst == null) {
  92.             dst = createCompatibleDestRaster(src);
  93.         }
  94.         else if (nrows != dst.getNumBands()) {
  95.             throw new IllegalArgumentException("Number of rows in the "+
  96.                                                "matrix ("+nrows+
  97.                                                ") must be equal to the number"+
  98.                                                " of bands ([+1]) in dst ("+
  99.                                                nBands+").");
  100.         }
  101.  
  102.         GraphicsEnvironment ge =
  103.             GraphicsEnvironment.getLocalGraphicsEnvironment();
  104.         ImagingLib imlib = ge.getImagingLib();
  105.  
  106.         if (imlib.filter(this, src, dst) != null) {
  107.             return dst;
  108.         }
  109.  
  110.         int[] pixel = null;
  111.         int[] dstPixel = new int[dst.getNumBands()];
  112.         float accum;
  113.         int sminX = src.getMinX();
  114.         int sY = src.getMinY();
  115.         int dminX = dst.getMinX();
  116.         int dY = dst.getMinY();
  117.         int sX;
  118.         int dX;
  119.         if (ncols == nBands) {
  120.             for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
  121.                 dX = dminX;
  122.                 sX = sminX;
  123.                 for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
  124.                     pixel = src.getPixel(sX, sY, pixel);
  125.                     for (int r=0; r < nrows; r++) {
  126.                         accum = 0.f;
  127.                         for (int c=0; c < ncols; c++) {
  128.                             accum += matrix[r][c]*pixel[c];
  129.                         }
  130.                         dstPixel[r] = (int) accum;
  131.                     }
  132.                     dst.setPixel(dX, dY, dstPixel);
  133.                 }
  134.             }
  135.         }
  136.         else {
  137.             // Need to add constant
  138.             for (int y=0; y < src.getHeight(); y++, sY++, dY++) {
  139.                 dX = dminX;
  140.                 sX = sminX;
  141.                 for (int x=0; x < src.getWidth(); x++, sX++, dX++) {
  142.                     pixel = src.getPixel(sX, sY, pixel);
  143.                     for (int r=0; r < nrows; r++) {
  144.                         accum = 0.f;
  145.                         for (int c=0; c < nBands; c++) {
  146.                             accum += matrix[r][c]*pixel[c];
  147.                         }
  148.                         dstPixel[r] = (int) (accum+matrix[r][nBands]);
  149.                     }
  150.                     dst.setPixel(dX, dY, dstPixel);
  151.                 }
  152.             }
  153.         }
  154.  
  155.         return dst;
  156.     }
  157.  
  158.     /**
  159.      * Returns the bounding box of the transformed destination.  Since
  160.      * this is not a geometric operation, the bounding box does not
  161.      * change.
  162.      * The IllegalArgumentException may be thrown if the number of
  163.      * components in the source is incompatible with the matrix.  See
  164.      * the class comments for more details.
  165.      */
  166.     public Rectangle2D getDestBounds (BufferedImage src) {
  167.         return new Rectangle (0, 0,
  168.                   src.getWidth(), src.getHeight());
  169.     }
  170.  
  171.     /**
  172.      * Returns the bounding box of the transformed destination.  Since
  173.      * this is not a geometric operation, the bounding box does not
  174.      * change.
  175.      * The IllegalArgumentException may be thrown if the number of
  176.      * bands in the source is incompatible with the matrix.  See
  177.      * the class comments for more details.
  178.      */
  179.     public Rectangle2D getDestBounds (Raster src) {
  180.     //        return new Rectangle (0, 0,
  181.         //                      src.getWidth(), src.getHeight());
  182.     return src.getBounds();
  183.     }
  184.  
  185.     
  186.     /**
  187.      * Creates an empty destination Raster with the correct size and
  188.      * number of bands.
  189.      * The IllegalArgumentException may be thrown if the number of
  190.      * bands in the source is incompatible with the matrix or if the
  191.      * number of rows in the matrix is not equal to the number of
  192.      * bands in the source image.  See
  193.      * the class comments for more details.
  194.      * @param src       Source Raster for the filter operation
  195.      */
  196.     public WritableRaster createCompatibleDestRaster (Raster src) {
  197.         int nBands = src.getNumBands();
  198.         if ((ncols != nBands) && (ncols != (nBands+1))) {
  199.             throw new IllegalArgumentException("Number of columns in the "+
  200.                                                "matrix ("+ncols+
  201.                                                ") must be equal to the number"+
  202.                                                " of bands ([+1]) in src ("+
  203.                                                nBands+").");
  204.         }
  205.         if (src.getNumBands() == nrows) {
  206.             return src.createCompatibleWritableRaster();
  207.         }
  208.         else {
  209.             throw new IllegalArgumentException("Don't know how to create a "+
  210.                                                " compatible Raster with "+
  211.                                                nrows+" bands.");
  212.         }
  213.     }
  214.  
  215.     /**
  216.      * Returns the location of the destination point given a
  217.      * point in the source image.  If dstPt is non-null, it will
  218.      * be used to hold the return value.  Since this is not a geometric
  219.      * operation, the srcPt will equal the dstPt.
  220.      */
  221.     public Point2D getDestPoint (Point2D srcPt, Point2D dstPt) {
  222.         if (dstPt == null) {
  223.             dstPt = new Point2D.Float();
  224.         }
  225.     dstPt.setLocation(srcPt.getX(), srcPt.getY());
  226.  
  227.         return dstPt;
  228.     }
  229.     
  230. }
  231.