KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)Raster.java 1.61 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 /* ****************************************************************
9  ******************************************************************
10  ******************************************************************
11  *** COPYRIGHT (c) Eastman Kodak Company, 1997
12  *** As an unpublished work pursuant to Title 17 of the United
13  *** States Code. All rights reserved.
14  ******************************************************************
15  ******************************************************************
16  ******************************************************************/

17
18
19 package java.awt.image;
20 import java.awt.Rectangle JavaDoc;
21 import java.awt.Point JavaDoc;
22
23 import sun.awt.image.ByteInterleavedRaster;
24 import sun.awt.image.ShortInterleavedRaster;
25 import sun.awt.image.IntegerInterleavedRaster;
26 import sun.awt.image.ByteBandedRaster;
27 import sun.awt.image.ShortBandedRaster;
28 import sun.awt.image.BytePackedRaster;
29 import sun.awt.image.SunWritableRaster;
30
31 /**
32  * A class representing a rectangular array of pixels. A Raster
33  * encapsulates a DataBuffer that stores the sample values and a
34  * SampleModel that describes how to locate a given sample value in a
35  * DataBuffer.
36  * <p>
37  * A Raster defines values for pixels occupying a particular
38  * rectangular area of the plane, not necessarily including (0, 0).
39  * The rectangle, known as the Raster's bounding rectangle and
40  * available by means of the getBounds method, is defined by minX,
41  * minY, width, and height values. The minX and minY values define
42  * the coordinate of the upper left corner of the Raster. References
43  * to pixels outside of the bounding rectangle may result in an
44  * exception being thrown, or may result in references to unintended
45  * elements of the Raster's associated DataBuffer. It is the user's
46  * responsibility to avoid accessing such pixels.
47  * <p>
48  * A SampleModel describes how samples of a Raster
49  * are stored in the primitive array elements of a DataBuffer.
50  * Samples may be stored one per data element, as in a
51  * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
52  * an element, as in a SinglePixelPackedSampleModel or
53  * MultiPixelPackedSampleModel. The SampleModel is also
54  * controls whether samples are sign extended, allowing unsigned
55  * data to be stored in signed Java data types such as byte, short, and
56  * int.
57  * <p>
58  * Although a Raster may live anywhere in the plane, a SampleModel
59  * makes use of a simple coordinate system that starts at (0, 0). A
60  * Raster therefore contains a translation factor that allows pixel
61  * locations to be mapped between the Raster's coordinate system and
62  * that of the SampleModel. The translation from the SampleModel
63  * coordinate system to that of the Raster may be obtained by the
64  * getSampleModelTranslateX and getSampleModelTranslateY methods.
65  * <p>
66  * A Raster may share a DataBuffer with another Raster either by
67  * explicit construction or by the use of the createChild and
68  * createTranslatedChild methods. Rasters created by these methods
69  * can return a reference to the Raster they were created from by
70  * means of the getParent method. For a Raster that was not
71  * constructed by means of a call to createTranslatedChild or
72  * createChild, getParent will return null.
73  * <p>
74  * The createTranslatedChild method returns a new Raster that
75  * shares all of the data of the current Raster, but occupies a
76  * bounding rectangle of the same width and height but with a
77  * different starting point. For example, if the parent Raster
78  * occupied the region (10, 10) to (100, 100), and the translated
79  * Raster was defined to start at (50, 50), then pixel (20, 20) of the
80  * parent and pixel (60, 60) of the child occupy the same location in
81  * the DataBuffer shared by the two Rasters. In the first case, (-10,
82  * -10) should be added to a pixel coordinate to obtain the
83  * corresponding SampleModel coordinate, and in the second case (-50,
84  * -50) should be added.
85  * <p>
86  * The translation between a parent and child Raster may be
87  * determined by subtracting the child's sampleModelTranslateX and
88  * sampleModelTranslateY values from those of the parent.
89  * <p>
90  * The createChild method may be used to create a new Raster
91  * occupying only a subset of its parent's bounding rectangle
92  * (with the same or a translated coordinate system) or
93  * with a subset of the bands of its parent.
94  * <p>
95  * All constructors are protected. The correct way to create a
96  * Raster is to use one of the static create methods defined in this
97  * class. These methods create instances of Raster that use the
98  * standard Interleaved, Banded, and Packed SampleModels and that may
99  * be processed more efficiently than a Raster created by combining
100  * an externally generated SampleModel and DataBuffer.
101  * @see java.awt.image.DataBuffer
102  * @see java.awt.image.SampleModel
103  * @see java.awt.image.PixelInterleavedSampleModel
104  * @see java.awt.image.BandedSampleModel
105  * @see java.awt.image.SinglePixelPackedSampleModel
106  * @see java.awt.image.MultiPixelPackedSampleModel
107  */

108 public class Raster {
109
110     /**
111      * The SampleModel that describes how pixels from this Raster
112      * are stored in the DataBuffer.
113      */

114     protected SampleModel JavaDoc sampleModel;
115
116     /** The DataBuffer that stores the image data. */
117     protected DataBuffer JavaDoc dataBuffer;
118
119     /** The X coordinate of the upper-left pixel of this Raster. */
120     protected int minX;
121
122     /** The Y coordinate of the upper-left pixel of this Raster. */
123     protected int minY;
124
125     /** The width of this Raster. */
126     protected int width;
127
128     /** The height of this Raster. */
129     protected int height;
130
131     /**
132      * The X translation from the coordinate space of the
133      * Raster's SampleModel to that of the Raster.
134      */

135     protected int sampleModelTranslateX;
136
137     /**
138      * The Y translation from the coordinate space of the
139      * Raster's SampleModel to that of the Raster.
140      */

141     protected int sampleModelTranslateY;
142
143     /** The number of bands in the Raster. */
144     protected int numBands;
145
146     /** The number of DataBuffer data elements per pixel. */
147     protected int numDataElements;
148
149     /** The parent of this Raster, or null. */
150     protected Raster JavaDoc parent;
151
152     static private native void initIDs();
153     static {
154         ColorModel.loadLibraries();
155         initIDs();
156     }
157
158     /**
159      * Creates a Raster based on a PixelInterleavedSampleModel with the
160      * specified data type, width, height, and number of bands.
161      *
162      * <p> The upper left corner of the Raster is given by the
163      * location argument. If location is null, (0, 0) will be used.
164      * The dataType parameter should be one of the enumerated values
165      * defined in the DataBuffer class.
166      *
167      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
168      * Rasters are not supported. To create a 1-band Raster of type
169      * <code>DataBuffer.TYPE_INT</code>, use
170      * Raster.createPackedRaster().
171      * <p> The only dataTypes supported currently are TYPE_BYTE
172      * and TYPE_USHORT.
173      * @param dataType the data type for storing samples
174      * @param w the width in pixels of the image data
175      * @param h the height in pixels of the image data
176      * @param bands the number of bands
177      * @param location the upper-left corner of the <code>Raster</code>
178      * @return a WritableRaster object with the specified data type,
179      * width, height and number of bands.
180      * @throws RasterFormatException if <code>w</code> or <code>h</code>
181      * is less than or equal to zero, or computing either
182      * <code>location.x + w</code> or
183      * <code>location.y + h</code> results in integer
184      * overflow
185      */

186     public static WritableRaster JavaDoc createInterleavedRaster(int dataType,
187                                                          int w, int h,
188                                                          int bands,
189                                                          Point JavaDoc location) {
190         int[] bandOffsets = new int[bands];
191         for (int i = 0; i < bands; i++) {
192             bandOffsets[i] = i;
193         }
194         return createInterleavedRaster(dataType, w, h, w*bands, bands,
195                                        bandOffsets, location);
196     }
197
198     /**
199      * Creates a Raster based on a PixelInterleavedSampleModel with the
200      * specified data type, width, height, scanline stride, pixel
201      * stride, and band offsets. The number of bands is inferred from
202      * bandOffsets.length.
203      *
204      * <p> The upper left corner of the Raster is given by the
205      * location argument. If location is null, (0, 0) will be used.
206      * The dataType parameter should be one of the enumerated values
207      * defined in the DataBuffer class.
208      *
209      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
210      * Rasters are not supported. To create a 1-band Raster of type
211      * <code>DataBuffer.TYPE_INT</code>, use
212      * Raster.createPackedRaster().
213      * <p> The only dataTypes supported currently are TYPE_BYTE
214      * and TYPE_USHORT.
215      * @param dataType the data type for storing samples
216      * @param w the width in pixels of the image data
217      * @param h the height in pixels of the image data
218      * @param scanlineStride the line stride of the image data
219      * @param pixelStride the pixel stride of the image data
220      * @param bandOffsets the offsets of all bands
221      * @param location the upper-left corner of the <code>Raster</code>
222      * @return a WritableRaster object with the specified data type,
223      * width, height, scanline stride, pixel stride and band
224      * offsets.
225      * @throws RasterFormatException if <code>w</code> or <code>h</code>
226      * is less than or equal to zero, or computing either
227      * <code>location.x + w</code> or
228      * <code>location.y + h</code> results in integer
229      * overflow
230      * @throws IllegalArgumentException if <code>dataType</code> is not
231      * one of the supported data types, which are
232      * <code>DataBuffer.TYPE_BYTE</code>, or
233      * <code>DataBuffer.TYPE_USHORT</code>.
234      */

235     public static WritableRaster JavaDoc createInterleavedRaster(int dataType,
236                                                          int w, int h,
237                                                          int scanlineStride,
238                                                          int pixelStride,
239                                                          int bandOffsets[],
240                                                          Point JavaDoc location) {
241     DataBuffer JavaDoc d;
242         int bands = bandOffsets.length;
243
244         int maxBandOff = bandOffsets[0];
245         for (int i=1; i < bands; i++) {
246             if (bandOffsets[i] > maxBandOff) {
247                 maxBandOff = bandOffsets[i];
248             }
249         }
250         int size = maxBandOff + scanlineStride*(h-1) + pixelStride*(w-1) + 1;
251         switch(dataType) {
252         case DataBuffer.TYPE_BYTE:
253             d = new DataBufferByte JavaDoc(size);
254             break;
255
256         case DataBuffer.TYPE_USHORT:
257             d = new DataBufferUShort JavaDoc(size);
258             break;
259
260         default:
261             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
262                                                 dataType);
263         }
264
265         SunWritableRaster raster = (SunWritableRaster)
266             createInterleavedRaster(d, w, h, scanlineStride,
267                                     pixelStride, bandOffsets, location);
268         raster.setStolen(false);
269         return raster;
270     }
271
272     /**
273      * Creates a Raster based on a BandedSampleModel with the
274      * specified data type, width, height, and number of bands.
275      *
276      * <p> The upper left corner of the Raster is given by the
277      * location argument. If location is null, (0, 0) will be used.
278      * The dataType parameter should be one of the enumerated values
279      * defined in the DataBuffer class.
280      *
281      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
282      * and TYPE_INT.
283      * @param dataType the data type for storing samples
284      * @param w the width in pixels of the image data
285      * @param h the height in pixels of the image data
286      * @param bands the number of bands
287      * @param location the upper-left corner of the <code>Raster</code>
288      * @return a WritableRaster object with the specified data type,
289      * width, height and number of bands.
290      * @throws RasterFormatException if <code>w</code> or <code>h</code>
291      * is less than or equal to zero, or computing either
292      * <code>location.x + w</code> or
293      * <code>location.y + h</code> results in integer
294      * overflow
295      * @throws ArrayIndexOutOfBoundsException if <code>bands</code>
296      * is less than 1
297      */

