001    /* Copyright (C) 2000, 2002, 2003, 2006,  Free Software Foundation
002    
003    This file is part of GNU Classpath.
004    
005    GNU Classpath is free software; you can redistribute it and/or modify
006    it under the terms of the GNU General Public License as published by
007    the Free Software Foundation; either version 2, or (at your option)
008    any later version.
009    
010    GNU Classpath is distributed in the hope that it will be useful, but
011    WITHOUT ANY WARRANTY; without even the implied warranty of
012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013    General Public License for more details.
014    
015    You should have received a copy of the GNU General Public License
016    along with GNU Classpath; see the file COPYING.  If not, write to the
017    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
018    02110-1301 USA.
019    
020    Linking this library statically or dynamically with other modules is
021    making a combined work based on this library.  Thus, the terms and
022    conditions of the GNU General Public License cover the whole
023    combination.
024    
025    As a special exception, the copyright holders of this library give you
026    permission to link this library with independent modules to produce an
027    executable, regardless of the license terms of these independent
028    modules, and to copy and distribute the resulting executable under
029    terms of your choice, provided that you also meet, for each linked
030    independent module, the terms and conditions of the license of that
031    module.  An independent module is a module which is not derived from
032    or based on this library.  If you modify this library, you may extend
033    this exception to your version of the library, but you are not
034    obligated to do so.  If you do not wish to do so, delete this
035    exception statement from your version. */
036    
037    
038    package java.awt.image;
039    
040    import java.awt.Point;
041    import java.awt.Rectangle;
042    
043    /**
044     * A raster with methods to support updating pixel values.
045     *
046     * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
047     */
048    public class WritableRaster extends Raster
049    {
050      /**
051       * Creates a new <code>WritableRaster</code>.
052       *
053       * @param sampleModel  the sample model.
054       * @param origin  the origin.
055       */
056      protected WritableRaster(SampleModel sampleModel, Point origin)
057      {
058        this(sampleModel, sampleModel.createDataBuffer(), origin);
059      }
060    
061      /**
062       * Creates a new <code>WritableRaster</code> instance.
063       *
064       * @param sampleModel  the sample model.
065       * @param dataBuffer  the data buffer.
066       * @param origin  the origin.
067       */
068      protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
069                               Point origin)
070      {
071        this(sampleModel, dataBuffer,
072             new Rectangle(origin != null ? origin.x : 0,
073                           origin != null ? origin.y : 0,
074                           sampleModel.getWidth(), sampleModel.getHeight()),
075             origin, null);
076      }
077    
078      /**
079       * Creates a new <code>WritableRaster</code> instance.
080       *
081       * @param sampleModel  the sample model.
082       * @param dataBuffer  the data buffer.
083       * @param aRegion  the raster's bounds.
084       * @param sampleModelTranslate  the translation.
085       * @param parent  the parent.
086       */
087      protected WritableRaster(SampleModel sampleModel,
088                               DataBuffer dataBuffer,
089                               Rectangle aRegion,
090                               Point sampleModelTranslate,
091                               WritableRaster parent)
092      {
093        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
094      }
095    
096      /**
097       * Returns the raster's parent, cast as a {@link WritableRaster}.
098       *
099       * @return The raster's parent.
100       */
101      public WritableRaster getWritableParent()
102      {
103        return (WritableRaster) getParent();
104      }
105    
106      /**
107       * @param childMinX
108       * @param childMinY
109       * @return
110       */
111      public WritableRaster createWritableTranslatedChild(int childMinX,
112                                                          int childMinY)
113      {
114        return createWritableChild(minX, minY, width, height,
115                                   childMinX, childMinY, null);
116      }
117    
118      /**
119       *
120       * @param parentX
121       * @param parentY
122       * @param w
123       * @param h
124       * @param childMinX
125       * @param childMinY
126       * @param bandList
127       * @return
128       */
129      public WritableRaster createWritableChild(int parentX, int parentY,
130          int w, int h, int childMinX, int childMinY, int[] bandList)
131      {
132        // This mirrors the code from the super class
133    
134        if (parentX < minX || parentX + w > minX + width
135            || parentY < minY || parentY + h > minY + height)
136          throw new RasterFormatException("Child raster extends beyond parent");
137    
138        SampleModel sm = (bandList == null) ?
139          sampleModel :
140          sampleModel.createSubsetSampleModel(bandList);
141    
142        return new WritableRaster(sm, getDataBuffer(),
143                                  new Rectangle(childMinX, childMinY, w, h),
144                                  new Point(sampleModelTranslateX + childMinX -
145                                              parentX,
146                                            sampleModelTranslateY + childMinY -
147                                              parentY),
148                                  this);
149      }
150    
151      public Raster createChild(int parentX, int parentY, int width,
152                                int height, int childMinX, int childMinY,
153                                int[] bandList)
154      {
155        if (parentX < minX || parentX + width > minX + this.width
156            || parentY < minY || parentY + height > minY + this.height)
157          throw new RasterFormatException("Child raster extends beyond parent");
158    
159        SampleModel sm = (bandList == null) ?
160          sampleModel :
161          sampleModel.createSubsetSampleModel(bandList);
162    
163        return new WritableRaster(sm, dataBuffer,
164            new Rectangle(childMinX, childMinY, width, height),
165            new Point(sampleModelTranslateX + childMinX - parentX,
166                      sampleModelTranslateY + childMinY - parentY),
167            this);
168      }
169    
170      public void setDataElements(int x, int y, Object inData)
171      {
172        sampleModel.setDataElements(x - sampleModelTranslateX,
173            y - sampleModelTranslateY, inData, dataBuffer);
174      }
175    
176      public void setDataElements(int x, int y, Raster inRaster)
177      {
178        Object dataElements = getDataElements(0, 0, inRaster.getWidth(),
179            inRaster.getHeight(), null);
180        setDataElements(x, y, dataElements);
181      }
182    
183      public void setDataElements(int x, int y, int w, int h, Object inData)
184      {
185        sampleModel.setDataElements(x - sampleModelTranslateX,
186            y - sampleModelTranslateY, w, h, inData, dataBuffer);
187      }
188    
189      /**
190       *
191       * @param srcRaster
192       */
193      public void setRect(Raster srcRaster)
194      {
195        setRect(0, 0, srcRaster);
196      }
197    
198      /**
199       *
200       * @param dx
201       * @param dy
202       * @param srcRaster
203       */
204      public void setRect(int dx, int dy, Raster srcRaster)
205      {
206        Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX() + dx,
207            srcRaster.getMinY() + dy, srcRaster.getWidth(), srcRaster.getHeight());
208    
209        Rectangle target = getBounds().intersection(targetUnclipped);
210    
211        if (target.isEmpty()) return;
212    
213        int sx = target.x - dx;
214        int sy = target.y - dy;
215    
216        // FIXME: Do tests on rasters and use get/set data instead.
217    
218        /* The JDK documentation seems to imply this implementation.
219           (the trucation of higher bits), but an implementation using
220           get/setDataElements would be more efficient. None of the
221           implementations would do anything sensible when the sample
222           models don't match.
223    
224           But this is probably not the place to consider such
225           optimizations.*/
226    
227        int[] pixels = srcRaster.getPixels(sx, sy, target.width, target.height,
228                                           (int[]) null);
229    
230        setPixels(target.x, target.y, target.width, target.height, pixels);
231      }
232    
233      /**
234       * Sets the samples for the pixel at (x, y) in the raster to the specified
235       * values.
236       *
237       * @param x  the x-coordinate of the pixel.
238       * @param y  the y-coordinate of the pixel.
239       * @param iArray  the sample values (<code>null</code> not permitted).
240       *
241       * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
242       */
243      public void setPixel(int x, int y, int[] iArray)
244      {
245        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
246                             iArray, dataBuffer);
247      }
248    
249      /**
250       * Sets the samples for the pixel at (x, y) in the raster to the specified
251       * values.
252       *
253       * @param x  the x-coordinate of the pixel.
254       * @param y  the y-coordinate of the pixel.
255       * @param fArray  the sample values (<code>null</code> not permitted).
256       *
257       * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
258       */
259      public void setPixel(int x, int y, float[] fArray)
260      {
261        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
262                             fArray, dataBuffer);
263      }
264    
265      /**
266       * Sets the samples for the pixel at (x, y) in the raster to the specified
267       * values.
268       *
269       * @param x  the x-coordinate of the pixel.
270       * @param y  the y-coordinate of the pixel.
271       * @param dArray  the sample values (<code>null</code> not permitted).
272       *
273       * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
274       */
275      public void setPixel(int x, int y, double[] dArray)
276      {
277        sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
278                             dArray, dataBuffer);
279      }
280    
281      /**
282       * Sets the sample values for the pixels in the region specified by
283       * (x, y, w, h) in the raster.  The array is ordered by pixels (that is, all
284       * the samples for the first pixel are grouped together, followed by all the
285       * samples for the second pixel, and so on).
286       *
287       * @param x  the x-coordinate of the top-left pixel.
288       * @param y  the y-coordinate of the top-left pixel.
289       * @param w  the width of the region of pixels.
290       * @param h  the height of the region of pixels.
291       * @param iArray  the pixel sample values (<code>null</code> not permitted).
292       *
293       * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
294       */
295      public void setPixels(int x, int y, int w, int h, int[] iArray)
296      {
297        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
298                              w, h, iArray, dataBuffer);
299      }
300    
301      /**
302       * Sets the sample values for the pixels in the region specified by
303       * (x, y, w, h) in the raster.  The array is ordered by pixels (that is, all
304       * the samples for the first pixel are grouped together, followed by all the
305       * samples for the second pixel, and so on).
306       *
307       * @param x  the x-coordinate of the top-left pixel.
308       * @param y  the y-coordinate of the top-left pixel.
309       * @param w  the width of the region of pixels.
310       * @param h  the height of the region of pixels.
311       * @param fArray  the pixel sample values (<code>null</code> not permitted).
312       *
313       * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
314       */
315      public void setPixels(int x, int y, int w, int h, float[] fArray)
316      {
317        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
318                              w, h, fArray, dataBuffer);
319      }
320    
321      /**
322       * Sets the sample values for the pixels in the region specified by
323       * (x, y, w, h) in the raster.  The array is ordered by pixels (that is, all
324       * the samples for the first pixel are grouped together, followed by all the
325       * samples for the second pixel, and so on).
326       *
327       * @param x  the x-coordinate of the top-left pixel.
328       * @param y  the y-coordinate of the top-left pixel.
329       * @param w  the width of the region of pixels.
330       * @param h  the height of the region of pixels.
331       * @param dArray  the pixel sample values (<code>null</code> not permitted).
332       *
333       * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
334       */
335      public void setPixels(int x, int y, int w, int h, double[] dArray)
336      {
337        sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
338                              w, h, dArray, dataBuffer);
339      }
340    
341      /**
342       * Sets the sample value for a band for the pixel at (x, y) in the raster.
343       *
344       * @param x  the x-coordinate of the pixel.
345       * @param y  the y-coordinate of the pixel.
346       * @param b  the band (in the range <code>0</code> to
347       *     <code>getNumBands() - 1</code>).
348       * @param s  the sample value.
349       */
350      public void setSample(int x, int y, int b, int s)
351      {
352        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
353                              b, s, dataBuffer);
354      }
355    
356      /**
357       * Sets the sample value for a band for the pixel at (x, y) in the raster.
358       *
359       * @param x  the x-coordinate of the pixel.
360       * @param y  the y-coordinate of the pixel.
361       * @param b  the band (in the range <code>0</code> to
362       *     <code>getNumBands() - 1</code>).
363       * @param s  the sample value.
364       */
365      public void setSample(int x, int y, int b, float s)
366      {
367        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
368                              b, s, dataBuffer);
369      }
370    
371      /**
372       * Sets the sample value for a band for the pixel at (x, y) in the raster.
373       *
374       * @param x  the x-coordinate of the pixel.
375       * @param y  the y-coordinate of the pixel.
376       * @param b  the band (in the range <code>0</code> to
377       *     <code>getNumBands() - 1</code>).
378       * @param s  the sample value.
379       */
380      public void setSample(int x, int y, int b, double s)
381      {
382        sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
383                              b, s, dataBuffer);
384      }
385    
386      /**
387       * Sets the sample values for one band for the pixels in the region
388       * specified by (x, y, w, h) in the raster.
389       *
390       * @param x  the x-coordinate of the top-left pixel.
391       * @param y  the y-coordinate of the top-left pixel.
392       * @param w  the width of the region of pixels.
393       * @param h  the height of the region of pixels.
394       * @param b  the band (in the range <code>0</code> to
395       *     </code>getNumBands() - 1</code>).
396       * @param iArray  the sample values (<code>null</code> not permitted).
397       *
398       * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
399       */
400      public void setSamples(int x, int y, int w, int h, int b,
401                             int[] iArray)
402      {
403        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
404                               w, h, b, iArray, dataBuffer);
405      }
406    
407      /**
408       * Sets the sample values for one band for the pixels in the region
409       * specified by (x, y, w, h) in the raster.
410       *
411       * @param x  the x-coordinate of the top-left pixel.
412       * @param y  the y-coordinate of the top-left pixel.
413       * @param w  the width of the region of pixels.
414       * @param h  the height of the region of pixels.
415       * @param b  the band (in the range <code>0</code> to
416       *     </code>getNumBands() - 1</code>).
417       * @param fArray  the sample values (<code>null</code> not permitted).
418       *
419       * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
420       */
421      public void setSamples(int x, int y, int w, int h, int b,
422                             float[] fArray)
423      {
424        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
425                               w, h, b, fArray, dataBuffer);
426      }
427    
428      /**
429       * Sets the sample values for one band for the pixels in the region
430       * specified by (x, y, w, h) in the raster.
431       *
432       * @param x  the x-coordinate of the top-left pixel.
433       * @param y  the y-coordinate of the top-left pixel.
434       * @param w  the width of the region of pixels.
435       * @param h  the height of the region of pixels.
436       * @param b  the band (in the range <code>0</code> to
437       *     </code>getNumBands() - 1</code>).
438       * @param dArray  the sample values (<code>null</code> not permitted).
439       *
440       * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
441       */
442      public void setSamples(int x, int y, int w, int h, int b,
443                             double[] dArray)
444      {
445        sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
446                               w, h, b, dArray, dataBuffer);
447      }
448    }