KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > image > BufferedImageFilter


1 /*
2  * @(#)BufferedImageFilter.java 1.30 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.image;
9
10 import java.util.Hashtable JavaDoc;
11 import java.awt.image.ImageConsumer JavaDoc;
12 import java.awt.image.ImageFilter JavaDoc;
13
14 /**
15  * The <code>BufferedImageFilter</code> class subclasses an
16  * <code>ImageFilter</code> to provide a simple means of
17  * using a single-source/single-destination image operator
18  * ({@link BufferedImageOp}) to filter a <code>BufferedImage</code>
19  * in the Image Producer/Consumer/Observer
20  * paradigm. Examples of these image operators are: {@link ConvolveOp},
21  * {@link AffineTransformOp} and {@link LookupOp}.
22  *
23  * @see ImageFilter
24  * @see BufferedImage
25  * @see BufferedImageOp
26  * @version 10 Feb 1997
27  */

28
29 public class BufferedImageFilter extends ImageFilter JavaDoc implements Cloneable JavaDoc {
30     BufferedImageOp JavaDoc bufferedImageOp;
31     ColorModel JavaDoc model;
32     int width;
33     int height;
34     byte[] bytePixels;
35     int[] intPixels;
36
37     /**
38      * Constructs a <code>BufferedImageFilter</code> with the
39      * specified single-source/single-destination operator.
40      * @param op the specified <code>BufferedImageOp</code> to
41      * use to filter a <code>BufferedImage</code>
42      * @throws NullPointerException if op is null
43      */

44     public BufferedImageFilter (BufferedImageOp JavaDoc op) {
45         super();
46         if (op == null) {
47             throw new NullPointerException JavaDoc("Operation cannot be null");
48         }
49         bufferedImageOp = op;
50     }
51
52     /**
53      * Returns the <code>BufferedImageOp</code>.
54      * @return the operator of this <code>BufferedImageFilter</code>.
55      */

56     public BufferedImageOp JavaDoc getBufferedImageOp() {
57         return bufferedImageOp;
58     }
59
60     /**
61      * Filters the information provided in the
62      * {@link ImageConsumer#setDimensions(int, int) setDimensions } method
63      * of the {@link ImageConsumer} interface.
64      * <p>
65      * Note: This method is intended to be called by the
66      * {@link ImageProducer} of the <code>Image</code> whose pixels are
67      * being filtered. Developers using this class to retrieve pixels from
68      * an image should avoid calling this method directly since that
69      * operation could result in problems with retrieving the requested
70      * pixels.
71      * <p>
72      * @param width the width to which to set the width of this
73      * <code>BufferedImageFilter</code>
74      * @param height the height to which to set the height of this
75      * <code>BufferedImageFilter</code>
76      * @see ImageConsumer#setDimensions
77      */

78     public void setDimensions(int width, int height) {
79         if (width <= 0 || height <= 0) {
80             imageComplete(STATICIMAGEDONE);
81             return;
82         }
83         this.width = width;
84         this.height = height;
85     }
86
87     /**
88      * Filters the information provided in the
89      * {@link ImageConsumer#setColorModel(ColorModel) setColorModel} method
90      * of the <code>ImageConsumer</code> interface.
91      * <p>
92      * If <code>model</code> is <code>null</code>, this
93      * method clears the current <code>ColorModel</code> of this
94      * <code>BufferedImageFilter</code>.
95      * <p>
96      * Note: This method is intended to be called by the
97      * <code>ImageProducer</code> of the <code>Image</code>
98      * whose pixels are being filtered. Developers using this
99      * class to retrieve pixels from an image
100      * should avoid calling this method directly since that
101      * operation could result in problems with retrieving the
102      * requested pixels.
103      * @param model the {@link ColorModel} to which to set the
104      * <code>ColorModel</code> of this <code>BufferedImageFilter</code>
105      * @see ImageConsumer#setColorModel
106      */

107     public void setColorModel(ColorModel JavaDoc model) {
108         this.model = model;
109     }
110
111     private void convertToRGB() {
112     int size = width * height;
113     int newpixels[] = new int[size];
114     if (bytePixels != null) {
115         for (int i = 0; i < size; i++) {
116         newpixels[i] = this.model.getRGB(bytePixels[i] & 0xff);
117         }
118     } else if (intPixels != null) {
119         for (int i = 0; i < size; i++) {
120         newpixels[i] = this.model.getRGB(intPixels[i]);
121         }
122     }
123     bytePixels = null;
124     intPixels = newpixels;
125     this.model = ColorModel.getRGBdefault();
126     }
127
128     /**
129      * Filters the information provided in the <code>setPixels</code>
130      * method of the <code>ImageConsumer</code> interface which takes
131      * an array of bytes.
132      * <p>
133      * Note: This method is intended to be called by the
134      * <code>ImageProducer</code> of the <code>Image</code> whose pixels
135      * are being filtered. Developers using
136      * this class to retrieve pixels from an image should avoid calling
137      * this method directly since that operation could result in problems
138      * with retrieving the requested pixels.
139      * @throws IllegalArgumentException if width or height are less than
140      * zero.
141      * @see ImageConsumer#setPixels(int, int, int, int, ColorModel, byte[],
142                                     int, int)
143      */

144     public void setPixels(int x, int y, int w, int h,
145               ColorModel JavaDoc model, byte pixels[], int off,
146               int scansize) {
147         // Fix 4184230
148
if (w < 0 || h < 0) {
149             throw new IllegalArgumentException JavaDoc("Width ("+w+
150                                                 ") and height ("+h+
151                                                 ") must be > 0");
152         }
153         // Nothing to do
154
if (w == 0 || h == 0) {
155             return;
156         }
157     if (y < 0) {
158         int diff = -y;
159         if (diff >= h) {
160         return;
161         }
162         off += scansize * diff;
163         y += diff;
164         h -= diff;
165     }
166     if (y + h > height) {
167         h = height - y;
168         if (h <= 0) {
169         return;
170         }
171     }
172     if (x < 0) {
173         int diff = -x;
174         if (diff >= w) {
175         return;
176         }
177         off += diff;
178         x += diff;
179         w -= diff;
180     }
181     if (x + w > width) {
182         w = width - x;
183         if (w <= 0) {
184         return;
185         }
186     }
187     int dstPtr = y*width + x;
188     if (intPixels == null) {
189         if (bytePixels == null) {
190         bytePixels = new byte[width*height];
191         this.model = model;
192         } else if (this.model != model) {
193         convertToRGB();
194         }
195         if (bytePixels != null) {
196         for (int sh = h; sh > 0; sh--) {
197             System.arraycopy(pixels, off, bytePixels, dstPtr, w);
198             off += scansize;
199             dstPtr += width;
200         }
201         }
202     }
203     if (intPixels != null) {
204         int dstRem = width - w;
205         int srcRem = scansize - w;
206         for (int sh = h; sh > 0; sh--) {
207         for (int sw = w; sw > 0; sw--) {
208             intPixels[dstPtr++] = model.getRGB(pixels[off++]&0xff);
209         }
210         off += srcRem;
211         dstPtr += dstRem;
212         }
213     }
214     }
215     /**
216      * Filters the information provided in the <code>setPixels</code>
217      * method of the <code>ImageConsumer</code> interface which takes
218      * an array of integers.
219      * <p>
220      * Note: This method is intended to be called by the
221      * <code>ImageProducer</code> of the <code>Image</code> whose
222      * pixels are being filtered. Developers using this class to
223      * retrieve pixels from an image should avoid calling this method
224      * directly since that operation could result in problems
225      * with retrieving the requested pixels.
226      * @throws IllegalArgumentException if width or height are less than
227      * zero.
228      * @see ImageConsumer#setPixels(int, int, int, int, ColorModel, int[],
229                                     int, int)
230      */

231     public void setPixels(int x, int y, int w, int h,
232               ColorModel JavaDoc model, int pixels[], int off,
233               int scansize) {
234         // Fix 4184230
235
if (w < 0 || h < 0) {
236             throw new IllegalArgumentException JavaDoc("Width ("+w+
237                                                 ") and height ("+h+
238                                                 ") must be > 0");
239         }
240         // Nothing to do
241
if (w == 0 || h == 0) {
242             return;
243         }
244     if (y < 0) {
245         int diff = -y;
246         if (diff >= h) {
247         return;
248         }
249         off += scansize * diff;
250         y += diff;
251         h -= diff;
252     }
253     if (y + h > height) {
254         h = height - y;
255         if (h <= 0) {
256         return;
257         }
258     }
259     if (x < 0) {
260         int diff = -x;
261         if (diff >= w) {
262         return;
263         }
264         off += diff;
265         x += diff;
266         w -= diff;
267     }
268     if (x + w > width) {
269         w = width - x;
270         if (w <= 0) {
271         return;
272         }
273     }
274
275     if (intPixels == null) {
276         if (bytePixels == null) {
277         intPixels = new int[width * height];
278         this.model = model;
279         } else {
280         convertToRGB();
281         }
282     }
283     int dstPtr = y*width + x;
284     if (this.model == model) {
285         for (int sh = h; sh > 0; sh--) {
286         System.arraycopy(pixels, off, intPixels, dstPtr, w);
287         off += scansize;
288         dstPtr += width;
289         }
290     } else {
291         if (this.model != ColorModel.getRGBdefault()) {
292         convertToRGB();
293         }
294         int dstRem = width - w;
295         int srcRem = scansize - w;
296         for (int sh = h; sh > 0; sh--) {
297         for (int sw = w; sw > 0; sw--) {
298             intPixels[dstPtr++] = model.getRGB(pixels[off++]);
299         }
300         off += srcRem;
301         dstPtr += dstRem;
302         }
303     }
304     }
305
306     /**
307      * Filters the information provided in the <code>imageComplete</code>
308      * method of the <code>ImageConsumer</code> interface.
309      * <p>
310      * Note: This method is intended to be called by the
311      * <code>ImageProducer</code> of the <code>Image</code> whose pixels
312      * are being filtered. Developers using
313      * this class to retrieve pixels from an image should avoid calling
314      * this method directly since that operation could result in problems
315      * with retrieving the requested pixels.
316      * @param status the status of image loading
317      * @throws ImagingOpException if there was a problem calling the filter
318      * method of the <code>BufferedImageOp</code> associated with this
319      * instance.
320      * @see ImageConsumer#imageComplete
321      */

322     public void imageComplete(int status) {
323         WritableRaster JavaDoc wr;
324         switch(status) {
325         case IMAGEERROR:
326         case IMAGEABORTED:
327             // reinitialize the params
328
model = null;
329             width = -1;
330             height = -1;
331             intPixels = null;
332             bytePixels = null;
333             break;
334
335         case SINGLEFRAMEDONE:
336         case STATICIMAGEDONE:
337             if (width <= 0 || height <= 0) break;
338             if (model instanceof DirectColorModel JavaDoc) {
339                 if (intPixels == null) break;
340                 wr = createDCMraster();
341             }
342             else if (model instanceof IndexColorModel JavaDoc) {
343                 int[] bandOffsets = {0};
344                 if (bytePixels == null) break;
345                 DataBufferByte JavaDoc db = new DataBufferByte JavaDoc(bytePixels,
346                                                        width*height);
347                 wr = Raster.createInterleavedRaster(db, width, height, width,
348                                                     1, bandOffsets, null);
349             }
350             else {
351                 convertToRGB();
352                 if (intPixels == null) break;
353                 wr = createDCMraster();
354             }
355             BufferedImage JavaDoc bi = new BufferedImage JavaDoc(model, wr,
356                                                  model.isAlphaPremultiplied(),
357                                                  null);
358             bi = bufferedImageOp.filter(bi, null);
359             WritableRaster JavaDoc r = bi.getRaster();
360             ColorModel JavaDoc cm = bi.getColorModel();
361             int w = r.getWidth();
362             int h = r.getHeight();
363             consumer.setDimensions(w, h);
364             consumer.setColorModel(cm);
365             if (cm instanceof DirectColorModel JavaDoc) {
366                 DataBufferInt JavaDoc db = (DataBufferInt JavaDoc) r.getDataBuffer();
367                 consumer.setPixels(0, 0, w, h,
368                                    cm, db.getData(), 0, w);
369             }
370             else if (cm instanceof IndexColorModel JavaDoc) {
371                 DataBufferByte JavaDoc db = (DataBufferByte JavaDoc) r.getDataBuffer();
372                 consumer.setPixels(0, 0, w, h,
373                                    cm, db.getData(), 0, w);
374             }
375             else {
376                 throw new InternalError JavaDoc("Unknown color model "+cm);
377             }
378             break;
379         }
380     consumer.imageComplete(status);
381     }
382
383     private final WritableRaster JavaDoc createDCMraster() {
384         WritableRaster JavaDoc wr;
385         DirectColorModel JavaDoc dcm = (DirectColorModel JavaDoc) model;
386         boolean hasAlpha = model.hasAlpha();
387         int[] bandMasks = new int[3+(hasAlpha ? 1 : 0)];
388         bandMasks[0] = dcm.getRedMask();
389         bandMasks[1] = dcm.getGreenMask();
390         bandMasks[2] = dcm.getBlueMask();
391         if (hasAlpha) {
392             bandMasks[3] = dcm.getAlphaMask();
393         }
394         DataBufferInt JavaDoc db = new DataBufferInt JavaDoc(intPixels, width*height);
395         wr = Raster.createPackedRaster(db, width, height, width,
396                                        bandMasks, null);
397         return wr;
398     }
399
400 }
401
Popular Tags