298     public static WritableRaster JavaDoc createBandedRaster(int dataType,
299                                                     int w, int h,
300                                                     int bands,
301                                                     Point JavaDoc location) {
302         if (bands < 1) {
303             throw new ArrayIndexOutOfBoundsException JavaDoc("Number of bands ("+
304                                                      bands+") must"+
305                                                      " be greater than 0");
306         }
307         int[] bankIndices = new int[bands];
308         int[] bandOffsets = new int[bands];
309         for (int i = 0; i < bands; i++) {
310             bankIndices[i] = i;
311             bandOffsets[i] = 0;
312         }
313
314         return createBandedRaster(dataType, w, h, w,
315                                   bankIndices, bandOffsets,
316                                   location);
317     }
318
319     /**
320      * Creates a Raster based on a BandedSampleModel with the
321      * specified data type, width, height, scanline stride, bank
322      * indices and band offsets. The number of bands is inferred from
323      * bankIndices.length and bandOffsets.length, which must be the
324      * same.
325      *
326      * <p> The upper left corner of the Raster is given by the
327      * location argument. The dataType parameter should be one of the
328      * enumerated values defined in the DataBuffer class.
329      *
330      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
331      * and TYPE_INT.
332      * @param dataType the data type for storing samples
333      * @param w the width in pixels of the image data
334      * @param h the height in pixels of the image data
335      * @param scanlineStride the line stride of the image data
336      * @param bankIndices the bank indices for each band
337      * @param bandOffsets the offsets of all bands
338      * @param location the upper-left corner of the <code>Raster</code>
339      * @return a WritableRaster object with the specified data type,
340      * width, height, scanline stride, bank indices and band
341      * offsets.
342      * @throws RasterFormatException if <code>w</code> or <code>h</code>
343      * is less than or equal to zero, or computing either
344      * <code>location.x + w</code> or
345      * <code>location.y + h</code> results in integer
346      * overflow
347      * @throws IllegalArgumentException if <code>dataType</code> is not
348      * one of the supported data types, which are
349      * <code>DataBuffer.TYPE_BYTE</code>,
350      * <code>DataBuffer.TYPE_USHORT</code>
351      * or <code>DataBuffer.TYPE_INT</code>
352      * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code>
353      * or <code>bandOffsets</code> is <code>null</code>
354      */

355     public static WritableRaster JavaDoc createBandedRaster(int dataType,
356                                                     int w, int h,
357                                                     int scanlineStride,
358                                                     int bankIndices[],
359                                                     int bandOffsets[],
360                                                     Point JavaDoc location) {
361     DataBuffer JavaDoc d;
362         int bands = bandOffsets.length;
363
364         if (bankIndices == null) {
365             throw new
366                 ArrayIndexOutOfBoundsException JavaDoc("Bank indices array is null");
367         }
368         if (bandOffsets == null) {
369             throw new
370                 ArrayIndexOutOfBoundsException JavaDoc("Band offsets array is null");
371         }
372
373         // Figure out the #banks and the largest band offset
374
int maxBank = bankIndices[0];
375         int maxBandOff = bandOffsets[0];
376         for (int i = 1; i < bands; i++) {
377             if (bankIndices[i] > maxBank) {
378                 maxBank = bankIndices[i];
379             }
380             if (bandOffsets[i] > maxBandOff) {
381                 maxBandOff = bandOffsets[i];
382             }
383         }
384         int banks = maxBank + 1;
385         int size = maxBandOff + scanlineStride*(h-1) + (w-1) + 1;
386
387         switch(dataType) {
388         case DataBuffer.TYPE_BYTE:
389             d = new DataBufferByte JavaDoc(size, banks);
390             break;
391
392         case DataBuffer.TYPE_USHORT:
393             d = new DataBufferUShort JavaDoc(size, banks);
394             break;
395
396         case DataBuffer.TYPE_INT:
397             d = new DataBufferInt JavaDoc(size, banks);
398             break;
399
400         default:
401             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
402                                                 dataType);
403         }
404
405         SunWritableRaster raster = (SunWritableRaster)
406             createBandedRaster(d, w, h, scanlineStride,
407                                bankIndices, bandOffsets, location);
408         raster.setStolen(false);
409         return raster;
410     }
411
412     /**
413      * Creates a Raster based on a SinglePixelPackedSampleModel with
414      * the specified data type, width, height, and band masks.
415      * The number of bands is inferred from bandMasks.length.
416      *
417      * <p> The upper left corner of the Raster is given by the
418      * location argument. If location is null, (0, 0) will be used.
419      * The dataType parameter should be one of the enumerated values
420      * defined in the DataBuffer class.
421      *
422      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
423      * and TYPE_INT.
424      * @param dataType the data type for storing samples
425      * @param w the width in pixels of the image data
426      * @param h the height in pixels of the image data
427      * @param bandMasks an array containing an entry for each band
428      * @param location the upper-left corner of the <code>Raster</code>
429      * @return a WritableRaster object with the specified data type,
430      * width, height, and band masks.
431      * @throws RasterFormatException if <code>w</code> or <code>h</code>
432      * is less than or equal to zero, or computing either
433      * <code>location.x + w</code> or
434      * <code>location.y + h</code> results in integer
435      * overflow
436      * @throws IllegalArgumentException if <code>dataType</code> is not
437      * one of the supported data types, which are
438      * <code>DataBuffer.TYPE_BYTE</code>,
439      * <code>DataBuffer.TYPE_USHORT</code>
440      * or <code>DataBuffer.TYPE_INT</code>
441      */

