001 /* ReplicateScaleFilter.java -- Java class for filtering images
002 Copyright (C) 1999 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package java.awt.image;
040
041 import 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 */
053 public 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 }