001/* ReplicateScaleFilter.java -- Java class for filtering images 002 Copyright (C) 1999 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.awt.image; 040 041import java.util.Hashtable; 042 043/** 044 * This filter should be used for fast scaling of images where the result 045 * does not need to ensure straight lines are still straight, etc. The 046 * exact method is not defined by Sun but some sort of fast Box filter should 047 * probably be correct. 048 * <br> 049 * Currently this filter does nothing and needs to be implemented. 050 * 051 * @author C. Brian Jones (cbj@gnu.org) 052 */ 053public class ReplicateScaleFilter extends ImageFilter 054{ 055 public ReplicateScaleFilter(int width, int height) { 056 destHeight = height; 057 destWidth = width; 058 } 059 060 /** 061 * The height of the destination image. 062 */ 063 protected int destHeight; 064 065 /** 066 * The width of the destination image. 067 */ 068 protected int destWidth; 069 070 /** 071 * The height of the source image. 072 */ 073 protected int srcHeight; 074 075 /** 076 * The width of the source image. 077 */ 078 protected int srcWidth; 079 080 /** 081 * 082 */ 083 protected int srcrows[]; 084 085 /** 086 * 087 */ 088 protected int srccols[]; 089 090 /** 091 * 092 */ 093 protected Object outpixbuf; 094 095 /** 096 * An <code>ImageProducer</code> indicates the size of the image 097 * being produced using this method. A filter can override this 098 * method to intercept these calls from the producer in order to 099 * change either the width or the height before in turn calling 100 * the consumer's <code>setDimensions</code> method. 101 * 102 * @param width the width of the image 103 * @param height the height of the image 104 */ 105 public void setDimensions(int width, int height) 106 { 107 srcWidth = width; 108 srcHeight = height; 109 110 /* If either destHeight or destWidth is < 0, the image should 111 maintain its original aspect ratio. When both are < 0, 112 just maintain the original width and height. */ 113 if (destWidth < 0 && destHeight < 0) 114 { 115 destWidth = width; 116 destHeight = height; 117 } 118 else if (destWidth < 0) 119 { 120 destWidth = width * destHeight / srcHeight; 121 } 122 else if (destHeight < 0) 123 { 124 destHeight = height * destWidth / srcWidth; 125 } 126 127 if (consumer != null) 128 consumer.setDimensions(destWidth, destHeight); 129 } 130 131 /** 132 * An <code>ImageProducer</code> can set a list of properties 133 * associated with this image by using this method. 134 * 135 * @param props the list of properties associated with this image 136 */ 137 public void setProperties(Hashtable<?, ?> props) 138 { 139 Hashtable<Object, Object> prop2 = (Hashtable<Object, Object>) props; 140 prop2.put("filters", "ReplicateScaleFilter"); 141 if (consumer != null) 142 consumer.setProperties(prop2); 143 } 144 145 /** 146 * This function delivers a rectangle of pixels where any 147 * pixel(m,n) is stored in the array as a <code>byte</code> at 148 * index (n * scansize + m + offset). 149 * 150 * @param x the x coordinate of the rectangle 151 * @param y the y coordinate of the rectangle 152 * @param w the width of the rectangle 153 * @param h the height of the rectangle 154 * @param model the <code>ColorModel</code> used to translate the pixels 155 * @param pixels the array of pixel values 156 * @param offset the index of the first pixels in the <code>pixels</code> array 157 * @param scansize the width to use in extracting pixels from the <code>pixels</code> array 158 */ 159 public void setPixels(int x, int y, int w, int h, 160 ColorModel model, byte[] pixels, int offset, int scansize) 161 { 162 if (srcrows == null || srccols == null) 163 setupSources(); 164 int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth); 165 int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight); 166 byte[] pix; 167 if (outpixbuf != null && outpixbuf instanceof byte[]) 168 { 169 pix = (byte[]) outpixbuf; 170 } 171 else 172 { 173 pix = new byte[destWidth]; 174 outpixbuf = pix; 175 } 176 int sy, sx; 177 for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++) 178 { 179 int offs = offset + scansize * (sy - y); 180 int xx; 181 for (xx = dx1; (sx = srccols[xx]) < x + w; xx++) 182 { 183 pix[xx] = pixels[offs + sx - x]; 184 } 185 if (xx > dx1) 186 { 187 consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1, 188 destWidth); 189 } 190 } 191 } 192 193 /** 194 * This function delivers a rectangle of pixels where any 195 * pixel(m,n) is stored in the array as an <code>int</code> at 196 * index (n * scansize + m + offset). 197 * 198 * @param x the x coordinate of the rectangle 199 * @param y the y coordinate of the rectangle 200 * @param w the width of the rectangle 201 * @param h the height of the rectangle 202 * @param model the <code>ColorModel</code> used to translate the pixels 203 * @param pixels the array of pixel values 204 * @param offset the index of the first pixels in the <code>pixels</code> array 205 * @param scansize the width to use in extracting pixels from the <code>pixels</code> array 206 */ 207 public void setPixels(int x, int y, int w, int h, 208 ColorModel model, int[] pixels, int offset, int scansize) 209 { 210 if (srcrows == null || srccols == null) 211 setupSources(); 212 int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * destWidth); 213 int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * destHeight); 214 int[] pix; 215 if (outpixbuf != null && outpixbuf instanceof int[]) 216 { 217 pix = (int[]) outpixbuf; 218 } 219 else 220 { 221 pix = new int[destWidth]; 222 outpixbuf = pix; 223 } 224 int sy, sx; 225 for (int yy = dy1; (sy = srcrows[yy]) < y + h; yy++) 226 { 227 int offs = offset + scansize * (sy - y); 228 int xx; 229 for (xx = dx1; (sx = srccols[xx]) < x + w; xx++) 230 { 231 pix[xx] = pixels[offs + sx - x]; 232 } 233 if (xx > dx1) 234 { 235 consumer.setPixels(dx1, yy, xx - dx1, 1, model, pix, dx1, 236 destWidth); 237 } 238 } 239 } 240 241 /** 242 * Sets up the srcrows and srccols arrays. 243 */ 244 private void setupSources() 245 { 246 srcrows = new int[destHeight + 1]; 247 for (int y = 0; y <= destHeight; y++) 248 { 249 srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight); 250 } 251 srccols = new int[destWidth + 1]; 252 for (int x = 0; x <= destWidth; x++) 253 { 254 srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth); 255 } 256 } 257}