442     public static WritableRaster JavaDoc createPackedRaster(int dataType,
443                                                     int w, int h,
444                                                     int bandMasks[],
445                                                     Point JavaDoc location) {
446         DataBuffer JavaDoc d;
447
448         switch(dataType) {
449         case DataBuffer.TYPE_BYTE:
450             d = new DataBufferByte JavaDoc(w*h);
451             break;
452
453         case DataBuffer.TYPE_USHORT:
454             d = new DataBufferUShort JavaDoc(w*h);
455             break;
456
457         case DataBuffer.TYPE_INT:
458             d = new DataBufferInt JavaDoc(w*h);
459             break;
460
461         default:
462             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
463                                                 dataType);
464         }
465
466         SunWritableRaster raster = (SunWritableRaster)
467             createPackedRaster(d, w, h, w, bandMasks, location);
468         raster.setStolen(false);
469         return raster;
470     }
471
472     /**
473      * Creates a Raster based on a packed SampleModel with the
474      * specified data type, width, height, number of bands, and bits
475      * per band. If the number of bands is one, the SampleModel will
476      * be a MultiPixelPackedSampleModel.
477      *
478      * <p> If the number of bands is more than one, the SampleModel
479      * will be a SinglePixelPackedSampleModel, with each band having
480      * bitsPerBand bits. In either case, the requirements on dataType
481      * and bitsPerBand imposed by the corresponding SampleModel must
482      * be met.
483      *
484      * <p> The upper left corner of the Raster is given by the
485      * location argument. If location is null, (0, 0) will be used.
486      * The dataType parameter should be one of the enumerated values
487      * defined in the DataBuffer class.
488      *
489      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
490      * and TYPE_INT.
491      * @param dataType the data type for storing samples
492      * @param w the width in pixels of the image data
493      * @param h the height in pixels of the image data
494      * @param bands the number of bands
495      * @param bitsPerBand the number of bits per band
496      * @param location the upper-left corner of the <code>Raster</code>
497      * @return a WritableRaster object with the specified data type,
498      * width, height, number of bands, and bits per band.
499      * @throws RasterFormatException if <code>w</code> or <code>h</code>
500      * is less than or equal to zero, or computing either
501      * <code>location.x + w</code> or
502      * <code>location.y + h</code> results in integer
503      * overflow
504      * @throws IllegalArgumentException if the product of
505      * <code>bitsPerBand</code> and <code>bands</code> is
506      * greater than the number of bits held by
507      * <code>dataType</code>
508      * @throws IllegalArgumentException if <code>bitsPerBand</code> or
509      * <code>bands</code> is not greater than zero
510      * @throws IllegalArgumentException if <code>dataType</code> is not
511      * one of the supported data types, which are
512      * <code>DataBuffer.TYPE_BYTE</code>,
513      * <code>DataBuffer.TYPE_USHORT</code>
514      * or <code>DataBuffer.TYPE_INT</code>
515      */

516     public static WritableRaster JavaDoc createPackedRaster(int dataType,
517                                                     int w, int h,
518                                                     int bands,
519                                                     int bitsPerBand,
520                                                     Point JavaDoc location) {
521         DataBuffer JavaDoc d;
522
523         if (bands <= 0) {
524             throw new IllegalArgumentException JavaDoc("Number of bands ("+bands+
525                                                ") must be greater than 0");
526         }
527
528         if (bitsPerBand <= 0) {
529             throw new IllegalArgumentException JavaDoc("Bits per band ("+bitsPerBand+
530                                                ") must be greater than 0");
531         }
532         
533         if (bands != 1) {
534             int[] masks = new int[bands];
535             int mask = (1 << bitsPerBand) - 1;
536             int shift = (bands-1)*bitsPerBand;
537
538             /* Make sure the total mask size will fit in the data type */
539             if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
540                 throw new IllegalArgumentException JavaDoc("bitsPerBand("+
541                                                    bitsPerBand+") * bands is "+
542                                                    " greater than data type "+
543                                                    "size.");
544             }
545             switch(dataType) {
546             case DataBuffer.TYPE_BYTE:
547             case DataBuffer.TYPE_USHORT:
548             case DataBuffer.TYPE_INT:
549                 break;
550             default:
551                 throw new IllegalArgumentException JavaDoc("Unsupported data type " +
552                                                     dataType);
553             }
554
555             for (int i = 0; i < bands; i++) {
556                 masks[i] = mask << shift;
557                 shift = shift - bitsPerBand;
558             }
559
560             return createPackedRaster(dataType, w, h, masks, location);
561         }
562         else {
563             double fw = w;
564             switch(dataType) {
565             case DataBuffer.TYPE_BYTE:
566                 d = new DataBufferByte JavaDoc((int)(Math.ceil(fw/(8/bitsPerBand)))*h);
567                 break;
568
569             case DataBuffer.TYPE_USHORT:
570                 d = new DataBufferUShort JavaDoc((int)(Math.ceil(fw/(16/bitsPerBand)))*h);
571                 break;
572
573             case DataBuffer.TYPE_INT:
574                 d = new DataBufferInt JavaDoc((int)(Math.ceil(fw/(32/bitsPerBand)))*h);
575                 break;
576
577             default:
578                 throw new IllegalArgumentException JavaDoc("Unsupported data type " +
579                                                    dataType);
580             }
581
582             SunWritableRaster raster = (SunWritableRaster)
583                 createPackedRaster(d, w, h, bitsPerBand, location);
584             raster.setStolen(false);
585             return raster;
586         }
587     }
588
589     /**
590      * Creates a Raster based on a PixelInterleavedSampleModel with the
591      * specified DataBuffer, width, height, scanline stride, pixel
592      * stride, and band offsets. The number of bands is inferred from
593      * bandOffsets.length. The upper left corner of the Raster
594      * is given by the location argument. If location is null, (0, 0)
595      * will be used.
596      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
597      * Rasters are not supported. To create a 1-band Raster of type
598      * <code>DataBuffer.TYPE_INT</code>, use
599      * Raster.createPackedRaster().
600      * @param dataBuffer the <code>DataBuffer</code> that contains the
601      * image data
602      * @param w the width in pixels of the image data
603      * @param h the height in pixels of the image data
604      * @param scanlineStride the line stride of the image data
605      * @param pixelStride the pixel stride of the image data
606      * @param bandOffsets the offsets of all bands
607      * @param location the upper-left corner of the <code>Raster</code>
608      * @return a WritableRaster object with the specified
609      * <code>DataBuffer</code>, width, height, scanline stride,
610      * pixel stride and band offsets.
611      * @throws RasterFormatException if <code>w</code> or <code>h</code>
612      * is less than or equal to zero, or computing either
613      * <code>location.x + w</code> or
614      * <code>location.y + h</code> results in integer
615      * overflow
616      * @throws IllegalArgumentException if <code>dataType</code> is not
617      * one of the supported data types, which are
618      * <code>DataBuffer.TYPE_BYTE</code>,
619      * <code>DataBuffer.TYPE_USHORT</code>
620      * @throws RasterFormatException if <code>dataBuffer</code> has more
621      * than one bank.
622      * @throws NullPointerException if <code>dataBuffer</code> is null
623      */

624     public static WritableRaster JavaDoc createInterleavedRaster(DataBuffer JavaDoc dataBuffer,
625                                                          int w, int h,
626                                                          int scanlineStride,
627                                                          int pixelStride,
628                                                          int bandOffsets[],
629                                                          Point JavaDoc location) {
630         if (dataBuffer == null) {
631             throw new NullPointerException JavaDoc("DataBuffer cannot be null");
632         }
633         if (location == null) {
634             location = new Point JavaDoc(0, 0);
635         }
636         int dataType = dataBuffer.getDataType();
637
638         PixelInterleavedSampleModel JavaDoc csm =
639             new PixelInterleavedSampleModel JavaDoc(dataType, w, h,
640                                             pixelStride,
641                                             scanlineStride,
642                                             bandOffsets);
643         switch(dataType) {
644         case DataBuffer.TYPE_BYTE:
645             return new ByteInterleavedRaster(csm, dataBuffer, location);
646
647         case DataBuffer.TYPE_USHORT:
648             return new ShortInterleavedRaster(csm, dataBuffer, location);
649
650         default:
651             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
652                                                 dataType);
653         }
654     }
655
656     /**
657      * Creates a Raster based on a BandedSampleModel with the
658      * specified DataBuffer, width, height, scanline stride, bank
659      * indices, and band offsets. The number of bands is inferred
660      * from bankIndices.length and bandOffsets.length, which must be
661      * the same. The upper left corner of the Raster is given by the
662      * location argument. If location is null, (0, 0) will be used.
663      * @param dataBuffer the <code>DataBuffer</code> that contains the
664      * image data
665      * @param w the width in pixels of the image data
666      * @param h the height in pixels of the image data
667      * @param scanlineStride the line stride of the image data
668      * @param bankIndices the bank indices for each band
669      * @param bandOffsets the offsets of all bands
670      * @param location the upper-left corner of the <code>Raster</code>
671      * @return a WritableRaster object with the specified
672      * <code>DataBuffer</code>, width, height, scanline stride,
673      * bank indices and band offsets.
674      * @throws RasterFormatException if <code>w</code> or <code>h</code>
675      * is less than or equal to zero, or computing either
676      * <code>location.x + w</code> or
677      * <code>location.y + h</code> results in integer
678      * overflow
679      * @throws IllegalArgumentException if <code>dataType</code> is not
680      * one of the supported data types, which are
681      * <code>DataBuffer.TYPE_BYTE</code>,
682      * <code>DataBuffer.TYPE_USHORT</code>
683      * or <code>DataBuffer.TYPE_INT</code>
684      * @throws NullPointerException if <code>dataBuffer</code> is null
685      */

