1 /*
2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /* ****************************************************************
27  ******************************************************************
28  ******************************************************************
29  *** COPYRIGHT (c) Eastman Kodak Company, 1997
30  *** As  an unpublished  work pursuant to Title 17 of the United
31  *** States Code.  All rights reserved.
32  ******************************************************************
33  ******************************************************************
34  ******************************************************************/
35 
36 
37 package java.awt.image;
38 import java.awt.Rectangle;
39 import java.awt.Point;
40 
41 import sun.awt.image.ByteInterleavedRaster;
42 import sun.awt.image.ShortInterleavedRaster;
43 import sun.awt.image.IntegerInterleavedRaster;
44 import sun.awt.image.ByteBandedRaster;
45 import sun.awt.image.ShortBandedRaster;
46 import sun.awt.image.BytePackedRaster;
47 import sun.awt.image.SunWritableRaster;
48 
49 /**
50  * A class representing a rectangular array of pixels.  A Raster
51  * encapsulates a DataBuffer that stores the sample values and a
52  * SampleModel that describes how to locate a given sample value in a
53  * DataBuffer.
54  * <p>
55  * A Raster defines values for pixels occupying a particular
56  * rectangular area of the plane, not necessarily including (0, 0).
57  * The rectangle, known as the Raster's bounding rectangle and
58  * available by means of the getBounds method, is defined by minX,
59  * minY, width, and height values.  The minX and minY values define
60  * the coordinate of the upper left corner of the Raster.  References
61  * to pixels outside of the bounding rectangle may result in an
62  * exception being thrown, or may result in references to unintended
63  * elements of the Raster's associated DataBuffer.  It is the user's
64  * responsibility to avoid accessing such pixels.
65  * <p>
66  * A SampleModel describes how samples of a Raster
67  * are stored in the primitive array elements of a DataBuffer.
68  * Samples may be stored one per data element, as in a
69  * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
70  * an element, as in a SinglePixelPackedSampleModel or
71  * MultiPixelPackedSampleModel.  The SampleModel is also
72  * controls whether samples are sign extended, allowing unsigned
73  * data to be stored in signed Java data types such as byte, short, and
74  * int.
75  * <p>
76  * Although a Raster may live anywhere in the plane, a SampleModel
77  * makes use of a simple coordinate system that starts at (0, 0).  A
78  * Raster therefore contains a translation factor that allows pixel
79  * locations to be mapped between the Raster's coordinate system and
80  * that of the SampleModel.  The translation from the SampleModel
81  * coordinate system to that of the Raster may be obtained by the
82  * getSampleModelTranslateX and getSampleModelTranslateY methods.
83  * <p>
84  * A Raster may share a DataBuffer with another Raster either by
85  * explicit construction or by the use of the createChild and
86  * createTranslatedChild methods.  Rasters created by these methods
87  * can return a reference to the Raster they were created from by
88  * means of the getParent method.  For a Raster that was not
89  * constructed by means of a call to createTranslatedChild or
90  * createChild, getParent will return null.
91  * <p>
92  * The createTranslatedChild method returns a new Raster that
93  * shares all of the data of the current Raster, but occupies a
94  * bounding rectangle of the same width and height but with a
95  * different starting point.  For example, if the parent Raster
96  * occupied the region (10, 10) to (100, 100), and the translated
97  * Raster was defined to start at (50, 50), then pixel (20, 20) of the
98  * parent and pixel (60, 60) of the child occupy the same location in
99  * the DataBuffer shared by the two Rasters.  In the first case, (-10,
100  * -10) should be added to a pixel coordinate to obtain the
101  * corresponding SampleModel coordinate, and in the second case (-50,
102  * -50) should be added.
103  * <p>
104  * The translation between a parent and child Raster may be
105  * determined by subtracting the child's sampleModelTranslateX and
106  * sampleModelTranslateY values from those of the parent.
107  * <p>
108  * The createChild method may be used to create a new Raster
109  * occupying only a subset of its parent's bounding rectangle
110  * (with the same or a translated coordinate system) or
111  * with a subset of the bands of its parent.
112  * <p>
113  * All constructors are protected.  The correct way to create a
114  * Raster is to use one of the static create methods defined in this
115  * class.  These methods create instances of Raster that use the
116  * standard Interleaved, Banded, and Packed SampleModels and that may
117  * be processed more efficiently than a Raster created by combining
118  * an externally generated SampleModel and DataBuffer.
119  * @see java.awt.image.DataBuffer
120  * @see java.awt.image.SampleModel
121  * @see java.awt.image.PixelInterleavedSampleModel
122  * @see java.awt.image.BandedSampleModel
123  * @see java.awt.image.SinglePixelPackedSampleModel
124  * @see java.awt.image.MultiPixelPackedSampleModel
125  */
126 public class Raster {
127 
128     /**
129      * The SampleModel that describes how pixels from this Raster
130      * are stored in the DataBuffer.
131      */
132     protected SampleModel sampleModel;
133 
134     /** The DataBuffer that stores the image data. */
135     protected DataBuffer dataBuffer;
136 
137     /** The X coordinate of the upper-left pixel of this Raster. */
138     protected int minX;
139 
140     /** The Y coordinate of the upper-left pixel of this Raster. */
141     protected int minY;
142 
143     /** The width of this Raster. */
144     protected int width;
145 
146     /** The height of this Raster. */
147     protected int height;
148 
149     /**
150      * The X translation from the coordinate space of the
151      * Raster's SampleModel to that of the Raster.
152      */
153     protected int sampleModelTranslateX;
154 
155     /**
156      * The Y translation from the coordinate space of the
157      * Raster's SampleModel to that of the Raster.
158      */
159     protected int sampleModelTranslateY;
160 
161     /** The number of bands in the Raster. */
162     protected int numBands;
163 
164     /** The number of DataBuffer data elements per pixel. */
165     protected int numDataElements;
166 
167     /** The parent of this Raster, or null. */
168     protected Raster parent;
169 
initIDs()170     private static native void initIDs();
171     static {
ColorModel.loadLibraries()172         ColorModel.loadLibraries();
initIDs()173         initIDs();
174     }
175 
176     /**
177      * Creates a Raster based on a PixelInterleavedSampleModel with the
178      * specified data type, width, height, and number of bands.
179      *
180      * <p> The upper left corner of the Raster is given by the
181      * location argument.  If location is null, (0, 0) will be used.
182      * The dataType parameter should be one of the enumerated values
183      * defined in the DataBuffer class.
184      *
185      * <p> Note that interleaved {@code DataBuffer.TYPE_INT}
186      * Rasters are not supported.  To create a 1-band Raster of type
187      * {@code DataBuffer.TYPE_INT}, use
188      * Raster.createPackedRaster().
189      * <p> The only dataTypes supported currently are TYPE_BYTE
190      * and TYPE_USHORT.
191      * @param dataType  the data type for storing samples
192      * @param w         the width in pixels of the image data
193      * @param h         the height in pixels of the image data
194      * @param bands     the number of bands
195      * @param location  the upper-left corner of the {@code Raster}
196      * @return a WritableRaster object with the specified data type,
197      *         width, height and number of bands.
198      * @throws RasterFormatException if {@code w} or {@code h}
199      *         is less than or equal to zero, or computing either
200      *         {@code location.x + w} or
201      *         {@code location.y + h} results in integer
202      *         overflow
203      */
createInterleavedRaster(int dataType, int w, int h, int bands, Point location)204     public static WritableRaster createInterleavedRaster(int dataType,
205                                                          int w, int h,
206                                                          int bands,
207                                                          Point location) {
208         int[] bandOffsets = new int[bands];
209         for (int i = 0; i < bands; i++) {
210             bandOffsets[i] = i;
211         }
212         return createInterleavedRaster(dataType, w, h, w*bands, bands,
213                                        bandOffsets, location);
214     }
215 
216     /**
217      * Creates a Raster based on a PixelInterleavedSampleModel with the
218      * specified data type, width, height, scanline stride, pixel
219      * stride, and band offsets.  The number of bands is inferred from
220      * bandOffsets.length.
221      *
222      * <p> The upper left corner of the Raster is given by the
223      * location argument.  If location is null, (0, 0) will be used.
224      * The dataType parameter should be one of the enumerated values
225      * defined in the DataBuffer class.
226      *
227      * <p> Note that interleaved {@code DataBuffer.TYPE_INT}
228      * Rasters are not supported.  To create a 1-band Raster of type
229      * {@code DataBuffer.TYPE_INT}, use
230      * Raster.createPackedRaster().
231      * <p> The only dataTypes supported currently are TYPE_BYTE
232      * and TYPE_USHORT.
233      * @param dataType  the data type for storing samples
234      * @param w         the width in pixels of the image data
235      * @param h         the height in pixels of the image data
236      * @param scanlineStride the line stride of the image data
237      * @param pixelStride the pixel stride of the image data
238      * @param bandOffsets the offsets of all bands
239      * @param location  the upper-left corner of the {@code Raster}
240      * @return a WritableRaster object with the specified data type,
241      *         width, height, scanline stride, pixel stride and band
242      *         offsets.
243      * @throws RasterFormatException if {@code w} or {@code h}
244      *         is less than or equal to zero, or computing either
245      *         {@code location.x + w} or
246      *         {@code location.y + h} results in integer
247      *         overflow
248      * @throws IllegalArgumentException if {@code dataType} is not
249      *         one of the supported data types, which are
250      *         {@code DataBuffer.TYPE_BYTE}, or
251      *         {@code DataBuffer.TYPE_USHORT}.
252      */
createInterleavedRaster(int dataType, int w, int h, int scanlineStride, int pixelStride, int bandOffsets[], Point location)253     public static WritableRaster createInterleavedRaster(int dataType,
254                                                          int w, int h,
255                                                          int scanlineStride,
256                                                          int pixelStride,
257                                                          int bandOffsets[],
258                                                          Point location) {
259         DataBuffer d;
260 
261         int size = scanlineStride * (h - 1) + // fisrt (h - 1) scans
262             pixelStride * w; // last scan
263 
264         switch(dataType) {
265         case DataBuffer.TYPE_BYTE:
266             d = new DataBufferByte(size);
267             break;
268 
269         case DataBuffer.TYPE_USHORT:
270             d = new DataBufferUShort(size);
271             break;
272 
273         default:
274             throw new IllegalArgumentException("Unsupported data type " +
275                                                 dataType);
276         }
277 
278         return createInterleavedRaster(d, w, h, scanlineStride,
279                                        pixelStride, bandOffsets, location);
280     }
281 
282     /**
283      * Creates a Raster based on a BandedSampleModel with the
284      * specified data type, width, height, and number of bands.
285      *
286      * <p> The upper left corner of the Raster is given by the
287      * location argument.  If location is null, (0, 0) will be used.
288      * The dataType parameter should be one of the enumerated values
289      * defined in the DataBuffer class.
290      *
291      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
292      * and TYPE_INT.
293      * @param dataType  the data type for storing samples
294      * @param w         the width in pixels of the image data
295      * @param h         the height in pixels of the image data
296      * @param bands     the number of bands
297      * @param location  the upper-left corner of the {@code Raster}
298      * @return a WritableRaster object with the specified data type,
299      *         width, height and number of bands.
300      * @throws RasterFormatException if {@code w} or {@code h}
301      *         is less than or equal to zero, or computing either
302      *         {@code location.x + w} or
303      *         {@code location.y + h} results in integer
304      *         overflow
305      * @throws ArrayIndexOutOfBoundsException if {@code bands}
306      *         is less than 1
307      */
createBandedRaster(int dataType, int w, int h, int bands, Point location)308     public static WritableRaster createBandedRaster(int dataType,
309                                                     int w, int h,
310                                                     int bands,
311                                                     Point location) {
312         if (bands < 1) {
313             throw new ArrayIndexOutOfBoundsException("Number of bands ("+
314                                                      bands+") must"+
315                                                      " be greater than 0");
316         }
317         int[] bankIndices = new int[bands];
318         int[] bandOffsets = new int[bands];
319         for (int i = 0; i < bands; i++) {
320             bankIndices[i] = i;
321             bandOffsets[i] = 0;
322         }
323 
324         return createBandedRaster(dataType, w, h, w,
325                                   bankIndices, bandOffsets,
326                                   location);
327     }
328 
329     /**
330      * Creates a Raster based on a BandedSampleModel with the
331      * specified data type, width, height, scanline stride, bank
332      * indices and band offsets.  The number of bands is inferred from
333      * bankIndices.length and bandOffsets.length, which must be the
334      * same.
335      *
336      * <p> The upper left corner of the Raster is given by the
337      * location argument.  The dataType parameter should be one of the
338      * enumerated values defined in the DataBuffer class.
339      *
340      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
341      * and TYPE_INT.
342      * @param dataType  the data type for storing samples
343      * @param w         the width in pixels of the image data
344      * @param h         the height in pixels of the image data
345      * @param scanlineStride the line stride of the image data
346      * @param bankIndices the bank indices for each band
347      * @param bandOffsets the offsets of all bands
348      * @param location  the upper-left corner of the {@code Raster}
349      * @return a WritableRaster object with the specified data type,
350      *         width, height, scanline stride, bank indices and band
351      *         offsets.
352      * @throws RasterFormatException if {@code w} or {@code h}
353      *         is less than or equal to zero, or computing either
354      *         {@code location.x + w} or
355      *         {@code location.y + h} results in integer
356      *         overflow
357      * @throws IllegalArgumentException if {@code dataType} is not
358      *         one of the supported data types, which are
359      *         {@code DataBuffer.TYPE_BYTE},
360      *         {@code DataBuffer.TYPE_USHORT}
361      *         or {@code DataBuffer.TYPE_INT}
362      * @throws ArrayIndexOutOfBoundsException if {@code bankIndices}
363      *         or {@code bandOffsets} is {@code null}
364      */
createBandedRaster(int dataType, int w, int h, int scanlineStride, int bankIndices[], int bandOffsets[], Point location)365     public static WritableRaster createBandedRaster(int dataType,
366                                                     int w, int h,
367                                                     int scanlineStride,
368                                                     int bankIndices[],
369                                                     int bandOffsets[],
370                                                     Point location) {
371         DataBuffer d;
372         int bands = bandOffsets.length;
373 
374         if (bankIndices == null) {
375             throw new
376                 ArrayIndexOutOfBoundsException("Bank indices array is null");
377         }
378         if (bandOffsets == null) {
379             throw new
380                 ArrayIndexOutOfBoundsException("Band offsets array is null");
381         }
382 
383         // Figure out the #banks and the largest band offset
384         int maxBank = bankIndices[0];
385         int maxBandOff = bandOffsets[0];
386         for (int i = 1; i < bands; i++) {
387             if (bankIndices[i] > maxBank) {
388                 maxBank = bankIndices[i];
389             }
390             if (bandOffsets[i] > maxBandOff) {
391                 maxBandOff = bandOffsets[i];
392             }
393         }
394         int banks = maxBank + 1;
395         int size = maxBandOff +
396             scanlineStride * (h - 1) + // first (h - 1) scans
397             w; // last scan
398 
399         switch(dataType) {
400         case DataBuffer.TYPE_BYTE:
401             d = new DataBufferByte(size, banks);
402             break;
403 
404         case DataBuffer.TYPE_USHORT:
405             d = new DataBufferUShort(size, banks);
406             break;
407 
408         case DataBuffer.TYPE_INT:
409             d = new DataBufferInt(size, banks);
410             break;
411 
412         default:
413             throw new IllegalArgumentException("Unsupported data type " +
414                                                 dataType);
415         }
416 
417         return createBandedRaster(d, w, h, scanlineStride,
418                                   bankIndices, bandOffsets, location);
419     }
420 
421     /**
422      * Creates a Raster based on a SinglePixelPackedSampleModel with
423      * the specified data type, width, height, and band masks.
424      * The number of bands is inferred from bandMasks.length.
425      *
426      * <p> The upper left corner of the Raster is given by the
427      * location argument.  If location is null, (0, 0) will be used.
428      * The dataType parameter should be one of the enumerated values
429      * defined in the DataBuffer class.
430      *
431      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
432      * and TYPE_INT.
433      * @param dataType  the data type for storing samples
434      * @param w         the width in pixels of the image data
435      * @param h         the height in pixels of the image data
436      * @param bandMasks an array containing an entry for each band
437      * @param location  the upper-left corner of the {@code Raster}
438      * @return a WritableRaster object with the specified data type,
439      *         width, height, and band masks.
440      * @throws RasterFormatException if {@code w} or {@code h}
441      *         is less than or equal to zero, or computing either
442      *         {@code location.x + w} or
443      *         {@code location.y + h} results in integer
444      *         overflow
445      * @throws IllegalArgumentException if {@code dataType} is not
446      *         one of the supported data types, which are
447      *         {@code DataBuffer.TYPE_BYTE},
448      *         {@code DataBuffer.TYPE_USHORT}
449      *         or {@code DataBuffer.TYPE_INT}
450      */
createPackedRaster(int dataType, int w, int h, int bandMasks[], Point location)451     public static WritableRaster createPackedRaster(int dataType,
452                                                     int w, int h,
453                                                     int bandMasks[],
454                                                     Point location) {
455         DataBuffer d;
456 
457         switch(dataType) {
458         case DataBuffer.TYPE_BYTE:
459             d = new DataBufferByte(w*h);
460             break;
461 
462         case DataBuffer.TYPE_USHORT:
463             d = new DataBufferUShort(w*h);
464             break;
465 
466         case DataBuffer.TYPE_INT:
467             d = new DataBufferInt(w*h);
468             break;
469 
470         default:
471             throw new IllegalArgumentException("Unsupported data type " +
472                                                 dataType);
473         }
474 
475         return createPackedRaster(d, w, h, w, bandMasks, location);
476     }
477 
478     /**
479      * Creates a Raster based on a packed SampleModel with the
480      * specified data type, width, height, number of bands, and bits
481      * per band.  If the number of bands is one, the SampleModel will
482      * be a MultiPixelPackedSampleModel.
483      *
484      * <p> If the number of bands is more than one, the SampleModel
485      * will be a SinglePixelPackedSampleModel, with each band having
486      * bitsPerBand bits.  In either case, the requirements on dataType
487      * and bitsPerBand imposed by the corresponding SampleModel must
488      * be met.
489      *
490      * <p> The upper left corner of the Raster is given by the
491      * location argument.  If location is null, (0, 0) will be used.
492      * The dataType parameter should be one of the enumerated values
493      * defined in the DataBuffer class.
494      *
495      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
496      * and TYPE_INT.
497      * @param dataType  the data type for storing samples
498      * @param w         the width in pixels of the image data
499      * @param h         the height in pixels of the image data
500      * @param bands     the number of bands
501      * @param bitsPerBand the number of bits per band
502      * @param location  the upper-left corner of the {@code Raster}
503      * @return a WritableRaster object with the specified data type,
504      *         width, height, number of bands, and bits per band.
505      * @throws RasterFormatException if {@code w} or {@code h}
506      *         is less than or equal to zero, or computing either
507      *         {@code location.x + w} or
508      *         {@code location.y + h} results in integer
509      *         overflow
510      * @throws IllegalArgumentException if the product of
511      *         {@code bitsPerBand} and {@code bands} is
512      *         greater than the number of bits held by
513      *         {@code dataType}
514      * @throws IllegalArgumentException if {@code bitsPerBand} or
515      *         {@code bands} is not greater than zero
516      * @throws IllegalArgumentException if {@code dataType} is not
517      *         one of the supported data types, which are
518      *         {@code DataBuffer.TYPE_BYTE},
519      *         {@code DataBuffer.TYPE_USHORT}
520      *         or {@code DataBuffer.TYPE_INT}
521      */
createPackedRaster(int dataType, int w, int h, int bands, int bitsPerBand, Point location)522     public static WritableRaster createPackedRaster(int dataType,
523                                                     int w, int h,
524                                                     int bands,
525                                                     int bitsPerBand,
526                                                     Point location) {
527         DataBuffer d;
528 
529         if (bands <= 0) {
530             throw new IllegalArgumentException("Number of bands ("+bands+
531                                                ") must be greater than 0");
532         }
533 
534         if (bitsPerBand <= 0) {
535             throw new IllegalArgumentException("Bits per band ("+bitsPerBand+
536                                                ") must be greater than 0");
537         }
538 
539         if (bands != 1) {
540             int[] masks = new int[bands];
541             int mask = (1 << bitsPerBand) - 1;
542             int shift = (bands-1)*bitsPerBand;
543 
544             /* Make sure the total mask size will fit in the data type */
545             if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
546                 throw new IllegalArgumentException("bitsPerBand("+
547                                                    bitsPerBand+") * bands is "+
548                                                    " greater than data type "+
549                                                    "size.");
550             }
551             switch(dataType) {
552             case DataBuffer.TYPE_BYTE:
553             case DataBuffer.TYPE_USHORT:
554             case DataBuffer.TYPE_INT:
555                 break;
556             default:
557                 throw new IllegalArgumentException("Unsupported data type " +
558                                                     dataType);
559             }
560 
561             for (int i = 0; i < bands; i++) {
562                 masks[i] = mask << shift;
563                 shift = shift - bitsPerBand;
564             }
565 
566             return createPackedRaster(dataType, w, h, masks, location);
567         }
568         else {
569             double fw = w;
570             switch(dataType) {
571             case DataBuffer.TYPE_BYTE:
572                 d = new DataBufferByte((int)(Math.ceil(fw/(8/bitsPerBand)))*h);
573                 break;
574 
575             case DataBuffer.TYPE_USHORT:
576                 d = new DataBufferUShort((int)(Math.ceil(fw/(16/bitsPerBand)))*h);
577                 break;
578 
579             case DataBuffer.TYPE_INT:
580                 d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h);
581                 break;
582 
583             default:
584                 throw new IllegalArgumentException("Unsupported data type " +
585                                                    dataType);
586             }
587 
588             return createPackedRaster(d, w, h, bitsPerBand, location);
589         }
590     }
591 
592     /**
593      * Creates a Raster based on a PixelInterleavedSampleModel with the
594      * specified DataBuffer, width, height, scanline stride, pixel
595      * stride, and band offsets.  The number of bands is inferred from
596      * bandOffsets.length.  The upper left corner of the Raster
597      * is given by the location argument.  If location is null, (0, 0)
598      * will be used.
599      * <p> Note that interleaved {@code DataBuffer.TYPE_INT}
600      * Rasters are not supported.  To create a 1-band Raster of type
601      * {@code DataBuffer.TYPE_INT}, use
602      * Raster.createPackedRaster().
603      * @param dataBuffer the {@code DataBuffer} that contains the
604      *        image data
605      * @param w         the width in pixels of the image data
606      * @param h         the height in pixels of the image data
607      * @param scanlineStride the line stride of the image data
608      * @param pixelStride the pixel stride of the image data
609      * @param bandOffsets the offsets of all bands
610      * @param location  the upper-left corner of the {@code Raster}
611      * @return a WritableRaster object with the specified
612      *         {@code DataBuffer}, width, height, scanline stride,
613      *         pixel stride and band offsets.
614      * @throws RasterFormatException if {@code w} or {@code h}
615      *         is less than or equal to zero, or computing either
616      *         {@code location.x + w} or
617      *         {@code location.y + h} results in integer
618      *         overflow
619      * @throws IllegalArgumentException if {@code dataType} is not
620      *         one of the supported data types, which are
621      *         {@code DataBuffer.TYPE_BYTE},
622      *         {@code DataBuffer.TYPE_USHORT}
623      * @throws RasterFormatException if {@code dataBuffer} has more
624      *         than one bank.
625      * @throws NullPointerException if {@code dataBuffer} is null
626      */
createInterleavedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int pixelStride, int bandOffsets[], Point location)627     public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
628                                                          int w, int h,
629                                                          int scanlineStride,
630                                                          int pixelStride,
631                                                          int bandOffsets[],
632                                                          Point location)
633     {
634         if (dataBuffer == null) {
635             throw new NullPointerException("DataBuffer cannot be null");
636         }
637         if (location == null) {
638             location = new Point(0, 0);
639         }
640         int dataType = dataBuffer.getDataType();
641 
642         PixelInterleavedSampleModel csm =
643             new PixelInterleavedSampleModel(dataType, w, h,
644                                             pixelStride,
645                                             scanlineStride,
646                                             bandOffsets);
647         switch(dataType) {
648         case DataBuffer.TYPE_BYTE:
649             if (dataBuffer instanceof DataBufferByte) {
650                 return new ByteInterleavedRaster(csm,
651                         (DataBufferByte) dataBuffer, location);
652             }
653             break;
654 
655         case DataBuffer.TYPE_USHORT:
656             if (dataBuffer instanceof DataBufferUShort) {
657                 return new ShortInterleavedRaster(csm,
658                         (DataBufferUShort) dataBuffer, location);
659             }
660             break;
661 
662         default:
663             throw new IllegalArgumentException("Unsupported data type " +
664                                                 dataType);
665         }
666 
667         // Create the generic raster
668         return new SunWritableRaster(csm, dataBuffer, location);
669     }
670 
671     /**
672      * Creates a Raster based on a BandedSampleModel with the
673      * specified DataBuffer, width, height, scanline stride, bank
674      * indices, and band offsets.  The number of bands is inferred
675      * from bankIndices.length and bandOffsets.length, which must be
676      * the same.  The upper left corner of the Raster is given by the
677      * location argument.  If location is null, (0, 0) will be used.
678      * @param dataBuffer the {@code DataBuffer} that contains the
679      *        image data
680      * @param w         the width in pixels of the image data
681      * @param h         the height in pixels of the image data
682      * @param scanlineStride the line stride of the image data
683      * @param bankIndices the bank indices for each band
684      * @param bandOffsets the offsets of all bands
685      * @param location  the upper-left corner of the {@code Raster}
686      * @return a WritableRaster object with the specified
687      *         {@code DataBuffer}, width, height, scanline stride,
688      *         bank indices and band offsets.
689      * @throws RasterFormatException if {@code w} or {@code h}
690      *         is less than or equal to zero, or computing either
691      *         {@code location.x + w} or
692      *         {@code location.y + h} results in integer
693      *         overflow
694      * @throws IllegalArgumentException if {@code dataType} is not
695      *         one of the supported data types, which are
696      *         {@code DataBuffer.TYPE_BYTE},
697      *         {@code DataBuffer.TYPE_USHORT}
698      *         or {@code DataBuffer.TYPE_INT}
699      * @throws NullPointerException if {@code dataBuffer} is null
700      */
createBandedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int bankIndices[], int bandOffsets[], Point location)701     public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
702                                                     int w, int h,
703                                                     int scanlineStride,
704                                                     int bankIndices[],
705                                                     int bandOffsets[],
706                                                     Point location)
707     {
708         if (dataBuffer == null) {
709             throw new NullPointerException("DataBuffer cannot be null");
710         }
711         if (location == null) {
712            location = new Point(0,0);
713         }
714         int dataType = dataBuffer.getDataType();
715 
716         int bands = bankIndices.length;
717         if (bandOffsets.length != bands) {
718             throw new IllegalArgumentException(
719                                    "bankIndices.length != bandOffsets.length");
720         }
721 
722         BandedSampleModel bsm =
723             new BandedSampleModel(dataType, w, h,
724                                   scanlineStride,
725                                   bankIndices, bandOffsets);
726 
727         switch(dataType) {
728         case DataBuffer.TYPE_BYTE:
729             if (dataBuffer instanceof DataBufferByte) {
730                 return new ByteBandedRaster(bsm,
731                         (DataBufferByte) dataBuffer, location);
732             }
733             break;
734 
735         case DataBuffer.TYPE_USHORT:
736             if (dataBuffer instanceof DataBufferUShort) {
737                 return new ShortBandedRaster(bsm,
738                         (DataBufferUShort) dataBuffer, location);
739             }
740             break;
741 
742         case DataBuffer.TYPE_INT:
743             break;
744 
745         default:
746             throw new IllegalArgumentException("Unsupported data type " +
747                                                 dataType);
748         }
749 
750         // Create the generic raster
751         return new SunWritableRaster(bsm, dataBuffer, location);
752     }
753 
754     /**
755      * Creates a Raster based on a SinglePixelPackedSampleModel with
756      * the specified DataBuffer, width, height, scanline stride, and
757      * band masks.  The number of bands is inferred from bandMasks.length.
758      * The upper left corner of the Raster is given by
759      * the location argument.  If location is null, (0, 0) will be used.
760      * @param dataBuffer the {@code DataBuffer} that contains the
761      *        image data
762      * @param w         the width in pixels of the image data
763      * @param h         the height in pixels of the image data
764      * @param scanlineStride the line stride of the image data
765      * @param bandMasks an array containing an entry for each band
766      * @param location  the upper-left corner of the {@code Raster}
767      * @return a WritableRaster object with the specified
768      *         {@code DataBuffer}, width, height, scanline stride,
769      *         and band masks.
770      * @throws RasterFormatException if {@code w} or {@code h}
771      *         is less than or equal to zero, or computing either
772      *         {@code location.x + w} or
773      *         {@code location.y + h} results in integer
774      *         overflow
775      * @throws IllegalArgumentException if {@code dataType} is not
776      *         one of the supported data types, which are
777      *         {@code DataBuffer.TYPE_BYTE},
778      *         {@code DataBuffer.TYPE_USHORT}
779      *         or {@code DataBuffer.TYPE_INT}
780      * @throws RasterFormatException if {@code dataBuffer} has more
781      *         than one bank.
782      * @throws NullPointerException if {@code dataBuffer} is null
783      */
createPackedRaster(DataBuffer dataBuffer, int w, int h, int scanlineStride, int bandMasks[], Point location)784     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
785                                                     int w, int h,
786                                                     int scanlineStride,
787                                                     int bandMasks[],
788                                                     Point location)
789     {
790         if (dataBuffer == null) {
791             throw new NullPointerException("DataBuffer cannot be null");
792         }
793         if (location == null) {
794            location = new Point(0,0);
795         }
796         int dataType = dataBuffer.getDataType();
797 
798         SinglePixelPackedSampleModel sppsm =
799             new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride,
800                                              bandMasks);
801 
802         switch(dataType) {
803         case DataBuffer.TYPE_BYTE:
804             if (dataBuffer instanceof DataBufferByte) {
805                 return new ByteInterleavedRaster(sppsm,
806                         (DataBufferByte) dataBuffer, location);
807             }
808             break;
809 
810         case DataBuffer.TYPE_USHORT:
811             if (dataBuffer instanceof DataBufferUShort) {
812                 return new ShortInterleavedRaster(sppsm,
813                         (DataBufferUShort) dataBuffer, location);
814             }
815             break;
816 
817         case DataBuffer.TYPE_INT:
818             if (dataBuffer instanceof DataBufferInt) {
819                 return new IntegerInterleavedRaster(sppsm,
820                         (DataBufferInt) dataBuffer, location);
821             }
822             break;
823 
824         default:
825             throw new IllegalArgumentException("Unsupported data type " +
826                                                 dataType);
827         }
828 
829         // Create the generic raster
830         return new SunWritableRaster(sppsm, dataBuffer, location);
831     }
832 
833     /**
834      * Creates a Raster based on a MultiPixelPackedSampleModel with the
835      * specified DataBuffer, width, height, and bits per pixel.  The upper
836      * left corner of the Raster is given by the location argument.  If
837      * location is null, (0, 0) will be used.
838      * @param dataBuffer the {@code DataBuffer} that contains the
839      *        image data
840      * @param w         the width in pixels of the image data
841      * @param h         the height in pixels of the image data
842      * @param bitsPerPixel the number of bits for each pixel
843      * @param location  the upper-left corner of the {@code Raster}
844      * @return a WritableRaster object with the specified
845      *         {@code DataBuffer}, width, height, and
846      *         bits per pixel.
847      * @throws RasterFormatException if {@code w} or {@code h}
848      *         is less than or equal to zero, or computing either
849      *         {@code location.x + w} or
850      *         {@code location.y + h} results in integer
851      *         overflow
852      * @throws IllegalArgumentException if {@code dataType} is not
853      *         one of the supported data types, which are
854      *         {@code DataBuffer.TYPE_BYTE},
855      *         {@code DataBuffer.TYPE_USHORT}
856      *         or {@code DataBuffer.TYPE_INT}
857      * @throws RasterFormatException if {@code dataBuffer} has more
858      *         than one bank.
859      * @throws NullPointerException if {@code dataBuffer} is null
860      */
createPackedRaster(DataBuffer dataBuffer, int w, int h, int bitsPerPixel, Point location)861     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
862                                                     int w, int h,
863                                                     int bitsPerPixel,
864                                                     Point location)
865     {
866         if (dataBuffer == null) {
867             throw new NullPointerException("DataBuffer cannot be null");
868         }
869         if (location == null) {
870            location = new Point(0,0);
871         }
872         int dataType = dataBuffer.getDataType();
873 
874         if (dataType != DataBuffer.TYPE_BYTE &&
875             dataType != DataBuffer.TYPE_USHORT &&
876             dataType != DataBuffer.TYPE_INT) {
877             throw new IllegalArgumentException("Unsupported data type " +
878                                                dataType);
879         }
880 
881         if (dataBuffer.getNumBanks() != 1) {
882             throw new
883                 RasterFormatException("DataBuffer for packed Rasters"+
884                                       " must only have 1 bank.");
885         }
886 
887         MultiPixelPackedSampleModel mppsm =
888                 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
889 
890         if (dataBuffer instanceof DataBufferByte &&
891             (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4))
892         {
893             return new BytePackedRaster(mppsm, (DataBufferByte) dataBuffer, location);
894         } else {
895             return new SunWritableRaster(mppsm, dataBuffer, location);
896         }
897     }
898 
899 
900     /**
901      *  Creates a Raster with the specified SampleModel and DataBuffer.
902      *  The upper left corner of the Raster is given by the location argument.
903      *  If location is null, (0, 0) will be used.
904      *  @param sm the specified {@code SampleModel}
905      *  @param db the specified {@code DataBuffer}
906      *  @param location the upper-left corner of the {@code Raster}
907      *  @return a {@code Raster} with the specified
908      *          {@code SampleModel}, {@code DataBuffer}, and
909      *          location.
910      * @throws RasterFormatException if computing either
911      *         {@code location.x + sm.getWidth()} or
912      *         {@code location.y + sm.getHeight()} results in integer
913      *         overflow
914      * @throws RasterFormatException if {@code db} has more
915      *         than one bank and {@code sm} is a
916      *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
917      *         or MultiPixelPackedSampleModel.
918      *  @throws NullPointerException if either SampleModel or DataBuffer is
919      *          null
920      */
createRaster(SampleModel sm, DataBuffer db, Point location)921     public static Raster createRaster(SampleModel sm,
922                                       DataBuffer db,
923                                       Point location)
924     {
925         if ((sm == null) || (db == null)) {
926             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
927         }
928 
929         if (location == null) {
930            location = new Point(0,0);
931         }
932         int dataType = sm.getDataType();
933 
934         if (sm instanceof PixelInterleavedSampleModel) {
935             switch(dataType) {
936             case DataBuffer.TYPE_BYTE:
937                 if (db instanceof DataBufferByte) {
938                     return new ByteInterleavedRaster(sm,
939                             (DataBufferByte) db, location);
940                 }
941                 break;
942 
943             case DataBuffer.TYPE_USHORT:
944                 if (db instanceof DataBufferUShort) {
945                     return new ShortInterleavedRaster(sm,
946                             (DataBufferUShort) db, location);
947                 }
948                 break;
949             }
950         } else if (sm instanceof SinglePixelPackedSampleModel) {
951             switch(dataType) {
952             case DataBuffer.TYPE_BYTE:
953                 if (db instanceof DataBufferByte) {
954                     return new ByteInterleavedRaster(sm,
955                             (DataBufferByte) db, location);
956                 }
957                 break;
958 
959             case DataBuffer.TYPE_USHORT:
960                 if (db instanceof DataBufferUShort) {
961                     return new ShortInterleavedRaster(sm,
962                             (DataBufferUShort) db, location);
963                 }
964                 break;
965 
966             case DataBuffer.TYPE_INT:
967                 if (db instanceof DataBufferInt) {
968                     return new IntegerInterleavedRaster(sm,
969                             (DataBufferInt) db, location);
970                 }
971                 break;
972             }
973         } else if (sm instanceof MultiPixelPackedSampleModel &&
974                    dataType == DataBuffer.TYPE_BYTE &&
975                    db instanceof DataBufferByte &&
976                    sm.getSampleSize(0) < 8)
977         {
978             return new BytePackedRaster(sm, (DataBufferByte) db, location);
979         }
980 
981         // we couldn't do anything special - do the generic thing
982         return new Raster(sm, db, location);
983     }
984 
985     /**
986      *  Creates a WritableRaster with the specified SampleModel.
987      *  The upper left corner of the Raster is given by the location argument.
988      *  If location is null, (0, 0) will be used.
989      *  @param sm the specified {@code SampleModel}
990      *  @param location the upper-left corner of the
991      *         {@code WritableRaster}
992      *  @return a {@code WritableRaster} with the specified
993      *          {@code SampleModel} and location.
994      *  @throws RasterFormatException if computing either
995      *          {@code location.x + sm.getWidth()} or
996      *          {@code location.y + sm.getHeight()} results in integer
997      *          overflow
998      */
createWritableRaster(SampleModel sm, Point location)999     public static WritableRaster createWritableRaster(SampleModel sm,
1000                                                       Point location) {
1001         if (location == null) {
1002            location = new Point(0,0);
1003         }
1004 
1005         return createWritableRaster(sm, sm.createDataBuffer(), location);
1006     }
1007 
1008     /**
1009      *  Creates a WritableRaster with the specified SampleModel and DataBuffer.
1010      *  The upper left corner of the Raster is given by the location argument.
1011      *  If location is null, (0, 0) will be used.
1012      *  @param sm the specified {@code SampleModel}
1013      *  @param db the specified {@code DataBuffer}
1014      *  @param location the upper-left corner of the
1015      *         {@code WritableRaster}
1016      *  @return a {@code WritableRaster} with the specified
1017      *          {@code SampleModel}, {@code DataBuffer}, and
1018      *          location.
1019      * @throws RasterFormatException if computing either
1020      *         {@code location.x + sm.getWidth()} or
1021      *         {@code location.y + sm.getHeight()} results in integer
1022      *         overflow
1023      * @throws RasterFormatException if {@code db} has more
1024      *         than one bank and {@code sm} is a
1025      *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
1026      *         or MultiPixelPackedSampleModel.
1027      * @throws NullPointerException if either SampleModel or DataBuffer is null
1028      */
createWritableRaster(SampleModel sm, DataBuffer db, Point location)1029     public static WritableRaster createWritableRaster(SampleModel sm,
1030                                                       DataBuffer db,
1031                                                       Point location)
1032     {
1033         if ((sm == null) || (db == null)) {
1034             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
1035         }
1036         if (location == null) {
1037            location = new Point(0,0);
1038         }
1039 
1040         int dataType = sm.getDataType();
1041 
1042         if (sm instanceof PixelInterleavedSampleModel) {
1043             switch(dataType) {
1044             case DataBuffer.TYPE_BYTE:
1045                 if (db instanceof DataBufferByte) {
1046                     return new ByteInterleavedRaster(sm,
1047                             (DataBufferByte) db, location);
1048                 }
1049                 break;
1050 
1051             case DataBuffer.TYPE_USHORT:
1052                 if (db instanceof DataBufferUShort) {
1053                     return new ShortInterleavedRaster(sm,
1054                             (DataBufferUShort) db, location);
1055                 }
1056                 break;
1057             }
1058         } else if (sm instanceof SinglePixelPackedSampleModel) {
1059             switch(dataType) {
1060             case DataBuffer.TYPE_BYTE:
1061                 if (db instanceof DataBufferByte) {
1062                     return new ByteInterleavedRaster(sm,
1063                             (DataBufferByte) db, location);
1064                 }
1065                 break;
1066 
1067             case DataBuffer.TYPE_USHORT:
1068                 if (db instanceof DataBufferUShort) {
1069                     return new ShortInterleavedRaster(sm,
1070                             (DataBufferUShort) db, location);
1071                 }
1072                 break;
1073 
1074             case DataBuffer.TYPE_INT:
1075                 if (db instanceof DataBufferInt) {
1076                     return new IntegerInterleavedRaster(sm,
1077                             (DataBufferInt) db, location);
1078                 }
1079                 break;
1080             }
1081         } else if (sm instanceof MultiPixelPackedSampleModel &&
1082                    dataType == DataBuffer.TYPE_BYTE &&
1083                    db instanceof DataBufferByte &&
1084                    sm.getSampleSize(0) < 8)
1085         {
1086             return new BytePackedRaster(sm, (DataBufferByte) db, location);
1087         }
1088 
1089         // we couldn't do anything special - do the generic thing
1090         return new SunWritableRaster(sm, db, location);
1091     }
1092 
1093     /**
1094      *  Constructs a Raster with the given SampleModel.  The Raster's
1095      *  upper left corner is origin and it is the same size as the
1096      *  SampleModel.  A DataBuffer large enough to describe the
1097      *  Raster is automatically created.
1098      *  @param sampleModel     The SampleModel that specifies the layout
1099      *  @param origin          The Point that specified the origin
1100      *  @throws RasterFormatException if computing either
1101      *          {@code origin.x + sampleModel.getWidth()} or
1102      *          {@code origin.y + sampleModel.getHeight()} results in
1103      *          integer overflow
1104      *  @throws NullPointerException either {@code sampleModel} or
1105      *          {@code origin} is null
1106      */
Raster(SampleModel sampleModel, Point origin)1107     protected Raster(SampleModel sampleModel,
1108                      Point origin) {
1109         this(sampleModel,
1110              sampleModel.createDataBuffer(),
1111              new Rectangle(origin.x,
1112                            origin.y,
1113                            sampleModel.getWidth(),
1114                            sampleModel.getHeight()),
1115              origin,
1116              null);
1117     }
1118 
1119     /**
1120      *  Constructs a Raster with the given SampleModel and DataBuffer.
1121      *  The Raster's upper left corner is origin and it is the same size
1122      *  as the SampleModel.  The DataBuffer is not initialized and must
1123      *  be compatible with SampleModel.
1124      *  @param sampleModel     The SampleModel that specifies the layout
1125      *  @param dataBuffer      The DataBuffer that contains the image data
1126      *  @param origin          The Point that specifies the origin
1127      *  @throws RasterFormatException if computing either
1128      *          {@code origin.x + sampleModel.getWidth()} or
1129      *          {@code origin.y + sampleModel.getHeight()} results in
1130      *          integer overflow
1131      *  @throws NullPointerException either {@code sampleModel} or
1132      *          {@code origin} is null
1133      */
Raster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin)1134     protected Raster(SampleModel sampleModel,
1135                      DataBuffer dataBuffer,
1136                      Point origin) {
1137         this(sampleModel,
1138              dataBuffer,
1139              new Rectangle(origin.x,
1140                            origin.y,
1141                            sampleModel.getWidth(),
1142                            sampleModel.getHeight()),
1143              origin,
1144              null);
1145     }
1146 
1147     /**
1148      * Constructs a Raster with the given SampleModel, DataBuffer, and
1149      * parent.  aRegion specifies the bounding rectangle of the new
1150      * Raster.  When translated into the base Raster's coordinate
1151      * system, aRegion must be contained by the base Raster.
1152      * (The base Raster is the Raster's ancestor which has no parent.)
1153      * sampleModelTranslate specifies the sampleModelTranslateX and
1154      * sampleModelTranslateY values of the new Raster.
1155      *
1156      * Note that this constructor should generally be called by other
1157      * constructors or create methods, it should not be used directly.
1158      * @param sampleModel     The SampleModel that specifies the layout
1159      * @param dataBuffer      The DataBuffer that contains the image data
1160      * @param aRegion         The Rectangle that specifies the image area
1161      * @param sampleModelTranslate  The Point that specifies the translation
1162      *                        from SampleModel to Raster coordinates
1163      * @param parent          The parent (if any) of this raster
1164      * @throws NullPointerException if any of {@code sampleModel},
1165      *         {@code dataBuffer}, {@code aRegion} or
1166      *         {@code sampleModelTranslate} is null
1167      * @throws RasterFormatException if {@code aRegion} has width
1168      *         or height less than or equal to zero, or computing either
1169      *         {@code aRegion.x + aRegion.width} or
1170      *         {@code aRegion.y + aRegion.height} results in integer
1171      *         overflow
1172      */
Raster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion, Point sampleModelTranslate, Raster parent)1173     protected Raster(SampleModel sampleModel,
1174                      DataBuffer dataBuffer,
1175                      Rectangle aRegion,
1176                      Point sampleModelTranslate,
1177                      Raster parent) {
1178 
1179         if ((sampleModel == null) || (dataBuffer == null) ||
1180             (aRegion == null) || (sampleModelTranslate == null)) {
1181             throw new NullPointerException("SampleModel, dataBuffer, aRegion and " +
1182                                            "sampleModelTranslate cannot be null");
1183         }
1184        this.sampleModel = sampleModel;
1185        this.dataBuffer = dataBuffer;
1186        minX = aRegion.x;
1187        minY = aRegion.y;
1188        width = aRegion.width;
1189        height = aRegion.height;
1190        if (width <= 0 || height <= 0) {
1191            throw new RasterFormatException("negative or zero " +
1192                ((width <= 0) ? "width" : "height"));
1193        }
1194        if ((minX + width) < minX) {
1195            throw new RasterFormatException(
1196                "overflow condition for X coordinates of Raster");
1197        }
1198        if ((minY + height) < minY) {
1199            throw new RasterFormatException(
1200                "overflow condition for Y coordinates of Raster");
1201        }
1202 
1203        sampleModelTranslateX = sampleModelTranslate.x;
1204        sampleModelTranslateY = sampleModelTranslate.y;
1205 
1206        numBands = sampleModel.getNumBands();
1207        numDataElements = sampleModel.getNumDataElements();
1208        this.parent = parent;
1209     }
1210 
1211 
1212     /**
1213      * Returns the parent Raster (if any) of this Raster or null.
1214      * @return the parent Raster or {@code null}.
1215      */
getParent()1216     public Raster getParent() {
1217         return parent;
1218     }
1219 
1220     /**
1221      * Returns the X translation from the coordinate system of the
1222      * SampleModel to that of the Raster.  To convert a pixel's X
1223      * coordinate from the Raster coordinate system to the SampleModel
1224      * coordinate system, this value must be subtracted.
1225      * @return the X translation from the coordinate space of the
1226      *         Raster's SampleModel to that of the Raster.
1227      */
getSampleModelTranslateX()1228     public final int getSampleModelTranslateX() {
1229         return sampleModelTranslateX;
1230     }
1231 
1232     /**
1233      * Returns the Y translation from the coordinate system of the
1234      * SampleModel to that of the Raster.  To convert a pixel's Y
1235      * coordinate from the Raster coordinate system to the SampleModel
1236      * coordinate system, this value must be subtracted.
1237      * @return the Y translation from the coordinate space of the
1238      *         Raster's SampleModel to that of the Raster.
1239      */
getSampleModelTranslateY()1240     public final int getSampleModelTranslateY() {
1241         return sampleModelTranslateY;
1242     }
1243 
1244     /**
1245      * Create a compatible WritableRaster the same size as this Raster with
1246      * the same SampleModel and a new initialized DataBuffer.
1247      * @return a compatible {@code WritableRaster} with the same sample
1248      *         model and a new data buffer.
1249      */
createCompatibleWritableRaster()1250     public WritableRaster createCompatibleWritableRaster() {
1251         return new SunWritableRaster(sampleModel, new Point(0,0));
1252     }
1253 
1254     /**
1255      * Create a compatible WritableRaster with the specified size, a new
1256      * SampleModel, and a new initialized DataBuffer.
1257      * @param w the specified width of the new {@code WritableRaster}
1258      * @param h the specified height of the new {@code WritableRaster}
1259      * @return a compatible {@code WritableRaster} with the specified
1260      *         size and a new sample model and data buffer.
1261      * @exception RasterFormatException if the width or height is less than
1262      *                               or equal to zero.
1263      */
createCompatibleWritableRaster(int w, int h)1264     public WritableRaster createCompatibleWritableRaster(int w, int h) {
1265         if (w <= 0 || h <=0) {
1266             throw new RasterFormatException("negative " +
1267                                           ((w <= 0) ? "width" : "height"));
1268         }
1269 
1270         SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
1271 
1272         return new SunWritableRaster(sm, new Point(0,0));
1273     }
1274 
1275     /**
1276      * Create a compatible WritableRaster with location (minX, minY)
1277      * and size (width, height) specified by rect, a
1278      * new SampleModel, and a new initialized DataBuffer.
1279      * @param rect a {@code Rectangle} that specifies the size and
1280      *        location of the {@code WritableRaster}
1281      * @return a compatible {@code WritableRaster} with the specified
1282      *         size and location and a new sample model and data buffer.
1283      * @throws RasterFormatException if {@code rect} has width
1284      *         or height less than or equal to zero, or computing either
1285      *         {@code rect.x + rect.width} or
1286      *         {@code rect.y + rect.height} results in integer
1287      *         overflow
1288      * @throws NullPointerException if {@code rect} is null
1289      */
createCompatibleWritableRaster(Rectangle rect)1290     public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
1291         if (rect == null) {
1292             throw new NullPointerException("Rect cannot be null");
1293         }
1294         return createCompatibleWritableRaster(rect.x, rect.y,
1295                                               rect.width, rect.height);
1296     }
1297 
1298     /**
1299      * Create a compatible WritableRaster with the specified
1300      * location (minX, minY) and size (width, height), a
1301      * new SampleModel, and a new initialized DataBuffer.
1302      * @param x the X coordinate of the upper-left corner of
1303      *        the {@code WritableRaster}
1304      * @param y the Y coordinate of the upper-left corner of
1305      *        the {@code WritableRaster}
1306      * @param w the specified width of the {@code WritableRaster}
1307      * @param h the specified height of the {@code WritableRaster}
1308      * @return a compatible {@code WritableRaster} with the specified
1309      *         size and location and a new sample model and data buffer.
1310      * @throws RasterFormatException if {@code w} or {@code h}
1311      *         is less than or equal to zero, or computing either
1312      *         {@code x + w} or
1313      *         {@code y + h} results in integer
1314      *         overflow
1315      */
createCompatibleWritableRaster(int x, int y, int w, int h)1316     public WritableRaster createCompatibleWritableRaster(int x, int y,
1317                                                          int w, int h) {
1318         WritableRaster ret = createCompatibleWritableRaster(w, h);
1319         return ret.createWritableChild(0,0,w,h,x,y,null);
1320     }
1321 
1322     /**
1323      * Create a Raster with the same size, SampleModel and DataBuffer
1324      * as this one, but with a different location.  The new Raster
1325      * will possess a reference to the current Raster, accessible
1326      * through its getParent() method.
1327      *
1328      * @param childMinX the X coordinate of the upper-left
1329      *        corner of the new {@code Raster}
1330      * @param childMinY the Y coordinate of the upper-left
1331      *        corner of the new {@code Raster}
1332      * @return a new {@code Raster} with the same size, SampleModel,
1333      *         and DataBuffer as this {@code Raster}, but with the
1334      *         specified location.
1335      * @throws RasterFormatException if  computing either
1336      *         {@code childMinX + this.getWidth()} or
1337      *         {@code childMinY + this.getHeight()} results in integer
1338      *         overflow
1339      */
createTranslatedChild(int childMinX, int childMinY)1340     public Raster createTranslatedChild(int childMinX, int childMinY) {
1341         return createChild(minX,minY,width,height,
1342                            childMinX,childMinY,null);
1343     }
1344 
1345     /**
1346      * Returns a new Raster which shares all or part of this Raster's
1347      * DataBuffer.  The new Raster will possess a reference to the
1348      * current Raster, accessible through its getParent() method.
1349      *
1350      * <p> The parentX, parentY, width and height parameters
1351      * form a Rectangle in this Raster's coordinate space,
1352      * indicating the area of pixels to be shared.  An error will
1353      * be thrown if this Rectangle is not contained with the bounds
1354      * of the current Raster.
1355      *
1356      * <p> The new Raster may additionally be translated to a
1357      * different coordinate system for the plane than that used by the current
1358      * Raster.  The childMinX and childMinY parameters give the new
1359      * (x, y) coordinate of the upper-left pixel of the returned
1360      * Raster; the coordinate (childMinX, childMinY) in the new Raster
1361      * will map to the same pixel as the coordinate (parentX, parentY)
1362      * in the current Raster.
1363      *
1364      * <p> The new Raster may be defined to contain only a subset of
1365      * the bands of the current Raster, possibly reordered, by means
1366      * of the bandList parameter.  If bandList is null, it is taken to
1367      * include all of the bands of the current Raster in their current
1368      * order.
1369      *
1370      * <p> To create a new Raster that contains a subregion of the current
1371      * Raster, but shares its coordinate system and bands,
1372      * this method should be called with childMinX equal to parentX,
1373      * childMinY equal to parentY, and bandList equal to null.
1374      *
1375      * @param parentX The X coordinate of the upper-left corner
1376      *        in this Raster's coordinates
1377      * @param parentY The Y coordinate of the upper-left corner
1378      *        in this Raster's coordinates
1379      * @param width      Width of the region starting at (parentX, parentY)
1380      * @param height     Height of the region starting at (parentX, parentY).
1381      * @param childMinX The X coordinate of the upper-left corner
1382      *                   of the returned Raster
1383      * @param childMinY The Y coordinate of the upper-left corner
1384      *                   of the returned Raster
1385      * @param bandList   Array of band indices, or null to use all bands
1386      * @return a new {@code Raster}.
1387      * @exception RasterFormatException if the specified subregion is outside
1388      *                               of the raster bounds.
1389      * @throws RasterFormatException if {@code width} or
1390      *         {@code height}
1391      *         is less than or equal to zero, or computing any of
1392      *         {@code parentX + width}, {@code parentY + height},
1393      *         {@code childMinX + width}, or
1394      *         {@code childMinY + height} results in integer
1395      *         overflow
1396      */
createChild(int parentX, int parentY, int width, int height, int childMinX, int childMinY, int bandList[])1397     public Raster createChild(int parentX, int parentY,
1398                               int width, int height,
1399                               int childMinX, int childMinY,
1400                               int bandList[]) {
1401         if (parentX < this.minX) {
1402             throw new RasterFormatException("parentX lies outside raster");
1403         }
1404         if (parentY < this.minY) {
1405             throw new RasterFormatException("parentY lies outside raster");
1406         }
1407         if ((parentX + width < parentX) ||
1408             (parentX + width > this.width + this.minX)) {
1409             throw new RasterFormatException("(parentX + width) is outside raster");
1410         }
1411         if ((parentY + height < parentY) ||
1412             (parentY + height > this.height + this.minY)) {
1413             throw new RasterFormatException("(parentY + height) is outside raster");
1414         }
1415 
1416         SampleModel subSampleModel;
1417         // Note: the SampleModel for the child Raster should have the same
1418         // width and height as that for the parent, since it represents
1419         // the physical layout of the pixel data.  The child Raster's width
1420         // and height represent a "virtual" view of the pixel data, so
1421         // they may be different than those of the SampleModel.
1422         if (bandList == null) {
1423             subSampleModel = sampleModel;
1424         } else {
1425             subSampleModel = sampleModel.createSubsetSampleModel(bandList);
1426         }
1427 
1428         int deltaX = childMinX - parentX;
1429         int deltaY = childMinY - parentY;
1430 
1431         return new Raster(subSampleModel, getDataBuffer(),
1432                           new Rectangle(childMinX, childMinY, width, height),
1433                           new Point(sampleModelTranslateX + deltaX,
1434                                     sampleModelTranslateY + deltaY), this);
1435     }
1436 
1437     /**
1438      * Returns the bounding Rectangle of this Raster. This function returns
1439      * the same information as getMinX/MinY/Width/Height.
1440      * @return the bounding box of this {@code Raster}.
1441      */
getBounds()1442     public Rectangle getBounds() {
1443         return new Rectangle(minX, minY, width, height);
1444     }
1445 
1446     /** Returns the minimum valid X coordinate of the Raster.
1447      *  @return the minimum x coordinate of this {@code Raster}.
1448      */
getMinX()1449     public final int getMinX() {
1450         return minX;
1451     }
1452 
1453     /** Returns the minimum valid Y coordinate of the Raster.
1454      *  @return the minimum y coordinate of this {@code Raster}.
1455      */
getMinY()1456     public final int getMinY() {
1457         return minY;
1458     }
1459 
1460     /** Returns the width in pixels of the Raster.
1461      *  @return the width of this {@code Raster}.
1462      */
getWidth()1463     public final int getWidth() {
1464         return width;
1465     }
1466 
1467     /** Returns the height in pixels of the Raster.
1468      *  @return the height of this {@code Raster}.
1469      */
getHeight()1470     public final int getHeight() {
1471         return height;
1472     }
1473 
1474     /** Returns the number of bands (samples per pixel) in this Raster.
1475      *  @return the number of bands of this {@code Raster}.
1476      */
getNumBands()1477     public final int getNumBands() {
1478         return numBands;
1479     }
1480 
1481     /**
1482      *  Returns the number of data elements needed to transfer one pixel
1483      *  via the getDataElements and setDataElements methods.  When pixels
1484      *  are transferred via these methods, they may be transferred in a
1485      *  packed or unpacked format, depending on the implementation of the
1486      *  underlying SampleModel.  Using these methods, pixels are transferred
1487      *  as an array of getNumDataElements() elements of a primitive type given
1488      *  by getTransferType().  The TransferType may or may not be the same
1489      *  as the storage data type of the DataBuffer.
1490      *  @return the number of data elements.
1491      */
getNumDataElements()1492     public final int getNumDataElements() {
1493         return sampleModel.getNumDataElements();
1494     }
1495 
1496     /**
1497      *  Returns the TransferType used to transfer pixels via the
1498      *  getDataElements and setDataElements methods.  When pixels
1499      *  are transferred via these methods, they may be transferred in a
1500      *  packed or unpacked format, depending on the implementation of the
1501      *  underlying SampleModel.  Using these methods, pixels are transferred
1502      *  as an array of getNumDataElements() elements of a primitive type given
1503      *  by getTransferType().  The TransferType may or may not be the same
1504      *  as the storage data type of the DataBuffer.  The TransferType will
1505      *  be one of the types defined in DataBuffer.
1506      *  @return this transfer type.
1507      */
getTransferType()1508     public final int getTransferType() {
1509         return sampleModel.getTransferType();
1510     }
1511 
1512     /** Returns the DataBuffer associated with this Raster.
1513      *  @return the {@code DataBuffer} of this {@code Raster}.
1514      */
getDataBuffer()1515     public DataBuffer getDataBuffer() {
1516         return dataBuffer;
1517     }
1518 
1519     /** Returns the SampleModel that describes the layout of the image data.
1520      *  @return the {@code SampleModel} of this {@code Raster}.
1521      */
getSampleModel()1522     public SampleModel getSampleModel() {
1523         return sampleModel;
1524     }
1525 
1526     /**
1527      * Returns data for a single pixel in a primitive array of type
1528      * TransferType.  For image data supported by the Java 2D(tm) API,
1529      * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
1530      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
1531      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
1532      * thus increasing efficiency for data transfers.
1533      * An ArrayIndexOutOfBoundsException may be thrown
1534      * if the coordinates are not in bounds.  However, explicit bounds
1535      * checking is not guaranteed.
1536      * A ClassCastException will be thrown if the input object is non null
1537      * and references anything other than an array of TransferType.
1538      * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
1539      * @param x        The X coordinate of the pixel location
1540      * @param y        The Y coordinate of the pixel location
1541      * @param outData  An object reference to an array of type defined by
1542      *                 getTransferType() and length getNumDataElements().
1543      *                 If null, an array of appropriate type and size will be
1544      *                 allocated
1545      * @return         An object reference to an array of type defined by
1546      *                 getTransferType() with the requested pixel data.
1547      *
1548      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1549      * in bounds, or if outData is too small to hold the output.
1550      */
getDataElements(int x, int y, Object outData)1551     public Object getDataElements(int x, int y, Object outData) {
1552         return sampleModel.getDataElements(x - sampleModelTranslateX,
1553                                            y - sampleModelTranslateY,
1554                                            outData, dataBuffer);
1555     }
1556 
1557     /**
1558      * Returns the pixel data for the specified rectangle of pixels in a
1559      * primitive array of type TransferType.
1560      * For image data supported by the Java 2D API, this
1561      * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
1562      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
1563      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
1564      * thus increasing efficiency for data transfers.
1565      * An ArrayIndexOutOfBoundsException may be thrown
1566      * if the coordinates are not in bounds.  However, explicit bounds
1567      * checking is not guaranteed.
1568      * A ClassCastException will be thrown if the input object is non null
1569      * and references anything other than an array of TransferType.
1570      * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
1571      * @param x    The X coordinate of the upper-left pixel location
1572      * @param y    The Y coordinate of the upper-left pixel location
1573      * @param w    Width of the pixel rectangle
1574      * @param h   Height of the pixel rectangle
1575      * @param outData  An object reference to an array of type defined by
1576      *                 getTransferType() and length w*h*getNumDataElements().
1577      *                 If null, an array of appropriate type and size will be
1578      *                 allocated.
1579      * @return         An object reference to an array of type defined by
1580      *                 getTransferType() with the requested pixel data.
1581      *
1582      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1583      * in bounds, or if outData is too small to hold the output.
1584      */
getDataElements(int x, int y, int w, int h, Object outData)1585     public Object getDataElements(int x, int y, int w, int h, Object outData) {
1586         return sampleModel.getDataElements(x - sampleModelTranslateX,
1587                                            y - sampleModelTranslateY,
1588                                            w, h, outData, dataBuffer);
1589     }
1590 
1591     /**
1592      * Returns the samples in an array of int for the specified pixel.
1593      * An ArrayIndexOutOfBoundsException may be thrown
1594      * if the coordinates are not in bounds.  However, explicit bounds
1595      * checking is not guaranteed.
1596      * @param x The X coordinate of the pixel location
1597      * @param y The Y coordinate of the pixel location
1598      * @param iArray An optionally preallocated int array
1599      * @return the samples for the specified pixel.
1600      *
1601      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1602      * in bounds, or if iArray is too small to hold the output.
1603      */
getPixel(int x, int y, int iArray[])1604     public int[] getPixel(int x, int y, int iArray[]) {
1605         return sampleModel.getPixel(x - sampleModelTranslateX,
1606                                     y - sampleModelTranslateY,
1607                                     iArray, dataBuffer);
1608     }
1609 
1610     /**
1611      * Returns the samples in an array of float for the
1612      * specified pixel.
1613      * An ArrayIndexOutOfBoundsException may be thrown
1614      * if the coordinates are not in bounds.  However, explicit bounds
1615      * checking is not guaranteed.
1616      * @param x The X coordinate of the pixel location
1617      * @param y The Y coordinate of the pixel location
1618      * @param fArray An optionally preallocated float array
1619      * @return the samples for the specified pixel.
1620      *
1621      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1622      * in bounds, or if fArray is too small to hold the output.
1623      */
getPixel(int x, int y, float fArray[])1624     public float[] getPixel(int x, int y, float fArray[]) {
1625         return sampleModel.getPixel(x - sampleModelTranslateX,
1626                                     y - sampleModelTranslateY,
1627                                     fArray, dataBuffer);
1628     }
1629 
1630     /**
1631      * Returns the samples in an array of double for the specified pixel.
1632      * An ArrayIndexOutOfBoundsException may be thrown
1633      * if the coordinates are not in bounds.  However, explicit bounds
1634      * checking is not guaranteed.
1635      * @param x The X coordinate of the pixel location
1636      * @param y The Y coordinate of the pixel location
1637      * @param dArray An optionally preallocated double array
1638      * @return the samples for the specified pixel.
1639      *
1640      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1641      * in bounds, or if dArray is too small to hold the output.
1642      */
getPixel(int x, int y, double dArray[])1643     public double[] getPixel(int x, int y, double dArray[]) {
1644         return sampleModel.getPixel(x - sampleModelTranslateX,
1645                                     y - sampleModelTranslateY,
1646                                     dArray, dataBuffer);
1647     }
1648 
1649     /**
1650      * Returns an int array containing all samples for a rectangle of pixels,
1651      * one sample per array element.
1652      * An ArrayIndexOutOfBoundsException may be thrown
1653      * if the coordinates are not in bounds.  However, explicit bounds
1654      * checking is not guaranteed.
1655      * @param x      The X coordinate of the upper-left pixel location
1656      * @param y      The Y coordinate of the upper-left pixel location
1657      * @param w      Width of the pixel rectangle
1658      * @param h      Height of the pixel rectangle
1659      * @param iArray An optionally pre-allocated int array
1660      * @return the samples for the specified rectangle of pixels.
1661      *
1662      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1663      * in bounds, or if iArray is too small to hold the output.
1664      */
getPixels(int x, int y, int w, int h, int iArray[])1665     public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
1666         return sampleModel.getPixels(x - sampleModelTranslateX,
1667                                      y - sampleModelTranslateY, w, h,
1668                                      iArray, dataBuffer);
1669     }
1670 
1671     /**
1672      * Returns a float array containing all samples for a rectangle of pixels,
1673      * one sample per array element.
1674      * An ArrayIndexOutOfBoundsException may be thrown
1675      * if the coordinates are not in bounds.  However, explicit bounds
1676      * checking is not guaranteed.
1677      * @param x        The X coordinate of the pixel location
1678      * @param y        The Y coordinate of the pixel location
1679      * @param w        Width of the pixel rectangle
1680      * @param h        Height of the pixel rectangle
1681      * @param fArray   An optionally pre-allocated float array
1682      * @return the samples for the specified rectangle of pixels.
1683      *
1684      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1685      * in bounds, or if fArray is too small to hold the output.
1686      */
getPixels(int x, int y, int w, int h, float fArray[])1687     public float[] getPixels(int x, int y, int w, int h,
1688                              float fArray[]) {
1689         return sampleModel.getPixels(x - sampleModelTranslateX,
1690                                      y - sampleModelTranslateY, w, h,
1691                                      fArray, dataBuffer);
1692     }
1693 
1694     /**
1695      * Returns a double array containing all samples for a rectangle of pixels,
1696      * one sample per array element.
1697      * An ArrayIndexOutOfBoundsException may be thrown
1698      * if the coordinates are not in bounds.  However, explicit bounds
1699      * checking is not guaranteed.
1700      * @param x        The X coordinate of the upper-left pixel location
1701      * @param y        The Y coordinate of the upper-left pixel location
1702      * @param w        Width of the pixel rectangle
1703      * @param h        Height of the pixel rectangle
1704      * @param dArray   An optionally pre-allocated double array
1705      * @return the samples for the specified rectangle of pixels.
1706      *
1707      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
1708      * in bounds, or if dArray is too small to hold the output.
1709      */
getPixels(int x, int y, int w, int h, double dArray[])1710     public double[] getPixels(int x, int y, int w, int h,
1711                               double dArray[]) {
1712         return sampleModel.getPixels(x - sampleModelTranslateX,
1713                                      y - sampleModelTranslateY,
1714                                      w, h, dArray, dataBuffer);
1715     }
1716 
1717 
1718     /**
1719      * Returns the sample in a specified band for the pixel located
1720      * at (x,y) as an int.
1721      * An ArrayIndexOutOfBoundsException may be thrown
1722      * if the coordinates are not in bounds.  However, explicit bounds
1723      * checking is not guaranteed.
1724      * @param x        The X coordinate of the pixel location
1725      * @param y        The Y coordinate of the pixel location
1726      * @param b        The band to return
1727      * @return the sample in the specified band for the pixel at the
1728      *         specified coordinate.
1729      *
1730      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1731      * the band index are not in bounds.
1732      */
getSample(int x, int y, int b)1733     public int getSample(int x, int y, int b) {
1734         return sampleModel.getSample(x - sampleModelTranslateX,
1735                                      y - sampleModelTranslateY, b,
1736                                      dataBuffer);
1737     }
1738 
1739     /**
1740      * Returns the sample in a specified band
1741      * for the pixel located at (x,y) as a float.
1742      * An ArrayIndexOutOfBoundsException may be thrown
1743      * if the coordinates are not in bounds.  However, explicit bounds
1744      * checking is not guaranteed.
1745      * @param x        The X coordinate of the pixel location
1746      * @param y        The Y coordinate of the pixel location
1747      * @param b        The band to return
1748      * @return the sample in the specified band for the pixel at the
1749      *         specified coordinate.
1750      *
1751      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1752      * the band index are not in bounds.
1753      */
getSampleFloat(int x, int y, int b)1754     public float getSampleFloat(int x, int y, int b) {
1755         return sampleModel.getSampleFloat(x - sampleModelTranslateX,
1756                                           y - sampleModelTranslateY, b,
1757                                           dataBuffer);
1758     }
1759 
1760     /**
1761      * Returns the sample in a specified band
1762      * for a pixel located at (x,y) as a double.
1763      * An ArrayIndexOutOfBoundsException may be thrown
1764      * if the coordinates are not in bounds.  However, explicit bounds
1765      * checking is not guaranteed.
1766      * @param x        The X coordinate of the pixel location
1767      * @param y        The Y coordinate of the pixel location
1768      * @param b        The band to return
1769      * @return the sample in the specified band for the pixel at the
1770      *         specified coordinate.
1771      *
1772      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1773      * the band index are not in bounds.
1774      */
getSampleDouble(int x, int y, int b)1775     public double getSampleDouble(int x, int y, int b) {
1776         return sampleModel.getSampleDouble(x - sampleModelTranslateX,
1777                                            y - sampleModelTranslateY,
1778                                            b, dataBuffer);
1779     }
1780 
1781     /**
1782      * Returns the samples for a specified band for the specified rectangle
1783      * of pixels in an int array, one sample per array element.
1784      * An ArrayIndexOutOfBoundsException may be thrown
1785      * if the coordinates are not in bounds.  However, explicit bounds
1786      * checking is not guaranteed.
1787      * @param x        The X coordinate of the upper-left pixel location
1788      * @param y        The Y coordinate of the upper-left pixel location
1789      * @param w        Width of the pixel rectangle
1790      * @param h        Height of the pixel rectangle
1791      * @param b        The band to return
1792      * @param iArray   An optionally pre-allocated int array
1793      * @return the samples for the specified band for the specified
1794      *         rectangle of pixels.
1795      *
1796      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1797      * the band index are not in bounds, or if iArray is too small to
1798      * hold the output.
1799      */
getSamples(int x, int y, int w, int h, int b, int iArray[])1800     public int[] getSamples(int x, int y, int w, int h, int b,
1801                             int iArray[]) {
1802         return sampleModel.getSamples(x - sampleModelTranslateX,
1803                                       y - sampleModelTranslateY,
1804                                       w, h, b, iArray,
1805                                       dataBuffer);
1806     }
1807 
1808     /**
1809      * Returns the samples for a specified band for the specified rectangle
1810      * of pixels in a float array, one sample per array element.
1811      * An ArrayIndexOutOfBoundsException may be thrown
1812      * if the coordinates are not in bounds.  However, explicit bounds
1813      * checking is not guaranteed.
1814      * @param x        The X coordinate of the upper-left pixel location
1815      * @param y        The Y coordinate of the upper-left pixel location
1816      * @param w        Width of the pixel rectangle
1817      * @param h        Height of the pixel rectangle
1818      * @param b        The band to return
1819      * @param fArray   An optionally pre-allocated float array
1820      * @return the samples for the specified band for the specified
1821      *         rectangle of pixels.
1822      *
1823      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1824      * the band index are not in bounds, or if fArray is too small to
1825      * hold the output.
1826      */
getSamples(int x, int y, int w, int h, int b, float fArray[])1827     public float[] getSamples(int x, int y, int w, int h, int b,
1828                               float fArray[]) {
1829         return sampleModel.getSamples(x - sampleModelTranslateX,
1830                                       y - sampleModelTranslateY,
1831                                       w, h, b, fArray, dataBuffer);
1832     }
1833 
1834     /**
1835      * Returns the samples for a specified band for a specified rectangle
1836      * of pixels in a double array, one sample per array element.
1837      * An ArrayIndexOutOfBoundsException may be thrown
1838      * if the coordinates are not in bounds.  However, explicit bounds
1839      * checking is not guaranteed.
1840      * @param x        The X coordinate of the upper-left pixel location
1841      * @param y        The Y coordinate of the upper-left pixel location
1842      * @param w        Width of the pixel rectangle
1843      * @param h        Height of the pixel rectangle
1844      * @param b        The band to return
1845      * @param dArray   An optionally pre-allocated double array
1846      * @return the samples for the specified band for the specified
1847      *         rectangle of pixels.
1848      *
1849      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1850      * the band index are not in bounds, or if dArray is too small to
1851      * hold the output.
1852      */
getSamples(int x, int y, int w, int h, int b, double dArray[])1853     public double[] getSamples(int x, int y, int w, int h, int b,
1854                                double dArray[]) {
1855          return sampleModel.getSamples(x - sampleModelTranslateX,
1856                                        y - sampleModelTranslateY,
1857                                        w, h, b, dArray, dataBuffer);
1858     }
1859 
1860 }
1861