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