686     public static WritableRaster JavaDoc createBandedRaster(DataBuffer JavaDoc dataBuffer,
687                                                     int w, int h,
688                                                     int scanlineStride,
689                                                     int bankIndices[],
690                                                     int bandOffsets[],
691                                                     Point JavaDoc location) {
692         if (dataBuffer == null) {
693             throw new NullPointerException JavaDoc("DataBuffer cannot be null");
694         }
695         if (location == null) {
696            location = new Point JavaDoc(0,0);
697         }
698         int dataType = dataBuffer.getDataType();
699
700         int bands = bankIndices.length;
701         if (bandOffsets.length != bands) {
702             throw new IllegalArgumentException JavaDoc(
703                                    "bankIndices.length != bandOffsets.length");
704         }
705
706         BandedSampleModel JavaDoc bsm =
707             new BandedSampleModel JavaDoc(dataType, w, h,
708                                   scanlineStride,
709                                   bankIndices, bandOffsets);
710
711         switch(dataType) {
712         case DataBuffer.TYPE_BYTE:
713             return new ByteBandedRaster(bsm, dataBuffer, location);
714
715         case DataBuffer.TYPE_USHORT:
716             return new ShortBandedRaster(bsm, dataBuffer, location);
717
718         case DataBuffer.TYPE_INT:
719             return new SunWritableRaster(bsm, dataBuffer, location);
720
721         default:
722             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
723                                                 dataType);
724         }
725     }
726
727     /**
728      * Creates a Raster based on a SinglePixelPackedSampleModel with
729      * the specified DataBuffer, width, height, scanline stride, and
730      * band masks. The number of bands is inferred from bandMasks.length.
731      * The upper left corner of the Raster is given by
732      * the location argument. If location is null, (0, 0) will be used.
733      * @param dataBuffer the <code>DataBuffer</code> that contains the
734      * image data
735      * @param w the width in pixels of the image data
736      * @param h the height in pixels of the image data
737      * @param scanlineStride the line stride of the image data
738      * @param bandMasks an array containing an entry for each band
739      * @param location the upper-left corner of the <code>Raster</code>
740      * @return a WritableRaster object with the specified
741      * <code>DataBuffer</code>, width, height, scanline stride,
742      * and band masks.
743      * @throws RasterFormatException if <code>w</code> or <code>h</code>
744      * is less than or equal to zero, or computing either
745      * <code>location.x + w</code> or
746      * <code>location.y + h</code> results in integer
747      * overflow
748      * @throws IllegalArgumentException if <code>dataType</code> is not
749      * one of the supported data types, which are
750      * <code>DataBuffer.TYPE_BYTE</code>,
751      * <code>DataBuffer.TYPE_USHORT</code>
752      * or <code>DataBuffer.TYPE_INT</code>
753      * @throws RasterFormatException if <code>dataBuffer</code> has more
754      * than one bank.
755      * @throws NullPointerException if <code>dataBuffer</code> is null
756      */

757     public static WritableRaster JavaDoc createPackedRaster(DataBuffer JavaDoc dataBuffer,
758                                                     int w, int h,
759                                                     int scanlineStride,
760                                                     int bandMasks[],
761                                                     Point JavaDoc location) {
762         if (dataBuffer == null) {
763             throw new NullPointerException JavaDoc("DataBuffer cannot be null");
764         }
765         if (location == null) {
766            location = new Point JavaDoc(0,0);
767         }
768         int dataType = dataBuffer.getDataType();
769
770         SinglePixelPackedSampleModel JavaDoc sppsm =
771             new SinglePixelPackedSampleModel JavaDoc(dataType, w, h, scanlineStride,
772                                              bandMasks);
773
774         switch(dataType) {
775         case DataBuffer.TYPE_BYTE:
776             return new ByteInterleavedRaster(sppsm, dataBuffer, location);
777
778         case DataBuffer.TYPE_USHORT:
779             return new ShortInterleavedRaster(sppsm, dataBuffer, location);
780
781         case DataBuffer.TYPE_INT:
782             return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
783
784         default:
785             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
786                                                 dataType);
787         }
788     }
789
790     /**
791      * Creates a Raster based on a MultiPixelPackedSampleModel with the
792      * specified DataBuffer, width, height, and bits per pixel. The upper
793      * left corner of the Raster is given by the location argument. If
794      * location is null, (0, 0) will be used.
795      * @param dataBuffer the <code>DataBuffer</code> that contains the
796      * image data
797      * @param w the width in pixels of the image data
798      * @param h the height in pixels of the image data
799      * @param bitsPerPixel the number of bits for each pixel
800      * @param location the upper-left corner of the <code>Raster</code>
801      * @return a WritableRaster object with the specified
802      * <code>DataBuffer</code>, width, height, and
803      * bits per pixel.
804      * @throws RasterFormatException if <code>w</code> or <code>h</code>
805      * is less than or equal to zero, or computing either
806      * <code>location.x + w</code> or
807      * <code>location.y + h</code> results in integer
808      * overflow
809      * @throws IllegalArgumentException if <code>dataType</code> is not
810      * one of the supported data types, which are
811      * <code>DataBuffer.TYPE_BYTE</code>,
812      * <code>DataBuffer.TYPE_USHORT</code>
813      * or <code>DataBuffer.TYPE_INT</code>
814      * @throws RasterFormatException if <code>dataBuffer</code> has more
815      * than one bank.
816      * @throws NullPointerException if <code>dataBuffer</code> is null
817      */

