Reset branch to trunk.
[official-gcc.git] / trunk / libjava / classpath / java / awt / image / AreaAveragingScaleFilter.java
blob491a2f519034430665944d3238c293cffbc76af5
1 /* AreaAveragingScaleFilter.java -- Java class for filtering images
2 Copyright (C) 1999,2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package java.awt.image;
41 /**
42 * This filter should produce images which do not have image artifacts
43 * like broken lines which were originally unbroken. The cost is of
44 * course speed. Using bi-linear interpolation here against 4 pixel
45 * points should give the desired results although Sun does not
46 * specify what the exact algorithm should be.
47 * <br>
49 * @author C. Brian Jones (cbj@gnu.org)
51 public class AreaAveragingScaleFilter extends ReplicateScaleFilter
53 /**
54 * Construct an instance of <code>AreaAveragingScaleFilter</code> which
55 * should be used in conjunction with a <code>FilteredImageSource</code>
56 * object.
58 * @param width the width of the destination image
59 * @param height the height of the destination image
61 public AreaAveragingScaleFilter(int width, int height) {
62 super(width, height);
65 /**
66 * The <code>ImageProducer</code> should call this method with a
67 * bit mask of hints from any of <code>RANDOMPIXELORDER</code>,
68 * <code>TOPDOWNLEFTRIGHT</code>, <code>COMPLETESCANLINES</code>,
69 * <code>SINGLEPASS</code>, <code>SINGLEFRAME</code> from the
70 * <code>ImageConsumer</code> interface.
71 * <br>
72 * FIXME - more than likely Sun's implementation desires
73 * <code>TOPDOWNLEFTRIGHT</code> order and this method is overloaded here
74 * in order to assure that mask is part of the hints added to
75 * the consumer.
77 * @param flags a bit mask of hints
78 * @see ImageConsumer
80 public void setHints(int flags)
82 if (consumer != null)
83 consumer.setHints(flags);
86 /**
87 * This function delivers a rectangle of pixels where any
88 * pixel(m,n) is stored in the array as a <code>byte</code> at
89 * index (n * scansize + m + offset).
91 * @param x the x coordinate of the rectangle
92 * @param y the y coordinate of the rectangle
93 * @param w the width of the rectangle
94 * @param h the height of the rectangle
95 * @param model the <code>ColorModel</code> used to translate the pixels
96 * @param pixels the array of pixel values
97 * @param offset the index of the first pixels in the <code>pixels</code> array
98 * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
100 public void setPixels(int x, int y, int w, int h,
101 ColorModel model, byte[] pixels, int offset, int scansize)
103 double rx = ((double) srcWidth) / destWidth;
104 double ry = ((double) srcHeight) / destHeight;
106 int destScansize = (int) Math.round(scansize / rx);
108 byte[] destPixels = averagePixels(x, y, w, h,
109 model, pixels, offset, scansize,
110 rx, ry, destScansize);
112 if (consumer != null)
113 consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
114 (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
115 model, destPixels, 0, destScansize);
119 * This function delivers a rectangle of pixels where any
120 * pixel(m,n) is stored in the array as an <code>int</code> at
121 * index (n * scansize + m + offset).
123 * @param x the x coordinate of the rectangle
124 * @param y the y coordinate of the rectangle
125 * @param w the width of the rectangle
126 * @param h the height of the rectangle
127 * @param model the <code>ColorModel</code> used to translate the pixels
128 * @param pixels the array of pixel values
129 * @param offset the index of the first pixels in the <code>pixels</code> array
130 * @param scansize the width to use in extracting pixels from the <code>pixels</code> array
132 public void setPixels(int x, int y, int w, int h,
133 ColorModel model, int[] pixels, int offset, int scansize)
135 double rx = ((double) srcWidth) / destWidth;
136 double ry = ((double) srcHeight) / destHeight;
138 int destScansize = (int) Math.round(scansize / rx);
140 int[] destPixels = averagePixels(x, y, w, h,
141 model, pixels, offset, scansize,
142 rx, ry, destScansize);
144 if (consumer != null)
145 consumer.setPixels((int) Math.floor(x/rx), (int) Math.floor(y/ry),
146 (int) Math.ceil(w/rx), (int) Math.ceil(h/ry),
147 model, destPixels, 0, destScansize);
151 * This is a really terrible implementation,
152 * since it uses the nearest-neighbor method. This filter is rarely used though.
154 * @param srcx, srcy - Source rectangle upper-left corner
155 * @param srcw, srch - Source rectangle width and height
156 * @param model - Pixel color model
157 * @param srcPixels - Source pixel data.
158 * @param srcOffset - Starting offset into the source pixel data array.
159 * @param srcScansize - Source array scanline size.
160 * @param rx,ry - Scaling factor.
161 * @param destScansize - Destination array scanline size.
163 private byte[] averagePixels(int srcx, int srcy, int srcw, int srch,
164 ColorModel model, byte[] srcPixels,
165 int srcOffset, int srcScansize,
166 double rx, double ry, int destScansize)
168 int destW = (int) Math.ceil(srcw/rx);
169 int destH = (int) Math.ceil(srch/ry);
170 byte[] destPixels = new byte[ destW * destH ];
171 int sx, sy;
173 int w = (int)Math.ceil(rx);
174 int h = (int)Math.ceil(ry);
176 for(int x = 0; x < destW; x++)
177 for(int y = 0; y < destH; y++)
179 sx = (int) (x * rx);
180 sy = (int) (y * ry);
182 int r,g,b,a;
183 r = g = b = a = 0;
185 for(int i = 0; i < w; i++)
187 for(int j = 0; j < h; j++)
189 int idx = srcx + sx + i + (srcy + sy + j)*srcScansize;
190 r += model.getRed(srcPixels[ idx ]);
191 g += model.getGreen(srcPixels[ idx ]);
192 b += model.getBlue(srcPixels[ idx ]);
193 a += model.getAlpha(srcPixels[ idx ]);
197 r = r / (w * h);
198 g = g / (w * h);
199 b = b / (w * h);
200 a = a / (w * h);
202 // Does this really work?
203 destPixels[x + destScansize*y] = (byte)model.getDataElement
204 (new int[]{r, g, b, a}, 0);
207 return destPixels;
211 * This is a really terrible implementation,
212 * since it uses the nearest-neighbor method. This filter is rarely used though.
214 * @param srcx, srcy - Source rectangle upper-left corner
215 * @param srcw, srch - Source rectangle width and height
216 * @param model - Pixel color model
217 * @param srcPixels - Source pixel data.
218 * @param srcOffset - Starting offset into the source pixel data array.
219 * @param srcScansize - Source array scanline size.
220 * @param rx,ry - Scaling factor.
221 * @param destScansize - Destination array scanline size.
223 private int[] averagePixels(int srcx, int srcy, int srcw, int srch,
224 ColorModel model, int[] srcPixels,
225 int srcOffset, int srcScansize,
226 double rx, double ry, int destScansize)
228 int destW = (int) Math.ceil(srcw/rx);
229 int destH = (int) Math.ceil(srch/ry);
230 int[] destPixels = new int[ destW * destH ];
231 int sx, sy;
233 int w = (int)Math.ceil(rx);
234 int h = (int)Math.ceil(ry);
236 for(int x = 0; x < destW; x++)
237 for(int y = 0; y < destH; y++)
239 sx = (int) (x * rx);
240 sy = (int) (y * ry);
242 int r,g,b,a;
243 r = g = b = a = 0;
245 for(int i = 0; i < w; i++)
247 for(int j = 0; j < h; j++)
249 int idx = srcx + sx + i + (srcy + sy + j)*srcScansize;
250 r += model.getRed(srcPixels[ idx ]);
251 g += model.getGreen(srcPixels[ idx ]);
252 b += model.getBlue(srcPixels[ idx ]);
253 a += model.getAlpha(srcPixels[ idx ]);
257 r = r / (w * h);
258 g = g / (w * h);
259 b = b / (w * h);
260 a = a / (w * h);
262 destPixels[x + destScansize*y] = model.getDataElement
263 (new int[]{r, g, b, a}, 0);
266 return destPixels;