Frames | No Frames |
1: /* ReplicateScaleFilter.java -- Java class for filtering images 2: Copyright (C) 1999 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.awt.image; 40: 41: import java.util.Hashtable; 42: 43: /** 44: * This filter should be used for fast scaling of images where the result 45: * does not need to ensure straight lines are still straight, etc. The 46: * exact method is not defined by Sun but some sort of fast Box filter should 47: * probably be correct. 48: * <br> 49: * 50: * @author C. Brian Jones (cbj@gnu.org) 51: */ 52: public class ReplicateScaleFilter extends ImageFilter 53: { 54: public ReplicateScaleFilter(int width, int height) { 55: destHeight = height; 56: destWidth = width; 57: } 58: 59: /** 60: * The height of the destination image. 61: */ 62: protected int destHeight; 63: 64: /** 65: * The width of the destination image. 66: */ 67: protected int destWidth; 68: 69: /** 70: * The height of the source image. 71: */ 72: protected int srcHeight; 73: 74: /** 75: * The width of the source image. 76: */ 77: protected int srcWidth; 78: 79: /** 80: * 81: */ 82: protected int srcrows[]; 83: 84: /** 85: * 86: */ 87: protected int srccols[]; 88: 89: /** 90: * 91: */ 92: protected Object outpixbuf; 93: 94: /** 95: * An <code>ImageProducer</code> indicates the size of the image 96: * being produced using this method. A filter can override this 97: * method to intercept these calls from the producer in order to 98: * change either the width or the height before in turn calling 99: * the consumer's <code>setDimensions</code> method. 100: * 101: * @param width the width of the image 102: * @param height the height of the image 103: */ 104: public void setDimensions(int width, int height) 105: { 106: srcWidth = width; 107: srcHeight = height; 108: 109: /* If either destHeight or destWidth is < 0, the image should 110: maintain its original aspect ratio. When both are < 0, 111: just maintain the original width and height. */ 112: if (destWidth < 0 && destHeight < 0) 113: { 114: destWidth = width; 115: destHeight = height; 116: } 117: else if (destWidth < 0) 118: { 119: destWidth = (int) (width * ((double) destHeight / srcHeight)); 120: } 121: else if (destHeight < 0) 122: { 123: destHeight = (int) (height * ((double) destWidth / srcWidth)); 124: } 125: 126: if (consumer != null) 127: consumer.setDimensions(destWidth, destHeight); 128: } 129: 130: /** 131: * An <code>ImageProducer</code> can set a list of properties 132: * associated with this image by using this method. 133: * 134: * @param props the list of properties associated with this image 135: */ 136: public void setProperties(Hashtable props) 137: { 138: props.put("filters", "ReplicateScaleFilter"); 139: if (consumer != null) 140: consumer.setProperties(props); 141: } 142: 143: /** 144: * This function delivers a rectangle of pixels where any 145: * pixel(m,n) is stored in the array as a <code>byte</code> at 146: * index (n * scansize + m + offset). 147: * 148: * @param x the x coordinate of the rectangle 149: * @param y the y coordinate of the rectangle 150: * @param w the width of the rectangle 151: * @param h the height of the rectangle 152: * @param model the <code>ColorModel</code> used to translate the pixels 153: * @param pixels the array of pixel values 154: * @param offset the index of the first pixels in the <code>pixels</code> array 155: * @param scansize the width to use in extracting pixels from the <code>pixels</code> array 156: */ 157: public void setPixels(int x, int y, int w, int h, 158: ColorModel model, byte[] pixels, int offset, int scansize) 159: { 160: double rx = ((double) srcWidth) / destWidth; 161: double ry = ((double) srcHeight) / destHeight; 162: 163: int destScansize = (int) Math.round(scansize / rx); 164: 165: byte[] destPixels = replicatePixels(x, y, w, h, 166: model, pixels, offset, scansize, 167: rx, ry, destScansize); 168: 169: if (consumer != null) 170: consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), 171: (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), 172: model, destPixels, 0, destScansize); 173: } 174: 175: /** 176: * This function delivers a rectangle of pixels where any 177: * pixel(m,n) is stored in the array as an <code>int</code> at 178: * index (n * scansize + m + offset). 179: * 180: * @param x the x coordinate of the rectangle 181: * @param y the y coordinate of the rectangle 182: * @param w the width of the rectangle 183: * @param h the height of the rectangle 184: * @param model the <code>ColorModel</code> used to translate the pixels 185: * @param pixels the array of pixel values 186: * @param offset the index of the first pixels in the <code>pixels</code> array 187: * @param scansize the width to use in extracting pixels from the <code>pixels</code> array 188: */ 189: public void setPixels(int x, int y, int w, int h, 190: ColorModel model, int[] pixels, int offset, int scansize) 191: { 192: double rx = ((double) srcWidth) / destWidth; 193: double ry = ((double) srcHeight) / destHeight; 194: 195: int destScansize = (int) Math.round(scansize / rx); 196: 197: int[] destPixels = replicatePixels(x, y, w, h, 198: model, pixels, offset, scansize, 199: rx, ry, destScansize); 200: 201: if (consumer != null) 202: consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry), 203: (int) Math.ceil(w/rx), (int) Math.ceil(h/ry), 204: model, destPixels, 0, destScansize); 205: } 206: 207: private byte[] replicatePixels(int srcx, int srcy, int srcw, int srch, 208: ColorModel model, byte[] srcPixels, 209: int srcOffset, int srcScansize, 210: double rx, double ry, int destScansize) 211: { 212: byte[] destPixels = 213: new byte[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)]; 214: 215: int a, b; 216: for (int i = 0; i < destPixels.length; i++) 217: { 218: a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize; 219: b = (int) ((i % destScansize) * rx); 220: if ((a + b + srcOffset) < srcPixels.length) 221: destPixels[i] = srcPixels[a + b + srcOffset]; 222: } 223: 224: return destPixels; 225: } 226: 227: private int[] replicatePixels(int srcx, int srcy, int srcw, int srch, 228: ColorModel model, int[] srcPixels, 229: int srcOffset, int srcScansize, 230: double rx, double ry, int destScansize) 231: { 232: int[] destPixels = 233: new int[(int) Math.ceil(srcw/rx) * (int) Math.ceil(srch/ry)]; 234: 235: int a, b; 236: for (int i = 0; i < destPixels.length; i++) 237: { 238: a = (int) ((int) ( ((double) i) / destScansize) * ry) * srcScansize; 239: b = (int) ((i % destScansize) * rx); 240: if ((a + b + srcOffset) < srcPixels.length) 241: destPixels[i] = srcPixels[a + b + srcOffset]; 242: } 243: 244: return destPixels; 245: } 246: }