818     public static WritableRaster JavaDoc createPackedRaster(DataBuffer JavaDoc dataBuffer,
819                                                     int w, int h,
820                                                     int bitsPerPixel,
821                                                     Point JavaDoc location) {
822         if (dataBuffer == null) {
823             throw new NullPointerException JavaDoc("DataBuffer cannot be null");
824         }
825         if (location == null) {
826            location = new Point JavaDoc(0,0);
827         }
828         int dataType = dataBuffer.getDataType();
829
830         if (dataType != DataBuffer.TYPE_BYTE &&
831             dataType != DataBuffer.TYPE_USHORT &&
832             dataType != DataBuffer.TYPE_INT) {
833             throw new IllegalArgumentException JavaDoc("Unsupported data type " +
834                                                dataType);
835         }
836
837         if (dataBuffer.getNumBanks() != 1) {
838             throw new
839                 RasterFormatException JavaDoc("DataBuffer for packed Rasters"+
840                                       " must only have 1 bank.");
841         }
842         
843         MultiPixelPackedSampleModel JavaDoc mppsm =
844                 new MultiPixelPackedSampleModel JavaDoc(dataType, w, h, bitsPerPixel);
845
846         if (dataType == DataBuffer.TYPE_BYTE &&
847             (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
848             return new BytePackedRaster(mppsm, dataBuffer, location);
849         } else {
850             return new SunWritableRaster(mppsm, dataBuffer, location);
851         }
852     }
853
854
855     /**
856      * Creates a Raster with the specified SampleModel and DataBuffer.
857      * The upper left corner of the Raster is given by the location argument.
858      * If location is null, (0, 0) will be used.
859      * @param sm the specified <code>SampleModel</code>
860      * @param db the specified <code>DataBuffer</code>
861      * @param location the upper-left corner of the <code>Raster</code>
862      * @return a <code>Raster</code> with the specified
863      * <code>SampleModel</code>, <code>DataBuffer</code>, and
864      * location.
865      * @throws RasterFormatException if computing either
866      * <code>location.x + sm.getWidth()</code> or
867      * <code>location.y + sm.getHeight()</code> results in integer
868      * overflow
869      * @throws RasterFormatException if <code>dataBuffer</code> has more
870      * than one bank and the <code>sampleModel</code> is
871      * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
872      * or MultiPixelPackedSampleModel.
873      * @throws NullPointerException if either SampleModel or DataBuffer is
874      * null
875      */

876     public static Raster JavaDoc createRaster(SampleModel JavaDoc sm,
877                                       DataBuffer JavaDoc db,
878                                       Point JavaDoc location) {
879         if ((sm == null) || (db == null)) {
880             throw new NullPointerException JavaDoc("SampleModel and DataBuffer cannot be null");
881         }
882         
883         if (location == null) {
884            location = new Point JavaDoc(0,0);
885         }
886         int dataType = sm.getDataType();
887
888         if (sm instanceof PixelInterleavedSampleModel JavaDoc) {
889             switch(dataType) {
890                 case DataBuffer.TYPE_BYTE:
891                     return new ByteInterleavedRaster(sm, db, location);
892
893                 case DataBuffer.TYPE_USHORT:
894                     return new ShortInterleavedRaster(sm, db, location);
895             }
896         } else if (sm instanceof SinglePixelPackedSampleModel JavaDoc) {
897             switch(dataType) {
898                 case DataBuffer.TYPE_BYTE:
899                     return new ByteInterleavedRaster(sm, db, location);
900
901                 case DataBuffer.TYPE_USHORT:
902                     return new ShortInterleavedRaster(sm, db, location);
903
904                 case DataBuffer.TYPE_INT:
905                     return new IntegerInterleavedRaster(sm, db, location);
906             }
907         } else if (sm instanceof MultiPixelPackedSampleModel JavaDoc &&
908                    dataType == DataBuffer.TYPE_BYTE &&
909                    sm.getSampleSize(0) < 8) {
910             return new BytePackedRaster(sm, db, location);
911         }
912
913         // we couldn't do anything special - do the generic thing
914

915         return new Raster JavaDoc(sm,db,location);
916     }
917
918     /**
919      * Creates a WritableRaster with the specified SampleModel.
920      * The upper left corner of the Raster is given by the location argument.
921      * If location is null, (0, 0) will be used.
922      * @param sm the specified <code>SampleModel</code>
923      * @param location the upper-left corner of the
924      * <code>WritableRaster</code>
925      * @return a <code>WritableRaster</code> with the specified
926      * <code>SampleModel</code> and location.
927      * @throws RasterFormatException if computing either
928      * <code>location.x + sm.getWidth()</code> or
929      * <code>location.y + sm.getHeight()</code> results in integer
930      * overflow
931      */

932     public static WritableRaster JavaDoc createWritableRaster(SampleModel JavaDoc sm,
933                                                       Point JavaDoc location) {
934         if (location == null) {
935            location = new Point JavaDoc(0,0);
936         }
937
938         SunWritableRaster raster = (SunWritableRaster)
939             createWritableRaster(sm, sm.createDataBuffer(), location);
940         raster.setStolen(false);
941         return raster;
942     }
943
944     /**
945      * Creates a WritableRaster with the specified SampleModel and DataBuffer.
946      * The upper left corner of the Raster is given by the location argument.
947      * If location is null, (0, 0) will be used.
948      * @param sm the specified <code>SampleModel</code>
949      * @param db the specified <code>DataBuffer</code>
950      * @param location the upper-left corner of the
951      * <code>WritableRaster</code>
952      * @return a <code>WritableRaster</code> with the specified
953      * <code>SampleModel</code>, <code>DataBuffer</code>, and
954      * location.
955      * @throws RasterFormatException if computing either
956      * <code>location.x + sm.getWidth()</code> or
957      * <code>location.y + sm.getHeight()</code> results in integer
958      * overflow
959      * @throws RasterFormatException if <code>dataBuffer</code> has more
960      * than one bank and the <code>sampleModel</code> is
961      * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
962      * or MultiPixelPackedSampleModel.
963      * @throws NullPointerException if either SampleModel or DataBuffer is null
964      */

965     public static WritableRaster JavaDoc createWritableRaster(SampleModel JavaDoc sm,
966                                                       DataBuffer JavaDoc db,
967                                                       Point JavaDoc location) {
968         if ((sm == null) || (db == null)) {
969             throw new NullPointerException JavaDoc("SampleModel and DataBuffer cannot be null");
970         }
971         if (location == null) {
972            location = new Point JavaDoc(0,0);
973         }
974
975         int dataType = sm.getDataType();
976
977         if (sm instanceof PixelInterleavedSampleModel JavaDoc) {
978             switch(dataType) {
979                 case DataBuffer.TYPE_BYTE:
980                     return new ByteInterleavedRaster(sm, db, location);
981
982                 case DataBuffer.TYPE_USHORT:
983                     return new ShortInterleavedRaster(sm, db, location);
984             }
985         } else if (sm instanceof SinglePixelPackedSampleModel JavaDoc) {
986             switch(dataType) {
987                 case DataBuffer.TYPE_BYTE:
988                     return new ByteInterleavedRaster(sm, db, location);
989
990                 case DataBuffer.TYPE_USHORT:
991                     return new ShortInterleavedRaster(sm, db, location);
992
993                 case DataBuffer.TYPE_INT:
994                     return new IntegerInterleavedRaster(sm, db, location);
995             }
996         } else if (sm instanceof MultiPixelPackedSampleModel JavaDoc &&
997                    dataType == DataBuffer.TYPE_BYTE &&
998                    sm.getSampleSize(0) < 8) {
999             return new BytePackedRaster(sm, db, location);
1000        }
1001
1002        // we couldn't do anything special - do the generic thing
1003

1004        return new SunWritableRaster(sm,db,location);
1005    }
1006
1007    /**
1008     * Constructs a Raster with the given SampleModel. The Raster's
1009     * upper left corner is origin and it is the same size as the
1010     * SampleModel. A DataBuffer large enough to describe the
1011     * Raster is automatically created.
1012     * @param sampleModel The SampleModel that specifies the layout
1013     * @param origin The Point that specified the origin
1014     * @throws RasterFormatException if computing either
1015     * <code>origin.x + sampleModel.getWidth()</code> or
1016     * <code>origin.y + sampleModel.getHeight()</code> results in
1017     * integer overflow
1018     * @throws NullPointerException either <code>sampleModel</code> or
1019     * <code>origin</code> is null
1020     */

1021    protected Raster(SampleModel JavaDoc sampleModel,
1022                     Point JavaDoc origin) {
1023        this(sampleModel,
1024             sampleModel.createDataBuffer(),
1025             new Rectangle JavaDoc(origin.x,
1026                           origin.y,
1027                           sampleModel.getWidth(),
1028                           sampleModel.getHeight()),
1029             origin,
1030             null);
1031    }
1032
1033    /**
1034     * Constructs a Raster with the given SampleModel and DataBuffer.
1035     * The Raster's upper left corner is origin and it is the same size
1036     * as the SampleModel. The DataBuffer is not initialized and must
1037     * be compatible with SampleModel.
1038     * @param sampleModel The SampleModel that specifies the layout
1039     * @param dataBuffer The DataBuffer that contains the image data
1040     * @param origin The Point that specifies the origin
1041     * @throws RasterFormatException if computing either
1042     * <code>origin.x + sampleModel.getWidth()</code> or
1043     * <code>origin.y + sampleModel.getHeight()</code> results in
1044     * integer overflow
1045     * @throws NullPointerException either <code>sampleModel</code> or
1046     * <code>origin</code> is null
1047     */

1048    protected Raster(SampleModel JavaDoc sampleModel,
1049                     DataBuffer JavaDoc dataBuffer,
1050                     Point JavaDoc origin) {
1051    this(sampleModel,
1052             dataBuffer,
1053             new Rectangle JavaDoc(origin.x,
1054                           origin.y,
1055                           sampleModel.getWidth(),
1056                           sampleModel.getHeight()),
1057             origin,
1058             null);
1059    }
1060
1061    /**
1062     * Constructs a Raster with the given SampleModel, DataBuffer, and
1063     * parent. aRegion specifies the bounding rectangle of the new
1064     * Raster. When translated into the base Raster's coordinate
1065     * system, aRegion must be contained by the base Raster.
1066     * (The base Raster is the Raster's ancestor which has no parent.)
1067     * sampleModelTranslate specifies the sampleModelTranslateX and
1068     * sampleModelTranslateY values of the new Raster.
1069     *
1070     * Note that this constructor should generally be called by other
1071     * constructors or create methods, it should not be used directly.
1072     * @param sampleModel The SampleModel that specifies the layout
1073     * @param dataBuffer The DataBuffer that contains the image data
1074     * @param aRegion The Rectangle that specifies the image area
1075     * @param sampleModelTranslate The Point that specifies the translation
1076     * from SampleModel to Raster coordinates
1077     * @param parent The parent (if any) of this raster
1078     * @throws NullPointerException if any of <code>sampleModel</code>,
1079     * <code>dataBuffer</code>, <code>aRegion</code> or
1080     * <code>sampleModelTranslate</code> is null
1081     * @throws RasterFormatException if <code>aRegion</code> has width
1082     * or height less than or equal to zero, or computing either
1083     * <code>aRegion.x + aRegion.width</code> or
1084     * <code>aRegion.y + aRegion.height</code> results in integer
1085     * overflow
1086     */

1087    protected Raster(SampleModel JavaDoc sampleModel,
1088                     DataBuffer JavaDoc dataBuffer,
1089                     Rectangle JavaDoc aRegion,
1090                     Point JavaDoc sampleModelTranslate,
1091                 Raster JavaDoc parent) {
1092        
1093        if ((sampleModel == null) || (dataBuffer == null) ||
1094            (aRegion == null) || (sampleModelTranslate == null)) {
1095            throw new NullPointerException JavaDoc("SampleModel, dataBuffer, aRegion and " +
1096                                           "sampleModelTranslate cannot be null");
1097        }
1098       this.sampleModel = sampleModel;
1099       this.dataBuffer = dataBuffer;
1100       minX = aRegion.x;
1101       minY = aRegion.y;
1102       width = aRegion.width;
1103       height = aRegion.height;
1104       if (width <= 0 || height <= 0) {
1105           throw new RasterFormatException JavaDoc("negative or zero " +
1106               ((width <= 0) ? "width" : "height"));
1107       }
1108       if ((minX + width) < minX) {
1109           throw new RasterFormatException JavaDoc(
1110               "overflow condition for X coordinates of Raster");
1111       }
1112       if ((minY + height) < minY) {
1113           throw new RasterFormatException JavaDoc(
1114               "overflow condition for Y coordinates of Raster");
1115       }
1116 
1117       sampleModelTranslateX = sampleModelTranslate.x;
1118       sampleModelTranslateY = sampleModelTranslate.y;
1119
1120       numBands = sampleModel.getNumBands();
1121       numDataElements = sampleModel.getNumDataElements();
1122       this.parent = parent;
1123    }
1124
1125
1126    /**
1127     * Returns the parent Raster (if any) of this Raster or null.
1128     * @return the parent Raster or <code>null</code>.
1129     */

1130    public Raster JavaDoc getParent() {
1131        return parent;
1132    }
1133
1134    /**
1135     * Returns the X translation from the coordinate system of the
1136     * SampleModel to that of the Raster. To convert a pixel's X
1137     * coordinate from the Raster coordinate system to the SampleModel
1138     * coordinate system, this value must be subtracted.
1139     * @return the X translation from the coordinate space of the
1140     * Raster's SampleModel to that of the Raster.
1141     */

1142    final public int getSampleModelTranslateX() {
1143    return sampleModelTranslateX;
1144    }
1145
1146    /**
1147     * Returns the Y translation from the coordinate system of the
1148     * SampleModel to that of the Raster. To convert a pixel's Y
1149     * coordinate from the Raster coordinate system to the SampleModel
1150     * coordinate system, this value must be subtracted.
1151     * @return the Y translation from the coordinate space of the
1152     * Raster's SampleModel to that of the Raster.
1153     */

1154    final public int getSampleModelTranslateY() {
1155    return sampleModelTranslateY;
1156    }
1157
1158    /**
1159     * Create a compatible WritableRaster the same size as this Raster with
1160     * the same SampleModel and a new initialized DataBuffer.
1161     * @return a compatible <code>WritableRaster</code> with the same sample
1162     * model and a new data buffer.
1163     */

1164    public WritableRaster JavaDoc createCompatibleWritableRaster() {
1165        return new SunWritableRaster(sampleModel, new Point JavaDoc(0,0));
1166    }
1167
1168    /**
1169     * Create a compatible WritableRaster with the specified size, a new
1170     * SampleModel, and a new initialized DataBuffer.
1171     * @param w the specified width of the new <code>WritableRaster</code>
1172     * @param h the specified height of the new <code>WritableRaster</code>
1173     * @return a compatible <code>WritableRaster</code> with the specified
1174     * size and a new sample model and data buffer.
1175     * @exception RasterFormatException if the width or height is less than
1176     * or equal to zero.
1177     */

1178    public WritableRaster JavaDoc createCompatibleWritableRaster(int w, int h) {
1179        if (w <= 0 || h <=0) {
1180            throw new RasterFormatException JavaDoc("negative " +
1181                                          ((w <= 0) ? "width" : "height"));
1182        }
1183
1184        SampleModel JavaDoc sm = sampleModel.createCompatibleSampleModel(w,h);
1185
1186        return new SunWritableRaster(sm, new Point JavaDoc(0,0));
1187    }
1188
1189    /**
1190     * Create a compatible WritableRaster with location (minX, minY)
1191     * and size (width, height) specified by rect, a
1192     * new SampleModel, and a new initialized DataBuffer.
1193     * @param rect a <code>Rectangle</code> that specifies the size and
1194     * location of the <code>WritableRaster</code>
1195     * @return a compatible <code>WritableRaster</code> with the specified
1196     * size and location and a new sample model and data buffer.
1197     * @throws RasterFormatException if <code>rect</code> has width
1198     * or height less than or equal to zero, or computing either
1199     * <code>rect.x + rect.width</code> or
1200     * <code>rect.y + rect.height</code> results in integer
1201     * overflow
1202     * @throws NullPointerException if <code>rect<code> is null
1203     */

1204    public WritableRaster JavaDoc createCompatibleWritableRaster(Rectangle JavaDoc rect) {
1205        if (rect == null) {
1206            throw new NullPointerException JavaDoc("Rect cannot be null");
1207        }
1208        return createCompatibleWritableRaster(rect.x, rect.y,
1209                                              rect.width, rect.height);
1210    }
1211
1212    /**
1213     * Create a compatible WritableRaster with the specified
1214     * location (minX, minY) and size (width, height), a
1215     * new SampleModel, and a new initialized DataBuffer.
1216     * @param x,&nbsp;y the coordinates of the upper-left corner of
1217     * the <code>WritableRaster</code>
1218     * @param w the specified width of the <code>WritableRaster</code>
1219     * @param h the specified height of the <code>WritableRaster</code>
1220     * @return a compatible <code>WritableRaster</code> with the specified
1221     * size and location and a new sample model and data buffer.
1222     * @throws RasterFormatException if <code>w</code> or <code>h</code>
1223     * is less than or equal to zero, or computing either
1224     * <code>x + w</code> or
1225     * <code>y + h</code> results in integer
1226     * overflow
1227     */

1228    public WritableRaster JavaDoc createCompatibleWritableRaster(int x, int y,
1229                                                         int w, int h) {
1230        WritableRaster JavaDoc ret = createCompatibleWritableRaster(w, h);
1231        return ret.createWritableChild(0,0,w,h,x,y,null);
1232    }
1233
1234    /**
1235     * Create a Raster with the same size, SampleModel and DataBuffer
1236     * as this one, but with a different location. The new Raster
1237     * will possess a reference to the current Raster, accessible
1238     * through its getParent() method.
1239     *
1240     * @param childMinX,&nbsp;childMinY coordinates of the upper-left
1241     * corner of the new <code>Raster</code>
1242     * @return a new <code>Raster</code> with the same size, SampleModel,
1243     * and DataBuffer as this <code>Raster</code>, but with the
1244     * specified location.
1245     * @throws RasterFormatException if computing either
1246     * <code>childMinX + this.getWidth()</code> or
1247     * <code>childMinY + this.getHeight()</code> results in integer
1248     * overflow
1249     */

1250    public Raster JavaDoc createTranslatedChild(int childMinX, int childMinY) {
1251        return createChild(minX,minY,width,height,
1252                           childMinX,childMinY,null);
1253    }
1254
1255    /**
1256     * Returns a new Raster which shares all or part of this Raster's
1257     * DataBuffer. The new Raster will possess a reference to the
1258     * current Raster, accessible through its getParent() method.
1259     *
1260     * <p> The parentX, parentY, width and height parameters
1261     * form a Rectangle in this Raster's coordinate space,
1262     * indicating the area of pixels to be shared. An error will
1263     * be thrown if this Rectangle is not contained with the bounds
1264     * of the current Raster.
1265     *
1266     * <p> The new Raster may additionally be translated to a
1267     * different coordinate system for the plane than that used by the current
1268     * Raster. The childMinX and childMinY parameters give the new
1269     * (x, y) coordinate of the upper-left pixel of the returned
1270     * Raster; the coordinate (childMinX, childMinY) in the new Raster
1271     * will map to the same pixel as the coordinate (parentX, parentY)
1272     * in the current Raster.
1273     *
1274     * <p> The new Raster may be defined to contain only a subset of
1275     * the bands of the current Raster, possibly reordered, by means
1276     * of the bandList parameter. If bandList is null, it is taken to
1277     * include all of the bands of the current Raster in their current
1278     * order.
1279     *
1280     * <p> To create a new Raster that contains a subregion of the current
1281     * Raster, but shares its coordinate system and bands,
1282     * this method should be called with childMinX equal to parentX,
1283     * childMinY equal to parentY, and bandList equal to null.
1284     *
1285     * @param parentX,&nbsp;parentY coordinates of the upper-left corner
1286     * in this Raster's coordinates
1287     * @param width Width of the region starting at (parentX, parentY)
1288     * @param height Height of the region starting at (parentX, parentY).
1289     * @param childMinX,&nbsp;childMinY coordinates of the upper-left corner
1290     * of the returned Raster
1291     * @param bandList Array of band indices, or null to use all bands
1292     * @return a new <code>Raster</code>.
1293     * @exception RasterFormatException if the specified subregion is outside
1294     * of the raster bounds.
1295     * @throws RasterFormatException if <code>width</code> or
1296     * <code>height</code>
1297     * is less than or equal to zero, or computing any of
1298     * <code>parentX + width</code>, <code>parentY + height</code>,
1299     * <code>childMinX + width</code>, or
1300     * <code>childMinY + height</code> results in integer
1301     * overflow
1302     */

1303    public Raster JavaDoc createChild(int parentX, int parentY,
1304                              int width, int height,
1305                              int childMinX, int childMinY,
1306                              int bandList[]) {
1307        if (parentX < this.minX) {
1308            throw new RasterFormatException JavaDoc("parentX lies outside raster");
1309        }
1310        if (parentY < this.minY) {
1311            throw new RasterFormatException JavaDoc("parentY lies outside raster");
1312        }
1313        if ((parentX + width < parentX) ||
1314            (parentX + width > this.width + this.minX)) {
1315            throw new RasterFormatException JavaDoc("(parentX + width) is outside raster");
1316        }
1317        if ((parentY + height < parentY) ||
1318            (parentY + height > this.height + this.minY)) {
1319            throw new RasterFormatException JavaDoc("(parentY + height) is outside raster");
1320        }
1321
1322        SampleModel JavaDoc subSampleModel;
1323        // Note: the SampleModel for the child Raster should have the same
1324
// width and height as that for the parent, since it represents
1325
// the physical layout of the pixel data. The child Raster's width
1326
// and height represent a "virtual" view of the pixel data, so
1327
// they may be different than those of the SampleModel.
1328
if (bandList == null) {
1329            subSampleModel = sampleModel;
1330        } else {
1331            subSampleModel = sampleModel.createSubsetSampleModel(bandList);
1332        }
1333
1334        int deltaX = childMinX - parentX;
1335        int deltaY = childMinY - parentY;
1336
1337        // we use getDataBuffer() here, which will ensure that notifyStolen()
1338
// is invoked if this is a SunWritableRaster, thus disabling future
1339
// acceleration of this WritableRaster
1340
return new Raster JavaDoc(subSampleModel, getDataBuffer(),
1341              new Rectangle JavaDoc(childMinX, childMinY, width, height),
1342              new Point JavaDoc(sampleModelTranslateX + deltaX,
1343                    sampleModelTranslateY + deltaY), this);
1344    }
1345
1346    /**
1347     * Returns the bounding Rectangle of this Raster. This function returns
1348     * the same information as getMinX/MinY/Width/Height.
1349     * @return the bounding box of this <code>Raster</code>.
1350     */

1351    public Rectangle JavaDoc getBounds() {
1352        return new Rectangle JavaDoc(minX, minY, width, height);
1353    }
1354
1355    /** Returns the minimum valid X coordinate of the Raster.
1356     * @return the minimum x coordinate of this <code>Raster</code>.
1357     */

1358    final public int getMinX() {
1359        return minX;
1360    }
1361
1362    /** Returns the minimum valid Y coordinate of the Raster.
1363     * @return the minimum y coordinate of this <code>Raster</code>.
1364     */

1365    final public int getMinY() {
1366        return minY;
1367    }
1368
1369    /** Returns the width in pixels of the Raster.
1370     * @return the width of this <code>Raster</code>.
1371     */

1372    final public int getWidth() {
1373        return width;
1374    }
1375
1376    /** Returns the height in pixels of the Raster.
1377     * @return the height of this <code>Raster</code>.
1378     */

1379    final public int getHeight() {
1380        return height;
1381    }
1382
1383    /** Returns the number of bands (samples per pixel) in this Raster.
1384     * @return the number of bands of this <code>Raster</code>.
1385     */

1386    final public int getNumBands() {
1387        return numBands;
1388    }
1389
1390    /**
1391     * Returns the number of data elements needed to transfer one pixel
1392     * via the getDataElements and setDataElements methods. When pixels
1393     * are transferred via these methods, they may be transferred in a
1394     * packed or unpacked format, depending on the implementation of the
1395     * underlying SampleModel. Using these methods, pixels are transferred
1396     * as an array of getNumDataElements() elements of a primitive type given
1397     * by getTransferType(). The TransferType may or may not be the same
1398     * as the storage data type of the DataBuffer.
1399     * @return the number of data elements.
1400     */

1401    final public int getNumDataElements() {
1402        return sampleModel.getNumDataElements();
1403    }
1404
1405    /**
1406     * Returns the TransferType used to transfer pixels via the
1407     * getDataElements and setDataElements methods. When pixels
1408     * are transferred via these methods, they may be transferred in a
1409     * packed or unpacked format, depending on the implementation of the
1410     * underlying SampleModel. Using these methods, pixels are transferred
1411     * as an array of getNumDataElements() elements of a primitive type given
1412     * by getTransferType(). The TransferType may or may not be the same
1413     * as the storage data type of the DataBuffer. The TransferType will
1414     * be one of the types defined in DataBuffer.
1415     * @return this transfer type.
1416     */

1417    final public int getTransferType() {
1418        return sampleModel.getTransferType();
1419    }
1420
1421    /** Returns the DataBuffer associated with this Raster.
1422     * @return the <code>DataBuffer</code> of this <code>Raster</code>.
1423     */

1424    public DataBuffer JavaDoc getDataBuffer() {
1425        return dataBuffer;
1426    }
1427
1428    /** Returns the SampleModel that describes the layout of the image data.
1429     * @return the <code>SampleModel</code> of this <code>Raster</code>.
1430     */

1431    public SampleModel JavaDoc getSampleModel() {
1432        return sampleModel;
1433    }
1434
1435    /**
1436     * Returns data for a single pixel in a primitive array of type
1437     * TransferType. For image data supported by the Java 2D(tm) API,
1438     * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
1439     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
1440     * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
1441     * thus increasing efficiency for data transfers.
1442     * An ArrayIndexOutOfBoundsException may be thrown
1443     * if the coordinates are not in bounds. However, explicit bounds
1444     * checking is not guaranteed.
1445     * A ClassCastException will be thrown if the input object is non null
1446     * and references anything other than an array of TransferType.
1447     * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
1448     * @param x,&nbsp;y the coordinates of the pixel location
1449     * @param outData An object reference to an array of type defined by
1450     * getTransferType() and length getNumDataElements().
1451     * If null, an array of appropriate type and size will be
1452     * allocated
1453     * @return An object reference to an array of type defined by
1454     * getTransferType() with the requested pixel data.
1455     *
1456     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1457     * in bounds, or if outData is too small to hold the output.
1458     */

1459    public Object JavaDoc getDataElements(int x, int y, Object JavaDoc outData) {
1460        return sampleModel.getDataElements(x - sampleModelTranslateX,
1461                                           y - sampleModelTranslateY,
1462                                           outData, dataBuffer);
1463    }
1464
1465    /**
1466     * Returns the pixel data for the specified rectangle of pixels in a
1467     * primitive array of type TransferType.
1468     * For image data supported by the Java 2D API, this
1469     * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
1470     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
1471     * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
1472     * thus increasing efficiency for data transfers.
1473     * An ArrayIndexOutOfBoundsException may be thrown
1474     * if the coordinates are not in bounds. However, explicit bounds
1475     * checking is not guaranteed.
1476     * A ClassCastException will be thrown if the input object is non null
1477     * and references anything other than an array of TransferType.
1478     * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
1479     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1480     * @param w Width of the pixel rectangle
1481     * @param h Height of the pixel rectangle
1482     * @param outData An object reference to an array of type defined by
1483     * getTransferType() and length w*h*getNumDataElements().
1484     * If null, an array of appropriate type and size will be
1485     * allocated.
1486     * @return An object reference to an array of type defined by
1487     * getTransferType() with the requested pixel data.
1488     *
1489     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1490     * in bounds, or if outData is too small to hold the output.
1491     */

1492    public Object JavaDoc getDataElements(int x, int y, int w, int h, Object JavaDoc outData) {
1493        return sampleModel.getDataElements(x - sampleModelTranslateX,
1494                                           y - sampleModelTranslateY,
1495                                           w, h, outData, dataBuffer);
1496    }
1497
1498    /**
1499     * Returns the samples in an array of int for the specified pixel.
1500     * An ArrayIndexOutOfBoundsException may be thrown
1501     * if the coordinates are not in bounds. However, explicit bounds
1502     * checking is not guaranteed.
1503     * @param x,&nbsp;y the coordinates of the pixel location
1504     * @param iArray An optionally preallocated int array
1505     * @return the samples for the specified pixel.
1506     *
1507     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1508     * in bounds, or if iArray is too small to hold the output.
1509     */

1510    public int[] getPixel(int x, int y, int iArray[]) {
1511        return sampleModel.getPixel(x - sampleModelTranslateX,
1512                    y - sampleModelTranslateY,
1513                                    iArray, dataBuffer);
1514    }
1515
1516    /**
1517     * Returns the samples in an array of float for the
1518     * specified pixel.
1519     * An ArrayIndexOutOfBoundsException may be thrown
1520     * if the coordinates are not in bounds. However, explicit bounds
1521     * checking is not guaranteed.
1522     * @param x,&nbsp;y the coordinates of the pixel location
1523     * @param fArray An optionally preallocated float array
1524     * @return the samples for the specified pixel.
1525     *
1526     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1527     * in bounds, or if fArray is too small to hold the output.
1528     */

1529    public float[] getPixel(int x, int y, float fArray[]) {
1530        return sampleModel.getPixel(x - sampleModelTranslateX,
1531                    y - sampleModelTranslateY,
1532                                    fArray, dataBuffer);
1533    }
1534  
1535    /**
1536     * Returns the samples in an array of double for the specified pixel.
1537     * An ArrayIndexOutOfBoundsException may be thrown
1538     * if the coordinates are not in bounds. However, explicit bounds
1539     * checking is not guaranteed.
1540     * @param x,&nbsp;y the coordinates of the pixel location
1541     * @param dArray An optionally preallocated double array
1542     * @return the samples for the specified pixel.
1543     *
1544     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1545     * in bounds, or if dArray is too small to hold the output.
1546     */

1547    public double[] getPixel(int x, int y, double dArray[]) {
1548        return sampleModel.getPixel(x - sampleModelTranslateX,
1549                    y - sampleModelTranslateY,
1550                    dArray, dataBuffer);
1551    }
1552  
1553    /**
1554     * Returns an int array containing all samples for a rectangle of pixels,
1555     * one sample per array element.
1556     * An ArrayIndexOutOfBoundsException may be thrown
1557     * if the coordinates are not in bounds. However, explicit bounds
1558     * checking is not guaranteed.
1559     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1560     * @param w Width of the pixel rectangle
1561     * @param h Height of the pixel rectangle
1562     * @param iArray An optionally pre-allocated int array
1563     * @return the samples for the specified rectangle of pixels.
1564     *
1565     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1566     * in bounds, or if iArray is too small to hold the output.
1567     */

1568    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
1569        return sampleModel.getPixels(x - sampleModelTranslateX,
1570                                     y - sampleModelTranslateY, w, h,
1571                                     iArray, dataBuffer);
1572    }
1573
1574    /**
1575     * Returns a float array containing all samples for a rectangle of pixels,
1576     * one sample per array element.
1577     * An ArrayIndexOutOfBoundsException may be thrown
1578     * if the coordinates are not in bounds. However, explicit bounds
1579     * checking is not guaranteed.
1580     * @param x,&nbsp;y the coordinates of the pixel location
1581     * @param w Width of the pixel rectangle
1582     * @param h Height of the pixel rectangle
1583     * @param fArray An optionally pre-allocated float array
1584     * @return the samples for the specified rectangle of pixels.
1585     *
1586     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1587     * in bounds, or if fArray is too small to hold the output.
1588     */

