Frames | No Frames |
1: /* Copyright (C) 2004 Free Software Foundation 2: 3: This file is part of GNU Classpath. 4: 5: GNU Classpath is free software; you can redistribute it and/or modify 6: it under the terms of the GNU General Public License as published by 7: the Free Software Foundation; either version 2, or (at your option) 8: any later version. 9: 10: GNU Classpath is distributed in the hope that it will be useful, but 11: WITHOUT ANY WARRANTY; without even the implied warranty of 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13: General Public License for more details. 14: 15: You should have received a copy of the GNU General Public License 16: along with GNU Classpath; see the file COPYING. If not, write to the 17: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18: 02110-1301 USA. 19: 20: Linking this library statically or dynamically with other modules is 21: making a combined work based on this library. Thus, the terms and 22: conditions of the GNU General Public License cover the whole 23: combination. 24: 25: As a special exception, the copyright holders of this library give you 26: permission to link this library with independent modules to produce an 27: executable, regardless of the license terms of these independent 28: modules, and to copy and distribute the resulting executable under 29: terms of your choice, provided that you also meet, for each linked 30: independent module, the terms and conditions of the license of that 31: module. An independent module is a module which is not derived from 32: or based on this library. If you modify this library, you may extend 33: this exception to your version of the library, but you are not 34: obligated to do so. If you do not wish to do so, delete this 35: exception statement from your version. */ 36: 37: package java.awt.image; 38: 39: import java.awt.Point; 40: import java.awt.RenderingHints; 41: import java.awt.geom.Point2D; 42: import java.awt.geom.Rectangle2D; 43: 44: /** 45: * Filter Raster pixels by applying a matrix. 46: * 47: * BandCombineOp applies a matrix to each pixel to produce new pixel values. 48: * The width of the matrix must be the same or one more than the number of 49: * bands in the source Raster. If one more, the pixels in the source are 50: * assumed to contain an implicit 1.0 at the end. 51: * 52: * The rows of the matrix are multiplied by the pixel to produce the values 53: * for the destination. Therefore the destination Raster must contain the 54: * same number of bands as the number of rows in the filter matrix. 55: * 56: * @author Jerry Quinn (jlquinn@optonline.net) 57: */ 58: public class BandCombineOp implements RasterOp 59: { 60: private RenderingHints hints; 61: private float[][] matrix; 62: 63: /** 64: * Construct a BandCombineOp. 65: * 66: * @param matrix The matrix to filter pixels with. 67: * @param hints Rendering hints to apply. Ignored. 68: */ 69: public BandCombineOp(float[][] matrix, RenderingHints hints) 70: { 71: this.matrix = matrix; 72: this.hints = hints; 73: } 74: 75: /** 76: * Filter Raster pixels through a matrix. 77: * 78: * Applies the Op matrix to source pixes to produce dest pixels. Each row 79: * of the matrix is multiplied by the src pixel components to produce the 80: * dest pixel. If matrix is one more than the number of bands in the src, 81: * the last element is implicitly multiplied by 1, i.e. added to the sum 82: * for that dest component. 83: * 84: * If dest is null, a suitable Raster is created. This implementation uses 85: * createCompatibleDestRaster. 86: * 87: * @param src The source Raster. 88: * @param dest The destination Raster, or null. 89: * @returns The destination Raster or an allocated Raster. 90: * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, 91: *java.awt.image.WritableRaster) 92: */ 93: public WritableRaster filter(Raster src, WritableRaster dest) { 94: if (dest == null) 95: dest = createCompatibleDestRaster(src); 96: 97: // Filter the pixels 98: float[] spix = new float[matrix[0].length]; 99: float[] dpix = new float[matrix.length]; 100: for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++) 101: for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++) 102: { 103: // In case matrix rows have implicit translation 104: spix[spix.length - 1] = 1.0f; 105: src.getPixel(x, y, spix); 106: for (int i = 0; i < matrix.length; i++) 107: { 108: dpix[i] = 0; 109: for (int j = 0; j < matrix[0].length; j++) 110: dpix[i] += spix[j] * matrix[i][j]; 111: } 112: dest.setPixel(x, y, dpix); 113: } 114: 115: return dest; 116: } 117: 118: /* (non-Javadoc) 119: * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster) 120: */ 121: public final Rectangle2D getBounds2D(Raster src) 122: { 123: return src.getBounds(); 124: } 125: 126: /** 127: * Creates a new WritableRaster that can be used as the destination for this 128: * Op. This implementation creates a Banded Raster with data type FLOAT. 129: * @see 130: *java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster) 131: */ 132: public WritableRaster createCompatibleDestRaster(Raster src) 133: { 134: return Raster.createBandedRaster(DataBuffer.TYPE_FLOAT, src.getWidth(), 135: src.getHeight(), matrix.length, 136: new Point(src.getMinX(), src.getMinY())); 137: } 138: 139: /** Return corresponding destination point for source point. 140: * 141: * LookupOp will return the value of src unchanged. 142: * @param src The source point. 143: * @param dst The destination point. 144: * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, 145: *java.awt.geom.Point2D) 146: */ 147: public final Point2D getPoint2D(Point2D src, Point2D dst) 148: { 149: if (dst == null) return (Point2D)src.clone(); 150: dst.setLocation(src); 151: return dst; 152: } 153: 154: /* (non-Javadoc) 155: * @see java.awt.image.RasterOp#getRenderingHints() 156: */ 157: public final RenderingHints getRenderingHints() 158: { 159: return hints; 160: } 161: 162: /** Return the matrix for this Op. */ 163: public final float[][] getMatrix() 164: { 165: return matrix; 166: } 167: 168: }