OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / awt / image / Raster.java
1 /* Copyright (C) 2000, 2002, 2003, 2006,  Free Software Foundation
2
3 This file is part of GNU Classpath.
4
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING.  If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 USA.
19
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library.  Thus, the terms and
22 conditions of the GNU General Public License cover the whole
23 combination.
24
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module.  An independent module is a module which is not derived from
32 or based on this library.  If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so.  If you do not wish to do so, delete this
35 exception statement from your version. */
36
37
38 package java.awt.image;
39
40 import gnu.java.lang.CPStringBuilder;
41
42 import java.awt.Point;
43 import java.awt.Rectangle;
44
45 /**
46  * A rectangular collection of pixels composed from a {@link DataBuffer} which
47  * stores the pixel values, and a {@link SampleModel} which is used to retrieve
48  * the pixel values.
49  * 
50  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
51  */
52 public class Raster
53 {
54   /** The sample model used to access the pixel values. */
55   protected SampleModel sampleModel;
56   
57   /** The data buffer used to store the pixel values. */
58   protected DataBuffer dataBuffer;
59   
60   /** The x-coordinate of the top left corner of the raster. */
61   protected int minX;
62   
63   /** The y-coordinate of the top left corner of the raster. */
64   protected int minY;
65   
66   /** The width of the raster. */
67   protected int width;
68   
69   /** The height of the raster. */
70   protected int height;
71   
72   protected int sampleModelTranslateX;
73   
74   protected int sampleModelTranslateY;
75   
76   /** The number of bands. */
77   protected int numBands;
78   
79   protected int numDataElements;
80   
81   /** The raster's parent. */
82   protected Raster parent;
83   
84   /**
85    * Creates a new raster.
86    * 
87    * @param sampleModel  the sample model.
88    * @param origin  the origin.
89    */
90   protected Raster(SampleModel sampleModel, Point origin)
91   {
92     this(sampleModel, sampleModel.createDataBuffer(), origin);
93   }
94   
95   /**
96    * Creates a new raster.
97    * 
98    * @param sampleModel  the sample model.
99    * @param dataBuffer  the data buffer.
100    * @param origin  the origin.
101    */
102   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
103                    Point origin)
104   {
105     this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
106          sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
107   }
108
109   /**
110    * Creates a new raster.
111    * 
112    * @param sampleModel  the sample model.
113    * @param dataBuffer  the data buffer.
114    * @param aRegion  the raster's bounds.
115    * @param sampleModelTranslate  the translation (<code>null</code> permitted).
116    * @param parent  the raster's parent.
117    */
118   protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
119       Rectangle aRegion, Point sampleModelTranslate, Raster parent)
120   {
121     this.sampleModel = sampleModel;
122     this.dataBuffer = dataBuffer;
123     this.minX = aRegion.x;
124     this.minY = aRegion.y;
125     this.width = aRegion.width;
126     this.height = aRegion.height;
127     
128     // If sampleModelTranslate is null, use (0,0).  Methods such as
129     // Raster.createRaster are specified to allow for a null argument.
130     if (sampleModelTranslate != null)
131     {
132       this.sampleModelTranslateX = sampleModelTranslate.x;
133       this.sampleModelTranslateY = sampleModelTranslate.y;
134     }
135
136     this.numBands = sampleModel.getNumBands();
137     this.numDataElements = sampleModel.getNumDataElements();
138     this.parent = parent;
139   }
140     
141   /**
142    * Creates an interleaved raster using the specified data type.
143    * 
144    * @param dataType  the data type.
145    * @param w  the width.
146    * @param h  the height.
147    * @param bands  the number of bands.
148    * @param location
149    * 
150    * @return The new raster.
151    */
152   public static WritableRaster createInterleavedRaster(int dataType,
153       int w, int h, int bands, Point location)
154   {
155     int[] bandOffsets = new int[bands];
156     // TODO: Maybe not generate this every time.
157     for (int b = 0; b < bands; b++) 
158       bandOffsets[b] = b;
159     
160     int scanlineStride = bands * w;
161     return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
162                                    bandOffsets, location);
163   }
164
165   /**
166    * Creates an interleaved raster.
167    * 
168    * @param dataType  the data type.
169    * @param w  the width.
170    * @param h  the height.
171    * @param scanlineStride  the number of data elements from a sample on one 
172    *     row to the corresponding sample on the next row.
173    * @param pixelStride  the number of elements from a sample in one pixel to
174    *     the corresponding sample in the next pixel.
175    * @param bandOffsets  the band offsets.
176    * @param location
177    * 
178    * @return The new raster.
179    */
180   public static WritableRaster createInterleavedRaster(int dataType, 
181       int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
182       Point location)
183   {
184     SampleModel sm = new ComponentSampleModel(dataType, w, h, pixelStride,
185         scanlineStride, bandOffsets);
186     return createWritableRaster(sm, location);
187   }
188
189   /**
190    * Creates a new banded raster.
191    * 
192    * @param dataType  the data type.
193    * @param w  the width.
194    * @param h  the height.
195    * @param bands  the number of bands.
196    * @param location  
197    * 
198    * @return The new raster.
199    */
200   public static WritableRaster createBandedRaster(int dataType, int w, int h, 
201       int bands, Point location)
202   {
203     SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
204     return createWritableRaster(sm, location);
205   }
206
207   /**
208    * Creates a new banded raster.
209    * 
210    * @param dataType  the data type.
211    * @param w  the width.
212    * @param h  the height.
213    * @param scanlineStride  the number of data elements from a sample on one 
214    *     row to the corresponding sample on the next row.
215    * @param bankIndices  the index for each bank.
216    * @param bandOffsets  the offset for each band.
217    * @param location
218    * 
219    * @return The new raster.
220    */
221   public static WritableRaster createBandedRaster(int dataType, int w, int h,
222       int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)
223   {
224     SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
225                                            bankIndices, bandOffsets);
226     return createWritableRaster(sm, location);
227   }
228   
229   /**
230    * Creates a new packed raster.
231    * 
232    * @param dataType  the data type.
233    * @param w  the width.
234    * @param h  the height.
235    * @param bandMasks  the bit mask for each band.
236    * @param location 
237    * 
238    * @return The new raster.
239    */
240   public static WritableRaster createPackedRaster(int dataType, int w, int h,
241       int[] bandMasks, Point location)
242   {
243     SampleModel sm = new SinglePixelPackedSampleModel(dataType, w, h,
244                                                      bandMasks);
245     return createWritableRaster(sm, location);
246   }
247
248   /**
249    * Creates a new raster.
250    * 
251    * @param dataType  the data type.
252    * @param w  the width.
253    * @param h  the height.
254    * @param bands  the number of bands.
255    * @param bitsPerBand  the number of bits per band.
256    * @param location
257    * 
258    * @return The new raster.
259    */
260   public static WritableRaster createPackedRaster(int dataType,
261       int w, int h, int bands, int bitsPerBand, Point location)
262   {
263     if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
264       throw new IllegalArgumentException();
265
266     SampleModel sm;
267
268     if (bands == 1)
269       sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
270     else
271       {
272         int[] bandMasks = new int[bands];
273         int mask = 0x1;
274         for (int bits = bitsPerBand; --bits != 0;)
275           mask = (mask << 1) | 0x1;
276         for (int i = 0; i < bands; i++)
277           {
278             bandMasks[i] = mask;
279             mask <<= bitsPerBand;
280           }
281           
282         sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
283       }
284     return createWritableRaster(sm, location);
285   }
286
287   /**
288    * Creates a new interleaved raster.
289    * 
290    * @param dataBuffer  the data buffer.
291    * @param w  the width.
292    * @param h  the height.
293    * @param scanlineStride  the number of data elements from a sample on one 
294    *     row to the corresponding sample on the next row.
295    * @param pixelStride  the number of elements from a sample in one pixel to
296    *     the corresponding sample in the next pixel.
297    * @param bandOffsets  the offset for each band.
298    * @param location
299    * 
300    * @return The new raster.
301    */
302   public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, 
303       int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets, 
304       Point location)
305   {
306     SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
307         w, h, pixelStride, scanlineStride, bandOffsets);
308     return createWritableRaster(sm, dataBuffer, location);
309   }
310
311   /**
312    * Creates a new banded raster.
313    * 
314    * @param dataBuffer  the data buffer.
315    * @param w  the width.
316    * @param h  the height.
317    * @param scanlineStride  the number of data elements from a sample on one 
318    *     row to the corresponding sample on the next row.
319    * @param bankIndices  the index for each bank.
320    * @param bandOffsets  the band offsets.
321    * @param location
322    * 
323    * @return The new raster.
324    */
325   public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
326       int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets,
327       Point location)
328   {
329     SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
330         w, h, scanlineStride, bankIndices, bandOffsets);
331     return createWritableRaster(sm, dataBuffer, location);
332   }
333   
334   /**
335    * Creates a new packed raster.
336    * 
337    * @param dataBuffer  the data buffer.
338    * @param w  the width.
339    * @param h  the height.
340    * @param scanlineStride  the number of data elements from a sample on one 
341    *     row to the corresponding sample on the next row.
342    * @param bandMasks  the bit mask for each band.
343    * @param location
344    * 
345    * @return The new raster.
346    */
347   public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
348       int w, int h, int scanlineStride, int[] bandMasks, Point location)
349  {
350     SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
351         w, h, scanlineStride, bandMasks);
352     return createWritableRaster(sm, dataBuffer, location);
353   }
354   
355   /**
356    * Creates a new packed raster.
357    * 
358    * @param dataBuffer  the data buffer.
359    * @param w  the width.
360    * @param h  the height.
361    * @param bitsPerPixel  the number of bits per pixel.
362    * @param location
363    * 
364    * @return The new raster.
365    */
366   public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
367       int w, int h, int bitsPerPixel, Point location)
368   {
369     SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
370         w, h, bitsPerPixel);
371     return createWritableRaster(sm, dataBuffer, location);
372   }
373     
374   /**
375    * Creates a new raster.
376    * 
377    * @param sm  the sample model.
378    * @param db  the data buffer.
379    * @param location
380    * 
381    * @return The new raster.
382    */
383   public static Raster createRaster(SampleModel sm, DataBuffer db,
384                                     Point location)
385   {
386     return new Raster(sm, db, location);
387   }
388
389   /**
390    * Creates a new writable raster.
391    * 
392    * @param sm  the sample model.
393    * @param location
394    * 
395    * @return The new writable raster.
396    */
397   public static WritableRaster createWritableRaster(SampleModel sm,
398                                                     Point location)
399   {
400     return new WritableRaster(sm, location);
401   }
402
403   /**
404    * Creates a new writable raster.
405    * 
406    * @param sm  the sample model.
407    * @param db  the data buffer.
408    * @param location 
409    * 
410    * @return The new writable raster.
411    */
412   public static WritableRaster createWritableRaster(SampleModel sm,
413       DataBuffer db, Point location)
414   {
415     return new WritableRaster(sm, db, location);
416   }
417
418   /**
419    * Returns the raster's parent.
420    * 
421    * @return The raster's parent.
422    */
423   public Raster getParent()
424   {
425     return parent;
426   }
427
428   /**
429    * Returns the x-translation.
430    * 
431    * @return The x-translation.
432    */
433   public final int getSampleModelTranslateX()
434   {
435     return sampleModelTranslateX;
436   }
437
438   /**
439    * Returns the y-translation.
440    * 
441    * @return The y-translation.
442    */
443   public final int getSampleModelTranslateY()
444   {
445     return sampleModelTranslateY;
446   }
447
448   /**
449    * Creates a new writable raster that is compatible with this raster.
450    * 
451    * @return A new writable raster.
452    */
453   public WritableRaster createCompatibleWritableRaster()
454   {
455     return new WritableRaster(getSampleModel(), new Point(minX, minY));
456   }
457
458   /**
459    * Creates a new writable raster that is compatible with this raster.
460    * 
461    * @param w  the width.
462    * @param h  the height.
463    * 
464    * @return A new writable raster.
465    */
466   public WritableRaster createCompatibleWritableRaster(int w, int h)
467   {
468     return createCompatibleWritableRaster(minX, minY, w, h);
469   }
470
471   /**
472    * Creates a new writable raster that is compatible with this raster, with
473    * the specified bounds.
474    * 
475    * @param rect  the raster bounds.
476    * 
477    * @return A new writable raster.
478    */
479   public WritableRaster createCompatibleWritableRaster(Rectangle rect)
480   {
481     return createCompatibleWritableRaster(rect.x, rect.y,
482                                           rect.width, rect.height);
483   }
484
485   /**
486    * Creates a new writable raster that is compatible with this raster, with
487    * the specified bounds.
488    * 
489    * @param x  the x-coordinate of the top-left corner of the raster.
490    * @param y  the y-coordinate of the top-left corner of the raster.
491    * @param w  the raster width.
492    * @param h  the raster height.
493    * 
494    * @return A new writable raster.
495    */
496   public WritableRaster createCompatibleWritableRaster(int x, int y,
497                                                        int w, int h)
498   {
499     SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
500     return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y));
501   }
502
503   public Raster createTranslatedChild(int childMinX, int childMinY) {
504     int tcx = sampleModelTranslateX - minX + childMinX;
505     int tcy = sampleModelTranslateY - minY + childMinY;
506     
507     return new Raster(sampleModel, dataBuffer,
508                       new Rectangle(childMinX, childMinY, width, height),
509                       new Point(tcx, tcy), this);
510   }
511
512   public Raster createChild(int parentX, int parentY, int width,
513                             int height, int childMinX, int childMinY,
514                             int[] bandList)
515   {
516     if (parentX < minX || parentX + width > minX + this.width
517         || parentY < minY || parentY + height > minY + this.height)
518       throw new RasterFormatException("Child raster extends beyond parent");
519     
520     SampleModel sm = (bandList == null) ?
521       sampleModel :
522       sampleModel.createSubsetSampleModel(bandList);
523
524     /*
525         data origin
526        /
527       +-------------------------
528       |\. __ parent trans
529       | \`.  
530       |  \ `.    parent origin
531       |   \  `. /
532       |   /\   +-------- - -
533       |trans\ /<\-- deltaTrans
534       |child +-+-\---- - - 
535       |     /|`|  \__ parent [x, y]
536       |child | |`. \
537       |origin| :  `.\
538       |      |    / `\
539       |      :   /    +
540       | child [x, y] 
541
542       parent_xy - parent_trans = child_xy - child_trans
543
544       child_trans = parent_trans + child_xy - parent_xy
545     */
546
547     return new Raster(sm, dataBuffer,
548         new Rectangle(childMinX, childMinY, width, height),
549         new Point(sampleModelTranslateX + childMinX - parentX,
550                   sampleModelTranslateY + childMinY - parentY),
551         this);
552   }
553
554   /**
555    * Returns a new rectangle containing the bounds of this raster.
556    * 
557    * @return A new rectangle containing the bounds of this raster.
558    */
559   public Rectangle getBounds()
560   {
561     return new Rectangle(minX, minY, width, height);
562   }
563
564   /**
565    * Returns the x-coordinate of the top left corner of the raster.
566    * 
567    * @return The x-coordinate of the top left corner of the raster.
568    */
569   public final int getMinX()
570   {
571     return minX;
572   }
573
574   /**
575    * Returns the t-coordinate of the top left corner of the raster.
576    * 
577    * @return The t-coordinate of the top left corner of the raster.
578    */
579   public final int getMinY()
580   {
581     return minY;
582   }
583
584   /**
585    * Returns the width of the raster.
586    * 
587    * @return The width of the raster.
588    */
589   public final int getWidth()
590   {
591     return width;
592   }
593
594   /**
595    * Returns the height of the raster.
596    * 
597    * @return The height of the raster.
598    */
599   public final int getHeight()
600   {
601     return height;
602   }
603
604   /**
605    * Returns the number of bands for this raster.
606    * 
607    * @return The number of bands.
608    */
609   public final int getNumBands()
610   {
611     return numBands;
612   }
613     
614   public final int getNumDataElements()
615   {
616     return numDataElements;
617   }
618   
619   /**
620    * Returns the transfer type for the raster (this is determined by the 
621    * raster's sample model).
622    * 
623    * @return The transfer type.
624    */
625   public final int getTransferType()
626   {
627     return sampleModel.getTransferType();
628   }
629
630   /**
631    * Returns the data buffer that stores the pixel data for this raster.
632    * 
633    * @return The data buffer.
634    */
635   public DataBuffer getDataBuffer()
636   {
637     return dataBuffer;
638   }
639
640   /**
641    * Returns the sample model that accesses the data buffer (to extract pixel
642    * data) for this raster.
643    * 
644    * @return The sample model.
645    */
646   public SampleModel getSampleModel()
647   {
648     return sampleModel;
649   }
650
651   public Object getDataElements(int x, int y, Object outData)
652   {
653     return sampleModel.getDataElements(x - sampleModelTranslateX,
654         y - sampleModelTranslateY, outData, dataBuffer);
655   }
656
657   public Object getDataElements(int x, int y, int w, int h, Object outData)
658   {
659     return sampleModel.getDataElements(x - sampleModelTranslateX,
660         y - sampleModelTranslateY, w, h, outData, dataBuffer);
661   }
662
663   /**
664    * Returns an array containing the samples for the pixel at (x, y) in the
665    * raster.  If <code>iArray</code> is not <code>null</code>, it will be 
666    * populated with the sample values and returned as the result of
667    * this function (this avoids allocating a new array instance).
668    * 
669    * @param x  the x-coordinate of the pixel.
670    * @param y  the y-coordinate of the pixel.
671    * @param iArray  an array to populate with the sample values and return as 
672    *     the result (if <code>null</code>, a new array will be allocated).
673    * 
674    * @return The pixel sample values.
675    */
676   public int[] getPixel(int x, int y, int[] iArray)
677   {
678     return sampleModel.getPixel(x - sampleModelTranslateX,
679         y - sampleModelTranslateY, iArray, dataBuffer);
680   }
681
682   /**
683    * Returns an array containing the samples for the pixel at (x, y) in the
684    * raster.  If <code>fArray</code> is not <code>null</code>, it will be 
685    * populated with the sample values and returned as the result of
686    * this function (this avoids allocating a new array instance).
687    * 
688    * @param x  the x-coordinate of the pixel.
689    * @param y  the y-coordinate of the pixel.
690    * @param fArray  an array to populate with the sample values and return as 
691    *     the result (if <code>null</code>, a new array will be allocated).
692    * 
693    * @return The pixel sample values.
694    */
695   public float[] getPixel(int x, int y, float[] fArray)
696   {
697     return sampleModel.getPixel(x - sampleModelTranslateX,
698         y - sampleModelTranslateY, fArray, dataBuffer);
699   }
700
701   /**
702    * Returns an array containing the samples for the pixel at (x, y) in the
703    * raster.  If <code>dArray</code> is not <code>null</code>, it will be 
704    * populated with the sample values and returned as the result of
705    * this function (this avoids allocating a new array instance).
706    * 
707    * @param x  the x-coordinate of the pixel.
708    * @param y  the y-coordinate of the pixel.
709    * @param dArray  an array to populate with the sample values and return as 
710    *     the result (if <code>null</code>, a new array will be allocated).
711    * 
712    * @return The pixel sample values.
713    */
714   public double[] getPixel(int x, int y, double[] dArray)
715   {
716     return sampleModel.getPixel(x - sampleModelTranslateX,
717         y - sampleModelTranslateY, dArray, dataBuffer);
718   }
719
720   /**
721    * Returns an array containing the samples for the pixels in the region 
722    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
723    * (that is, all the samples for the first pixel are grouped together, 
724    * followed by all the samples for the second pixel, and so on).  
725    * If <code>iArray</code> is not <code>null</code>, it will be populated 
726    * with the sample values and returned as the result of this function (this 
727    * avoids allocating a new array instance).
728    * 
729    * @param x  the x-coordinate of the top-left pixel.
730    * @param y  the y-coordinate of the top-left pixel.
731    * @param w  the width of the region of pixels.
732    * @param h  the height of the region of pixels.
733    * @param iArray  an array to populate with the sample values and return as 
734    *     the result (if <code>null</code>, a new array will be allocated).
735    * 
736    * @return The pixel sample values.
737    */
738   public int[] getPixels(int x, int y, int w, int h, int[] iArray)
739   {
740     return sampleModel.getPixels(x - sampleModelTranslateX,
741         y - sampleModelTranslateY, w, h, iArray, dataBuffer);
742   }
743
744   /**
745    * Returns an array containing the samples for the pixels in the region 
746    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
747    * (that is, all the samples for the first pixel are grouped together, 
748    * followed by all the samples for the second pixel, and so on).  
749    * If <code>fArray</code> is not <code>null</code>, it will be populated 
750    * with the sample values and returned as the result of this function (this 
751    * avoids allocating a new array instance).
752    * 
753    * @param x  the x-coordinate of the top-left pixel.
754    * @param y  the y-coordinate of the top-left pixel.
755    * @param w  the width of the region of pixels.
756    * @param h  the height of the region of pixels.
757    * @param fArray  an array to populate with the sample values and return as 
758    *     the result (if <code>null</code>, a new array will be allocated).
759    * 
760    * @return The pixel sample values.
761    */
762   public float[] getPixels(int x, int y, int w, int h, float[] fArray)
763   {
764     return sampleModel.getPixels(x - sampleModelTranslateX,
765         y - sampleModelTranslateY, w, h, fArray, dataBuffer);
766   }
767
768   /**
769    * Returns an array containing the samples for the pixels in the region 
770    * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
771    * (that is, all the samples for the first pixel are grouped together, 
772    * followed by all the samples for the second pixel, and so on).  
773    * If <code>dArray</code> is not <code>null</code>, it will be populated 
774    * with the sample values and returned as the result of this function (this 
775    * avoids allocating a new array instance).
776    * 
777    * @param x  the x-coordinate of the top-left pixel.
778    * @param y  the y-coordinate of the top-left pixel.
779    * @param w  the width of the region of pixels.
780    * @param h  the height of the region of pixels.
781    * @param dArray  an array to populate with the sample values and return as 
782    *     the result (if <code>null</code>, a new array will be allocated).
783    * 
784    * @return The pixel sample values.
785    */
786   public double[] getPixels(int x, int y, int w, int h, double[] dArray)
787   {
788     return sampleModel.getPixels(x - sampleModelTranslateX,
789         y - sampleModelTranslateY, w, h, dArray, dataBuffer);
790   }
791
792   /**
793    * Returns the sample value for the pixel at (x, y) in the raster.
794    * 
795    * @param x  the x-coordinate of the pixel.
796    * @param y  the y-coordinate of the pixel.
797    * @param b  the band (in the range <code>0</code> to 
798    *     <code>getNumBands() - 1</code>).
799    * 
800    * @return The sample value.
801    */
802   public int getSample(int x, int y, int b)
803   {
804     return sampleModel.getSample(x - sampleModelTranslateX,
805         y - sampleModelTranslateY, b, dataBuffer);
806   }
807
808   /**
809    * Returns the sample value for the pixel at (x, y) in the raster.
810    * 
811    * @param x  the x-coordinate of the pixel.
812    * @param y  the y-coordinate of the pixel.
813    * @param b  the band (in the range <code>0</code> to 
814    *     <code>getNumBands() - 1</code>).
815    * 
816    * @return The sample value.
817    * 
818    * @see #getSample(int, int, int)
819    */
820   public float getSampleFloat(int x, int y, int b)
821   {
822     return sampleModel.getSampleFloat(x - sampleModelTranslateX,
823         y - sampleModelTranslateY, b, dataBuffer);
824   }
825
826   /**
827    * Returns the sample value for the pixel at (x, y) in the raster.
828    * 
829    * @param x  the x-coordinate of the pixel.
830    * @param y  the y-coordinate of the pixel.
831    * @param b  the band (in the range <code>0</code> to 
832    *     <code>getNumBands() - 1</code>).
833    * 
834    * @return The sample value.
835    * 
836    * @see #getSample(int, int, int)
837    */
838   public double getSampleDouble(int x, int y, int b)
839   {
840     return sampleModel.getSampleDouble(x - sampleModelTranslateX,
841         y - sampleModelTranslateY, b, dataBuffer);
842   }
843
844   /**
845    * Returns an array containing the samples from one band for the pixels in 
846    * the region specified by (x, y, w, h) in the raster.  If 
847    * <code>iArray</code> is not <code>null</code>, it will be 
848    * populated with the sample values and returned as the result of this 
849    * function (this avoids allocating a new array instance).
850    * 
851    * @param x  the x-coordinate of the top-left pixel.
852    * @param y  the y-coordinate of the top-left pixel.
853    * @param w  the width of the region of pixels.
854    * @param h  the height of the region of pixels.
855    * @param b  the band (in the range <code>0</code> to 
856    *     </code>getNumBands() - 1</code>).
857    * @param iArray  an array to populate with the sample values and return as 
858    *     the result (if <code>null</code>, a new array will be allocated).
859    * 
860    * @return The sample values.
861    */
862   public int[] getSamples(int x, int y, int w, int h, int b,
863                           int[] iArray)
864   {
865     return sampleModel.getSamples(x - sampleModelTranslateX,
866         y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
867   }
868
869   /**
870    * Returns an array containing the samples from one band for the pixels in 
871    * the region specified by (x, y, w, h) in the raster.  If 
872    * <code>fArray</code> is not <code>null</code>, it will be 
873    * populated with the sample values and returned as the result of this 
874    * function (this avoids allocating a new array instance).
875    *
876    * @param x  the x-coordinate of the top-left pixel.
877    * @param y  the y-coordinate of the top-left pixel.
878    * @param w  the width of the region of pixels.
879    * @param h  the height of the region of pixels.
880    * @param b  the band (in the range <code>0</code> to 
881    *     </code>getNumBands() - 1</code>).
882    * @param fArray  an array to populate with the sample values and return as 
883    *     the result (if <code>null</code>, a new array will be allocated).
884    * 
885    * @return The sample values.
886    */  
887   public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray)
888   {
889     return sampleModel.getSamples(x - sampleModelTranslateX,
890         y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
891   }
892
893   /**
894    * Returns an array containing the samples from one band for the pixels in 
895    * the region specified by (x, y, w, h) in the raster.  If 
896    * <code>dArray</code> is not <code>null</code>, it will be 
897    * populated with the sample values and returned as the result of this 
898    * function (this avoids allocating a new array instance).
899    * 
900    * @param x  the x-coordinate of the top-left pixel.
901    * @param y  the y-coordinate of the top-left pixel.
902    * @param w  the width of the region of pixels.
903    * @param h  the height of the region of pixels.
904    * @param b  the band (in the range <code>0</code> to 
905    *     </code>getNumBands() - 1</code>).
906    * @param dArray  an array to populate with the sample values and return as 
907    *     the result (if <code>null</code>, a new array will be allocated).
908    * 
909    * @return The sample values.
910    */
911   public double[] getSamples(int x, int y, int w, int h, int b, 
912                              double[] dArray)
913   {
914     return sampleModel.getSamples(x - sampleModelTranslateX,
915         y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
916   }
917   
918   /**
919    * Create a String representing the state of this Raster.
920    * 
921    * @return A String representing the stat of this Raster.
922    */
923   public String toString()
924   {
925     CPStringBuilder result = new CPStringBuilder();
926     
927     result.append(getClass().getName());
928     result.append("[(");
929     result.append(minX).append(",").append(minY).append("), ");
930     result.append(width).append(" x ").append(height).append(",");
931     result.append(sampleModel).append(",");
932     result.append(dataBuffer);
933     result.append("]");
934     
935     return result.toString();
936   }
937
938   /**
939    * Returns the number of bits used to represent the specified data type.  
940    * Valid types are:
941    * <ul>
942    *   <li>{@link DataBuffer#TYPE_BYTE};</li>
943    *   <li>{@link DataBuffer#TYPE_USHORT};</li>
944    *   <li>{@link DataBuffer#TYPE_SHORT};</li>
945    *   <li>{@link DataBuffer#TYPE_INT};</li>
946    *   <li>{@link DataBuffer#TYPE_FLOAT};</li>
947    *   <li>{@link DataBuffer#TYPE_DOUBLE};</li>
948    * </ul>
949    * This method returns 0 for invalid data types.
950    * 
951    * @param dataType  the data type.
952    * 
953    * @return The number of bits used to represent the specified data type.
954    */
955   private static int getTypeBits(int dataType)
956   {
957     switch (dataType)
958       {
959       case DataBuffer.TYPE_BYTE:
960         return 8;
961       case DataBuffer.TYPE_USHORT:
962       case DataBuffer.TYPE_SHORT:
963         return 16;
964       case DataBuffer.TYPE_INT:
965       case DataBuffer.TYPE_FLOAT:
966         return 32;
967       case DataBuffer.TYPE_DOUBLE:
968         return 64;
969       default:
970         return 0;
971       }
972   }
973 }