1589    public float[] getPixels(int x, int y, int w, int h,
1590                             float fArray[]) {
1591        return sampleModel.getPixels(x - sampleModelTranslateX,
1592                                     y - sampleModelTranslateY, w, h,
1593                                     fArray, dataBuffer);
1594    }
1595
1596    /**
1597     * Returns a double array containing all samples for a rectangle of pixels,
1598     * one sample per array element.
1599     * An ArrayIndexOutOfBoundsException may be thrown
1600     * if the coordinates are not in bounds. However, explicit bounds
1601     * checking is not guaranteed.
1602     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1603     * @param w Width of the pixel rectangle
1604     * @param h Height of the pixel rectangle
1605     * @param dArray An optionally pre-allocated double array
1606     * @return the samples for the specified rectangle of pixels.
1607     *
1608     * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1609     * in bounds, or if dArray is too small to hold the output.
1610     */

1611    public double[] getPixels(int x, int y, int w, int h,
1612                              double dArray[]) {
1613        return sampleModel.getPixels(x - sampleModelTranslateX,
1614                                     y - sampleModelTranslateY,
1615                                     w, h, dArray, dataBuffer);
1616    }
1617  
1618  
1619    /**
1620     * Returns the sample in a specified band for the pixel located
1621     * at (x,y) as an int.
1622     * An ArrayIndexOutOfBoundsException may be thrown
1623     * if the coordinates are not in bounds. However, explicit bounds
1624     * checking is not guaranteed.
1625     * @param x,&nbsp;y the coordinates of the pixel location
1626     * @param b The band to return
1627     * @return the sample in the specified band for the pixel at the
1628     * specified coordinate.
1629     *
1630     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1631     * the band index are not in bounds.
1632     */

1633    public int getSample(int x, int y, int b) {
1634        return sampleModel.getSample(x - sampleModelTranslateX,
1635                     y - sampleModelTranslateY, b,
1636                     dataBuffer);
1637    }
1638    
1639    /**
1640     * Returns the sample in a specified band
1641     * for the pixel located at (x,y) as a float.
1642     * An ArrayIndexOutOfBoundsException may be thrown
1643     * if the coordinates are not in bounds. However, explicit bounds
1644     * checking is not guaranteed.
1645     * @param x,&nbsp;y the coordinates of the pixel location
1646     * @param b The band to return
1647     * @return the sample in the specified band for the pixel at the
1648     * specified coordinate.
1649     *
1650     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1651     * the band index are not in bounds.
1652     */

1653    public float getSampleFloat(int x, int y, int b) {
1654        return sampleModel.getSampleFloat(x - sampleModelTranslateX,
1655                      y - sampleModelTranslateY, b,
1656                      dataBuffer);
1657    }
1658  
1659    /**
1660     * Returns the sample in a specified band
1661     * for a pixel located at (x,y) as a double.
1662     * An ArrayIndexOutOfBoundsException may be thrown
1663     * if the coordinates are not in bounds. However, explicit bounds
1664     * checking is not guaranteed.
1665     * @param x,&nbsp;y the coordinates of the pixel location
1666     * @param b The band to return
1667     * @return the sample in the specified band for the pixel at the
1668     * specified coordinate.
1669     *
1670     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1671     * the band index are not in bounds.
1672     */

1673    public double getSampleDouble(int x, int y, int b) {
1674        return sampleModel.getSampleDouble(x - sampleModelTranslateX,
1675                       y - sampleModelTranslateY,
1676                       b, dataBuffer);
1677    }
1678  
1679    /**
1680     * Returns the samples for a specified band for the specified rectangle
1681     * of pixels in an int array, one sample per array element.
1682     * An ArrayIndexOutOfBoundsException may be thrown
1683     * if the coordinates are not in bounds. However, explicit bounds
1684     * checking is not guaranteed.
1685     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1686     * @param w Width of the pixel rectangle
1687     * @param h Height of the pixel rectangle
1688     * @param b The band to return
1689     * @param iArray An optionally pre-allocated int array
1690     * @return the samples for the specified band for the specified
1691     * rectangle of pixels.
1692     *
1693     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1694     * the band index are not in bounds, or if iArray is too small to
1695     * hold the output.
1696     */

1697    public int[] getSamples(int x, int y, int w, int h, int b,
1698                            int iArray[]) {
1699        return sampleModel.getSamples(x - sampleModelTranslateX,
1700                                      y - sampleModelTranslateY,
1701                                      w, h, b, iArray,
1702                                      dataBuffer);
1703    }
1704
1705    /**
1706     * Returns the samples for a specified band for the specified rectangle
1707     * of pixels in a float array, one sample per array element.
1708     * An ArrayIndexOutOfBoundsException may be thrown
1709     * if the coordinates are not in bounds. However, explicit bounds
1710     * checking is not guaranteed.
1711     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1712     * @param w Width of the pixel rectangle
1713     * @param h Height of the pixel rectangle
1714     * @param b The band to return
1715     * @param fArray An optionally pre-allocated float array
1716     * @return the samples for the specified band for the specified
1717     * rectangle of pixels.
1718     *
1719     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1720     * the band index are not in bounds, or if fArray is too small to
1721     * hold the output.
1722     */

1723    public float[] getSamples(int x, int y, int w, int h, int b,
1724                              float fArray[]) {
1725        return sampleModel.getSamples(x - sampleModelTranslateX,
1726                                      y - sampleModelTranslateY,
1727                                      w, h, b, fArray, dataBuffer);
1728    }
1729
1730    /**
1731     * Returns the samples for a specified band for a specified rectangle
1732     * of pixels in a double array, one sample per array element.
1733     * An ArrayIndexOutOfBoundsException may be thrown
1734     * if the coordinates are not in bounds. However, explicit bounds
1735     * checking is not guaranteed.
1736     * @param x,&nbsp;y the coordinates of the upper-left pixel location
1737     * @param w Width of the pixel rectangle
1738     * @param h Height of the pixel rectangle
1739     * @param b The band to return
1740     * @param dArray An optionally pre-allocated double array
1741     * @return the samples for the specified band for the specified
1742     * rectangle of pixels.
1743     *
1744     * @throws ArrayIndexOutOfBoundsException if the coordinates or
1745     * the band index are not in bounds, or if dArray is too small to
1746     * hold the output.
1747     */

1748    public double[] getSamples(int x, int y, int w, int h, int b,
1749                               double dArray[]) {
1750         return sampleModel.getSamples(x - sampleModelTranslateX,
1751                                       y - sampleModelTranslateY,
1752                                       w, h, b, dArray, dataBuffer);
1753    }
1754
1755}
1756
Popular Tags