View Javadoc
1   /*
2    * Copyright (c) 1997, 2011, 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  package java.awt.image;
37  
38  /**
39   *  This abstract class defines an interface for extracting samples of pixels
40   *  in an image.  All image data is expressed as a collection of pixels.
41   *  Each pixel consists of a number of samples. A sample is a datum
42   *  for one band of an image and a band consists of all samples of a
43   *  particular type in an image.  For example, a pixel might contain
44   *  three samples representing its red, green and blue components.
45   *  There are three bands in the image containing this pixel.  One band
46   *  consists of all the red samples from all pixels in the
47   *  image.  The second band consists of all the green samples and
48   *  the remaining band consists of all of the blue samples.  The pixel
49   *  can be stored in various formats.  For example, all samples from
50   *  a particular band can be stored contiguously or all samples from a
51   *  single pixel can be stored contiguously.
52   *  <p>
53   *  Subclasses of SampleModel specify the types of samples they can
54   *  represent (e.g. unsigned 8-bit byte, signed 16-bit short, etc.)
55   *  and may specify how the samples are organized in memory.
56   *  In the Java 2D(tm) API, built-in image processing operators may
57   *  not operate on all possible sample types, but generally will work
58   *  for unsigned integral samples of 16 bits or less.  Some operators
59   *  support a wider variety of sample types.
60   *  <p>
61   *  A collection of pixels is represented as a Raster, which consists of
62   *  a DataBuffer and a SampleModel.  The SampleModel allows access to
63   *  samples in the DataBuffer and may provide low-level information that
64   *  a programmer can use to directly manipulate samples and pixels in the
65   *  DataBuffer.
66   *  <p>
67   *  This class is generally a fall back method for dealing with
68   *  images.  More efficient code will cast the SampleModel to the
69   *  appropriate subclass and extract the information needed to directly
70   *  manipulate pixels in the DataBuffer.
71   *
72   *  @see java.awt.image.DataBuffer
73   *  @see java.awt.image.Raster
74   *  @see java.awt.image.ComponentSampleModel
75   *  @see java.awt.image.PixelInterleavedSampleModel
76   *  @see java.awt.image.BandedSampleModel
77   *  @see java.awt.image.MultiPixelPackedSampleModel
78   *  @see java.awt.image.SinglePixelPackedSampleModel
79   */
80  
81  public abstract class SampleModel
82  {
83  
84      /** Width in pixels of the region of image data that this SampleModel
85       *  describes.
86       */
87      protected int width;
88  
89      /** Height in pixels of the region of image data that this SampleModel
90       *  describes.
91       */
92      protected int height;
93  
94      /** Number of bands of the image data that this SampleModel describes. */
95      protected int numBands;
96  
97      /** Data type of the DataBuffer storing the pixel data.
98       *  @see java.awt.image.DataBuffer
99       */
100     protected int dataType;
101 
102     static private native void initIDs();
103     static {
104         ColorModel.loadLibraries();
105         initIDs();
106     }
107 
108     /**
109      * Constructs a SampleModel with the specified parameters.
110      * @param dataType  The data type of the DataBuffer storing the pixel data.
111      * @param w         The width (in pixels) of the region of image data.
112      * @param h         The height (in pixels) of the region of image data.
113      * @param numBands  The number of bands of the image data.
114      * @throws IllegalArgumentException if <code>w</code> or <code>h</code>
115      *         is not greater than 0
116      * @throws IllegalArgumentException if the product of <code>w</code>
117      *         and <code>h</code> is greater than
118      *         <code>Integer.MAX_VALUE</code>
119      * @throws IllegalArgumentException if <code>dataType</code> is not
120      *         one of the supported data types
121      */
122     public SampleModel(int dataType, int w, int h, int numBands)
123     {
124         long size = (long)w * h;
125         if (w <= 0 || h <= 0) {
126             throw new IllegalArgumentException("Width ("+w+") and height ("+
127                                                h+") must be > 0");
128         }
129         if (size >= Integer.MAX_VALUE) {
130             throw new IllegalArgumentException("Dimensions (width="+w+
131                                                " height="+h+") are too large");
132         }
133 
134         if (dataType < DataBuffer.TYPE_BYTE ||
135             (dataType > DataBuffer.TYPE_DOUBLE &&
136              dataType != DataBuffer.TYPE_UNDEFINED))
137         {
138             throw new IllegalArgumentException("Unsupported dataType: "+
139                                                dataType);
140         }
141 
142         if (numBands <= 0) {
143             throw new IllegalArgumentException("Number of bands must be > 0");
144         }
145 
146         this.dataType = dataType;
147         this.width = w;
148         this.height = h;
149         this.numBands = numBands;
150     }
151 
152     /** Returns the width in pixels.
153      *  @return the width in pixels of the region of image data
154      *          that this <code>SampleModel</code> describes.
155      */
156     final public int getWidth() {
157          return width;
158     }
159 
160     /** Returns the height in pixels.
161      *  @return the height in pixels of the region of image data
162      *          that this <code>SampleModel</code> describes.
163      */
164     final public int getHeight() {
165          return height;
166     }
167 
168     /** Returns the total number of bands of image data.
169      *  @return the number of bands of image data that this
170      *          <code>SampleModel</code> describes.
171      */
172     final public int getNumBands() {
173          return numBands;
174     }
175 
176     /** Returns the number of data elements needed to transfer a pixel
177      *  via the getDataElements and setDataElements methods.  When pixels
178      *  are transferred via these methods, they may be transferred in a
179      *  packed or unpacked format, depending on the implementation of the
180      *  SampleModel.  Using these methods, pixels are transferred as an
181      *  array of getNumDataElements() elements of a primitive type given
182      *  by getTransferType().  The TransferType may or may not be the same
183      *  as the storage DataType.
184      *  @return the number of data elements.
185      *  @see #getDataElements(int, int, Object, DataBuffer)
186      *  @see #getDataElements(int, int, int, int, Object, DataBuffer)
187      *  @see #setDataElements(int, int, Object, DataBuffer)
188      *  @see #setDataElements(int, int, int, int, Object, DataBuffer)
189      *  @see #getTransferType
190      */
191     public abstract int getNumDataElements();
192 
193     /** Returns the data type of the DataBuffer storing the pixel data.
194      *  @return the data type.
195      */
196     final public int getDataType() {
197         return dataType;
198     }
199 
200     /** Returns the TransferType used to transfer pixels via the
201      *  getDataElements and setDataElements methods.  When pixels
202      *  are transferred via these methods, they may be transferred in a
203      *  packed or unpacked format, depending on the implementation of the
204      *  SampleModel.  Using these methods, pixels are transferred as an
205      *  array of getNumDataElements() elements of a primitive type given
206      *  by getTransferType().  The TransferType may or may not be the same
207      *  as the storage DataType.  The TransferType will be one of the types
208      *  defined in DataBuffer.
209      *  @return the transfer type.
210      *  @see #getDataElements(int, int, Object, DataBuffer)
211      *  @see #getDataElements(int, int, int, int, Object, DataBuffer)
212      *  @see #setDataElements(int, int, Object, DataBuffer)
213      *  @see #setDataElements(int, int, int, int, Object, DataBuffer)
214      *  @see #getNumDataElements
215      *  @see java.awt.image.DataBuffer
216      */
217     public int getTransferType() {
218         return dataType;
219     }
220 
221     /**
222      * Returns the samples for a specified pixel in an int array,
223      * one sample per array element.
224      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
225      * not in bounds.
226      * @param x         The X coordinate of the pixel location
227      * @param y         The Y coordinate of the pixel location
228      * @param iArray    If non-null, returns the samples in this array
229      * @param data      The DataBuffer containing the image data
230      * @return the samples for the specified pixel.
231      * @see #setPixel(int, int, int[], DataBuffer)
232      *
233      * @throws NullPointerException if data is null.
234      * @throws ArrayIndexOutOfBoundsException if the coordinates are
235      * not in bounds, or if iArray is too small to hold the output.
236      */
237     public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
238 
239         int pixels[];
240 
241         if (iArray != null)
242             pixels = iArray;
243         else
244             pixels = new int[numBands];
245 
246         for (int i=0; i<numBands; i++) {
247             pixels[i] = getSample(x, y, i, data);
248         }
249 
250         return pixels;
251     }
252 
253     /**
254      * Returns data for a single pixel in a primitive array of type
255      * TransferType.  For image data supported by the Java 2D API, this
256      * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
257      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
258      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
259      * thus increasing efficiency for data transfers. Generally, obj
260      * should be passed in as null, so that the Object will be created
261      * automatically and will be of the right primitive data type.
262      * <p>
263      * The following code illustrates transferring data for one pixel from
264      * DataBuffer <code>db1</code>, whose storage layout is described by
265      * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
266      * storage layout is described by SampleModel <code>sm2</code>.
267      * The transfer will generally be more efficient than using
268      * getPixel/setPixel.
269      * <pre>
270      *       SampleModel sm1, sm2;
271      *       DataBuffer db1, db2;
272      *       sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1), db2);
273      * </pre>
274      * Using getDataElements/setDataElements to transfer between two
275      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
276      * the same number of bands, corresponding bands have the same number of
277      * bits per sample, and the TransferTypes are the same.
278      * <p>
279      * If obj is non-null, it should be a primitive array of type TransferType.
280      * Otherwise, a ClassCastException is thrown.  An
281      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
282      * not in bounds, or if obj is non-null and is not large enough to hold
283      * the pixel data.
284      * @param x         The X coordinate of the pixel location.
285      * @param y         The Y coordinate of the pixel location.
286      * @param obj       If non-null, a primitive array in which to return
287      *                  the pixel data.
288      * @param data      The DataBuffer containing the image data.
289      * @return the data elements for the specified pixel.
290      * @see #getNumDataElements
291      * @see #getTransferType
292      * @see java.awt.image.DataBuffer
293      * @see #setDataElements(int, int, Object, DataBuffer)
294      *
295      * @throws NullPointerException if data is null.
296      * @throws ArrayIndexOutOfBoundsException if the coordinates are
297      * not in bounds, or if obj is too small to hold the output.
298      */
299     public abstract Object getDataElements(int x, int y,
300                                            Object obj, DataBuffer data);
301 
302     /**
303      * Returns the pixel data for the specified rectangle of pixels in a
304      * primitive array of type TransferType.
305      * For image data supported by the Java 2D API, this
306      * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
307      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
308      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
309      * thus increasing efficiency for data transfers. Generally, obj
310      * should be passed in as null, so that the Object will be created
311      * automatically and will be of the right primitive data type.
312      * <p>
313      * The following code illustrates transferring data for a rectangular
314      * region of pixels from
315      * DataBuffer <code>db1</code>, whose storage layout is described by
316      * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
317      * storage layout is described by SampleModel <code>sm2</code>.
318      * The transfer will generally be more efficient than using
319      * getPixels/setPixels.
320      * <pre>
321      *       SampleModel sm1, sm2;
322      *       DataBuffer db1, db2;
323      *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w,
324      *                           h, null, db1), db2);
325      * </pre>
326      * Using getDataElements/setDataElements to transfer between two
327      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
328      * the same number of bands, corresponding bands have the same number of
329      * bits per sample, and the TransferTypes are the same.
330      * <p>
331      * If obj is non-null, it should be a primitive array of type TransferType.
332      * Otherwise, a ClassCastException is thrown.  An
333      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
334      * not in bounds, or if obj is non-null and is not large enough to hold
335      * the pixel data.
336      * @param x         The minimum X coordinate of the pixel rectangle.
337      * @param y         The minimum Y coordinate of the pixel rectangle.
338      * @param w         The width of the pixel rectangle.
339      * @param h         The height of the pixel rectangle.
340      * @param obj       If non-null, a primitive array in which to return
341      *                  the pixel data.
342      * @param data      The DataBuffer containing the image data.
343      * @return the data elements for the specified region of pixels.
344      * @see #getNumDataElements
345      * @see #getTransferType
346      * @see #setDataElements(int, int, int, int, Object, DataBuffer)
347      * @see java.awt.image.DataBuffer
348      *
349      * @throws NullPointerException if data is null.
350      * @throws ArrayIndexOutOfBoundsException if the coordinates are
351      * not in bounds, or if obj is too small to hold the output.
352      */
353     public Object getDataElements(int x, int y, int w, int h,
354                                   Object obj, DataBuffer data) {
355 
356         int type = getTransferType();
357         int numDataElems = getNumDataElements();
358         int cnt = 0;
359         Object o = null;
360 
361         int x1 = x + w;
362         int y1 = y + h;
363 
364         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
365             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
366         {
367             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
368         }
369 
370         switch(type) {
371 
372         case DataBuffer.TYPE_BYTE:
373 
374             byte[] btemp;
375             byte[] bdata;
376 
377             if (obj == null)
378                 bdata = new byte[numDataElems*w*h];
379             else
380                 bdata = (byte[])obj;
381 
382             for (int i=y; i<y1; i++) {
383                 for (int j=x; j<x1; j++) {
384                     o = getDataElements(j, i, o, data);
385                     btemp = (byte[])o;
386                     for (int k=0; k<numDataElems; k++) {
387                         bdata[cnt++] = btemp[k];
388                     }
389                 }
390             }
391             obj = (Object)bdata;
392             break;
393 
394         case DataBuffer.TYPE_USHORT:
395         case DataBuffer.TYPE_SHORT:
396 
397             short[] sdata;
398             short[] stemp;
399 
400             if (obj == null)
401                 sdata = new short[numDataElems*w*h];
402             else
403                 sdata = (short[])obj;
404 
405             for (int i=y; i<y1; i++) {
406                 for (int j=x; j<x1; j++) {
407                     o = getDataElements(j, i, o, data);
408                     stemp = (short[])o;
409                     for (int k=0; k<numDataElems; k++) {
410                         sdata[cnt++] = stemp[k];
411                     }
412                 }
413             }
414 
415             obj = (Object)sdata;
416             break;
417 
418         case DataBuffer.TYPE_INT:
419 
420             int[] idata;
421             int[] itemp;
422 
423             if (obj == null)
424                 idata = new int[numDataElems*w*h];
425             else
426                 idata = (int[])obj;
427 
428             for (int i=y; i<y1; i++) {
429                 for (int j=x; j<x1; j++) {
430                     o = getDataElements(j, i, o, data);
431                     itemp = (int[])o;
432                     for (int k=0; k<numDataElems; k++) {
433                         idata[cnt++] = itemp[k];
434                     }
435                 }
436             }
437 
438             obj = (Object)idata;
439             break;
440 
441         case DataBuffer.TYPE_FLOAT:
442 
443             float[] fdata;
444             float[] ftemp;
445 
446             if (obj == null)
447                 fdata = new float[numDataElems*w*h];
448             else
449                 fdata = (float[])obj;
450 
451             for (int i=y; i<y1; i++) {
452                 for (int j=x; j<x1; j++) {
453                     o = getDataElements(j, i, o, data);
454                     ftemp = (float[])o;
455                     for (int k=0; k<numDataElems; k++) {
456                         fdata[cnt++] = ftemp[k];
457                     }
458                 }
459             }
460 
461             obj = (Object)fdata;
462             break;
463 
464         case DataBuffer.TYPE_DOUBLE:
465 
466             double[] ddata;
467             double[] dtemp;
468 
469             if (obj == null)
470                 ddata = new double[numDataElems*w*h];
471             else
472                 ddata = (double[])obj;
473 
474             for (int i=y; i<y1; i++) {
475                 for (int j=x; j<x1; j++) {
476                     o = getDataElements(j, i, o, data);
477                     dtemp = (double[])o;
478                     for (int k=0; k<numDataElems; k++) {
479                         ddata[cnt++] = dtemp[k];
480                     }
481                 }
482             }
483 
484             obj = (Object)ddata;
485             break;
486         }
487 
488         return obj;
489     }
490 
491     /**
492      * Sets the data for a single pixel in the specified DataBuffer from a
493      * primitive array of type TransferType.  For image data supported by
494      * the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
495      * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
496      * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
497      * may be in a packed format, thus increasing efficiency for data
498      * transfers.
499      * <p>
500      * The following code illustrates transferring data for one pixel from
501      * DataBuffer <code>db1</code>, whose storage layout is described by
502      * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
503      * storage layout is described by SampleModel <code>sm2</code>.
504      * The transfer will generally be more efficient than using
505      * getPixel/setPixel.
506      * <pre>
507      *       SampleModel sm1, sm2;
508      *       DataBuffer db1, db2;
509      *       sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1),
510      *                           db2);
511      * </pre>
512      * Using getDataElements/setDataElements to transfer between two
513      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
514      * the same number of bands, corresponding bands have the same number of
515      * bits per sample, and the TransferTypes are the same.
516      * <p>
517      * obj must be a primitive array of type TransferType.  Otherwise,
518      * a ClassCastException is thrown.  An
519      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
520      * not in bounds, or if obj is not large enough to hold the pixel data.
521      * @param x         The X coordinate of the pixel location.
522      * @param y         The Y coordinate of the pixel location.
523      * @param obj       A primitive array containing pixel data.
524      * @param data      The DataBuffer containing the image data.
525      * @see #getNumDataElements
526      * @see #getTransferType
527      * @see #getDataElements(int, int, Object, DataBuffer)
528      * @see java.awt.image.DataBuffer
529      *
530      * @throws NullPointerException if data is null.
531      * @throws ArrayIndexOutOfBoundsException if the coordinates are
532      * not in bounds, or if obj is too small to hold the input.
533      */
534     public abstract void setDataElements(int x, int y,
535                                          Object obj, DataBuffer data);
536 
537     /**
538      * Sets the data for a rectangle of pixels in the specified DataBuffer
539      * from a primitive array of type TransferType.  For image data supported
540      * by the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
541      * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
542      * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.  Data in the array
543      * may be in a packed format, thus increasing efficiency for data
544      * transfers.
545      * <p>
546      * The following code illustrates transferring data for a rectangular
547      * region of pixels from
548      * DataBuffer <code>db1</code>, whose storage layout is described by
549      * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
550      * storage layout is described by SampleModel <code>sm2</code>.
551      * The transfer will generally be more efficient than using
552      * getPixels/setPixels.
553      * <pre>
554      *       SampleModel sm1, sm2;
555      *       DataBuffer db1, db2;
556      *       sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w, h,
557      *                           null, db1), db2);
558      * </pre>
559      * Using getDataElements/setDataElements to transfer between two
560      * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
561      * the same number of bands, corresponding bands have the same number of
562      * bits per sample, and the TransferTypes are the same.
563      * <p>
564      * obj must be a primitive array of type TransferType.  Otherwise,
565      * a ClassCastException is thrown.  An
566      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
567      * not in bounds, or if obj is not large enough to hold the pixel data.
568      * @param x         The minimum X coordinate of the pixel rectangle.
569      * @param y         The minimum Y coordinate of the pixel rectangle.
570      * @param w         The width of the pixel rectangle.
571      * @param h         The height of the pixel rectangle.
572      * @param obj       A primitive array containing pixel data.
573      * @param data      The DataBuffer containing the image data.
574      * @see #getNumDataElements
575      * @see #getTransferType
576      * @see #getDataElements(int, int, int, int, Object, DataBuffer)
577      * @see java.awt.image.DataBuffer
578      *
579      * @throws NullPointerException if data is null.
580      * @throws ArrayIndexOutOfBoundsException if the coordinates are
581      * not in bounds, or if obj is too small to hold the input.
582      */
583     public void setDataElements(int x, int y, int w, int h,
584                                 Object obj, DataBuffer data) {
585 
586         int cnt = 0;
587         Object o = null;
588         int type = getTransferType();
589         int numDataElems = getNumDataElements();
590 
591         int x1 = x + w;
592         int y1 = y + h;
593 
594         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
595             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
596         {
597             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
598         }
599 
600         switch(type) {
601 
602         case DataBuffer.TYPE_BYTE:
603 
604             byte[] barray = (byte[])obj;
605             byte[] btemp = new byte[numDataElems];
606 
607             for (int i=y; i<y1; i++) {
608                 for (int j=x; j<x1; j++) {
609                     for (int k=0; k<numDataElems; k++) {
610                         btemp[k] = barray[cnt++];
611                     }
612 
613                     setDataElements(j, i, btemp, data);
614                 }
615             }
616             break;
617 
618         case DataBuffer.TYPE_USHORT:
619         case DataBuffer.TYPE_SHORT:
620 
621             short[] sarray = (short[])obj;
622             short[] stemp = new short[numDataElems];
623 
624             for (int i=y; i<y1; i++) {
625                 for (int j=x; j<x1; j++) {
626                     for (int k=0; k<numDataElems; k++) {
627                         stemp[k] = sarray[cnt++];
628                     }
629 
630                     setDataElements(j, i, stemp, data);
631                 }
632             }
633             break;
634 
635         case DataBuffer.TYPE_INT:
636 
637             int[] iArray = (int[])obj;
638             int[] itemp = new int[numDataElems];
639 
640             for (int i=y; i<y1; i++) {
641                 for (int j=x; j<x1; j++) {
642                     for (int k=0; k<numDataElems; k++) {
643                         itemp[k] = iArray[cnt++];
644                     }
645 
646                     setDataElements(j, i, itemp, data);
647                 }
648             }
649             break;
650 
651         case DataBuffer.TYPE_FLOAT:
652 
653             float[] fArray = (float[])obj;
654             float[] ftemp = new float[numDataElems];
655 
656             for (int i=y; i<y1; i++) {
657                 for (int j=x; j<x1; j++) {
658                     for (int k=0; k<numDataElems; k++) {
659                         ftemp[k] = fArray[cnt++];
660                     }
661 
662                     setDataElements(j, i, ftemp, data);
663                 }
664             }
665             break;
666 
667         case DataBuffer.TYPE_DOUBLE:
668 
669             double[] dArray = (double[])obj;
670             double[] dtemp = new double[numDataElems];
671 
672             for (int i=y; i<y1; i++) {
673                 for (int j=x; j<x1; j++) {
674                     for (int k=0; k<numDataElems; k++) {
675                         dtemp[k] = dArray[cnt++];
676                     }
677 
678                     setDataElements(j, i, dtemp, data);
679                 }
680             }
681             break;
682         }
683 
684     }
685 
686     /**
687      * Returns the samples for the specified pixel in an array of float.
688      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
689      * not in bounds.
690      * @param x         The X coordinate of the pixel location.
691      * @param y         The Y coordinate of the pixel location.
692      * @param fArray    If non-null, returns the samples in this array.
693      * @param data      The DataBuffer containing the image data.
694      * @return the samples for the specified pixel.
695      * @see #setPixel(int, int, float[], DataBuffer)
696      *
697      * @throws NullPointerException if data is null.
698      * @throws ArrayIndexOutOfBoundsException if the coordinates are
699      * not in bounds, or if fArray is too small to hold the output.
700      */
701     public float[] getPixel(int x, int y, float fArray[],
702                             DataBuffer data) {
703 
704         float pixels[];
705 
706         if (fArray != null)
707             pixels = fArray;
708         else
709             pixels = new float[numBands];
710 
711         for (int i=0; i<numBands; i++)
712             pixels[i] = getSampleFloat(x, y, i, data);
713 
714         return pixels;
715     }
716 
717     /**
718      * Returns the samples for the specified pixel in an array of double.
719      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
720      * not in bounds.
721      * @param x         The X coordinate of the pixel location.
722      * @param y         The Y coordinate of the pixel location.
723      * @param dArray    If non-null, returns the samples in this array.
724      * @param data      The DataBuffer containing the image data.
725      * @return the samples for the specified pixel.
726      * @see #setPixel(int, int, double[], DataBuffer)
727      *
728      * @throws NullPointerException if data is null.
729      * @throws ArrayIndexOutOfBoundsException if the coordinates are
730      * not in bounds, or if dArray is too small to hold the output.
731      */
732     public double[] getPixel(int x, int y, double dArray[],
733                              DataBuffer data) {
734 
735         double pixels[];
736 
737         if(dArray != null)
738             pixels = dArray;
739         else
740             pixels = new double[numBands];
741 
742         for (int i=0; i<numBands; i++)
743             pixels[i] = getSampleDouble(x, y, i, data);
744 
745         return pixels;
746     }
747 
748     /**
749      * Returns all samples for a rectangle of pixels in an
750      * int array, one sample per array element.
751      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
752      * not in bounds.
753      * @param x         The X coordinate of the upper left pixel location.
754      * @param y         The Y coordinate of the upper left pixel location.
755      * @param w         The width of the pixel rectangle.
756      * @param h         The height of the pixel rectangle.
757      * @param iArray    If non-null, returns the samples in this array.
758      * @param data      The DataBuffer containing the image data.
759      * @return the samples for the specified region of pixels.
760      * @see #setPixels(int, int, int, int, int[], DataBuffer)
761      *
762      * @throws NullPointerException if data is null.
763      * @throws ArrayIndexOutOfBoundsException if the coordinates are
764      * not in bounds, or if iArray is too small to hold the output.
765      */
766     public int[] getPixels(int x, int y, int w, int h,
767                            int iArray[], DataBuffer data) {
768 
769         int pixels[];
770         int Offset=0;
771         int x1 = x + w;
772         int y1 = y + h;
773 
774         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
775             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
776         {
777             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
778         }
779 
780         if (iArray != null)
781             pixels = iArray;
782         else
783             pixels = new int[numBands * w * h];
784 
785         for (int i=y; i<y1; i++) {
786             for (int j=x; j<x1; j++) {
787                 for(int k=0; k<numBands; k++) {
788                     pixels[Offset++] = getSample(j, i, k, data);
789                 }
790             }
791         }
792 
793         return pixels;
794     }
795 
796     /**
797      * Returns all samples for a rectangle of pixels in a float
798      * array, one sample per array element.
799      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
800      * not in bounds.
801      * @param x         The X coordinate of the upper left pixel location.
802      * @param y         The Y coordinate of the upper left pixel location.
803      * @param w         The width of the pixel rectangle.
804      * @param h         The height of the pixel rectangle.
805      * @param fArray    If non-null, returns the samples in this array.
806      * @param data      The DataBuffer containing the image data.
807      * @return the samples for the specified region of pixels.
808      * @see #setPixels(int, int, int, int, float[], DataBuffer)
809      *
810      * @throws NullPointerException if data is null.
811      * @throws ArrayIndexOutOfBoundsException if the coordinates are
812      * not in bounds, or if fArray is too small to hold the output.
813      */
814     public float[] getPixels(int x, int y, int w, int h,
815                              float fArray[], DataBuffer data) {
816 
817         float pixels[];
818         int Offset = 0;
819         int x1 = x + w;
820         int y1 = y + h;
821 
822         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
823             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
824         {
825             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
826         }
827 
828         if (fArray != null)
829             pixels = fArray;
830         else
831             pixels = new float[numBands * w * h];
832 
833         for (int i=y; i<y1; i++) {
834             for(int j=x; j<x1; j++) {
835                 for(int k=0; k<numBands; k++) {
836                     pixels[Offset++] = getSampleFloat(j, i, k, data);
837                 }
838             }
839         }
840 
841         return pixels;
842     }
843 
844     /**
845      * Returns all samples for a rectangle of pixels in a double
846      * array, one sample per array element.
847      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
848      * not in bounds.
849      * @param x         The X coordinate of the upper left pixel location.
850      * @param y         The Y coordinate of the upper left pixel location.
851      * @param w         The width of the pixel rectangle.
852      * @param h         The height of the pixel rectangle.
853      * @param dArray    If non-null, returns the samples in this array.
854      * @param data      The DataBuffer containing the image data.
855      * @return the samples for the specified region of pixels.
856      * @see #setPixels(int, int, int, int, double[], DataBuffer)
857      *
858      * @throws NullPointerException if data is null.
859      * @throws ArrayIndexOutOfBoundsException if the coordinates are
860      * not in bounds, or if dArray is too small to hold the output.
861      */
862     public double[] getPixels(int x, int y, int w, int h,
863                               double dArray[], DataBuffer data) {
864         double pixels[];
865         int    Offset = 0;
866         int x1 = x + w;
867         int y1 = y + h;
868 
869         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
870             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
871         {
872             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
873         }
874 
875         if (dArray != null)
876             pixels = dArray;
877         else
878             pixels = new double[numBands * w * h];
879 
880         // Fix 4217412
881         for (int i=y; i<y1; i++) {
882             for (int j=x; j<x1; j++) {
883                 for (int k=0; k<numBands; k++) {
884                     pixels[Offset++] = getSampleDouble(j, i, k, data);
885                 }
886             }
887         }
888 
889         return pixels;
890     }
891 
892 
893     /**
894      * Returns the sample in a specified band for the pixel located
895      * at (x,y) as an int.
896      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
897      * not in bounds.
898      * @param x         The X coordinate of the pixel location.
899      * @param y         The Y coordinate of the pixel location.
900      * @param b         The band to return.
901      * @param data      The DataBuffer containing the image data.
902      * @return the sample in a specified band for the specified pixel.
903      * @see #setSample(int, int, int, int, DataBuffer)
904      *
905      * @throws NullPointerException if data is null.
906      * @throws ArrayIndexOutOfBoundsException if the coordinates or
907      * the band index are not in bounds.
908      */
909     public abstract int getSample(int x, int y, int b, DataBuffer data);
910 
911 
912     /**
913      * Returns the sample in a specified band
914      * for the pixel located at (x,y) as a float.
915      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
916      * not in bounds.
917      * @param x         The X coordinate of the pixel location.
918      * @param y         The Y coordinate of the pixel location.
919      * @param b         The band to return.
920      * @param data      The DataBuffer containing the image data.
921      * @return the sample in a specified band for the specified pixel.
922      *
923      * @throws NullPointerException if data is null.
924      * @throws ArrayIndexOutOfBoundsException if the coordinates or
925      * the band index are not in bounds.
926      */
927     public float getSampleFloat(int x, int y, int b, DataBuffer data) {
928 
929         float sample;
930         sample = (float) getSample(x, y, b, data);
931         return sample;
932     }
933 
934     /**
935      * Returns the sample in a specified band
936      * for a pixel located at (x,y) as a double.
937      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
938      * not in bounds.
939      * @param x         The X coordinate of the pixel location.
940      * @param y         The Y coordinate of the pixel location.
941      * @param b         The band to return.
942      * @param data      The DataBuffer containing the image data.
943      * @return the sample in a specified band for the specified pixel.
944      *
945      * @throws NullPointerException if data is null.
946      * @throws ArrayIndexOutOfBoundsException if the coordinates or
947      * the band index are not in bounds.
948      */
949     public double getSampleDouble(int x, int y, int b, DataBuffer data) {
950 
951         double sample;
952 
953         sample = (double) getSample(x, y, b, data);
954         return sample;
955     }
956 
957     /**
958      * Returns the samples for a specified band for the specified rectangle
959      * of pixels in an int array, one sample per array element.
960      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
961      * not in bounds.
962      * @param x         The X coordinate of the upper left pixel location.
963      * @param y         The Y coordinate of the upper left pixel location.
964      * @param w         The width of the pixel rectangle.
965      * @param h         The height of the pixel rectangle.
966      * @param b         The band to return.
967      * @param iArray    If non-null, returns the samples in this array.
968      * @param data      The DataBuffer containing the image data.
969      * @return the samples for the specified band for the specified region
970      *         of pixels.
971      * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
972      *
973      * @throws NullPointerException if data is null.
974      * @throws ArrayIndexOutOfBoundsException if the coordinates or
975      * the band index are not in bounds, or if iArray is too small to
976      * hold the output.
977      */
978     public int[] getSamples(int x, int y, int w, int h, int b,
979                             int iArray[], DataBuffer data) {
980         int pixels[];
981         int Offset=0;
982         int x1 = x + w;
983         int y1 = y + h;
984 
985         if (x < 0 || x1 < x || x1 > width ||
986             y < 0 || y1 < y || y1 > height)
987         {
988             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
989         }
990 
991         if (iArray != null)
992             pixels = iArray;
993         else
994             pixels = new int[w * h];
995 
996         for(int i=y; i<y1; i++) {
997             for (int j=x; j<x1; j++) {
998                 pixels[Offset++] = getSample(j, i, b, data);
999             }
1000         }
1001 
1002         return pixels;
1003     }
1004 
1005     /**
1006      * Returns the samples for a specified band for the specified rectangle
1007      * of pixels in a float array, one sample per array element.
1008      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1009      * not in bounds.
1010      * @param x         The X coordinate of the upper left pixel location.
1011      * @param y         The Y coordinate of the upper left pixel location.
1012      * @param w         The width of the pixel rectangle.
1013      * @param h         The height of the pixel rectangle.
1014      * @param b         The band to return.
1015      * @param fArray    If non-null, returns the samples in this array.
1016      * @param data      The DataBuffer containing the image data.
1017      * @return the samples for the specified band for the specified region
1018      *         of pixels.
1019      * @see #setSamples(int, int, int, int, int, float[], DataBuffer)
1020      *
1021      * @throws NullPointerException if data is null.
1022      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1023      * the band index are not in bounds, or if fArray is too small to
1024      * hold the output.
1025      */
1026     public float[] getSamples(int x, int y, int w, int h,
1027                               int b, float fArray[],
1028                               DataBuffer data) {
1029         float pixels[];
1030         int   Offset=0;
1031         int x1 = x + w;
1032         int y1 = y + h;
1033 
1034         if (x < 0 || x1 < x || x1 > width ||
1035             y < 0 || y1 < y || y1 > height)
1036         {
1037             throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
1038         }
1039 
1040         if (fArray != null)
1041             pixels = fArray;
1042         else
1043             pixels = new float[w * h];
1044 
1045         for (int i=y; i<y1; i++) {
1046             for (int j=x; j<x1; j++) {
1047                 pixels[Offset++] = getSampleFloat(j, i, b, data);
1048             }
1049         }
1050 
1051         return pixels;
1052     }
1053 
1054     /**
1055      * Returns the samples for a specified band for a specified rectangle
1056      * of pixels in a double array, one sample per array element.
1057      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1058      * not in bounds.
1059      * @param x         The X coordinate of the upper left pixel location.
1060      * @param y         The Y coordinate of the upper left pixel location.
1061      * @param w         The width of the pixel rectangle.
1062      * @param h         The height of the pixel rectangle.
1063      * @param b         The band to return.
1064      * @param dArray    If non-null, returns the samples in this array.
1065      * @param data      The DataBuffer containing the image data.
1066      * @return the samples for the specified band for the specified region
1067      *         of pixels.
1068      * @see #setSamples(int, int, int, int, int, double[], DataBuffer)
1069      *
1070      * @throws NullPointerException if data is null.
1071      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1072      * the band index are not in bounds, or if dArray is too small to
1073      * hold the output.
1074      */
1075     public double[] getSamples(int x, int y, int w, int h,
1076                                int b, double dArray[],
1077                                DataBuffer data) {
1078         double pixels[];
1079         int    Offset=0;
1080         int x1 = x + w;
1081         int y1 = y + h;
1082 
1083         if (x < 0 || x1 < x || x1 > width ||
1084             y < 0 || y1 < y || y1 > height)
1085         {
1086             throw new ArrayIndexOutOfBoundsException("Invalid coordinates");
1087         }
1088 
1089         if (dArray != null)
1090             pixels = dArray;
1091         else
1092             pixels = new double[w * h];
1093 
1094         for (int i=y; i<y1; i++) {
1095             for (int j=x; j<x1; j++) {
1096                 pixels[Offset++] = getSampleDouble(j, i, b, data);
1097             }
1098         }
1099 
1100         return pixels;
1101     }
1102 
1103     /**
1104      * Sets a pixel in  the DataBuffer using an int array of samples for input.
1105      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1106      * not in bounds.
1107      * @param x         The X coordinate of the pixel location.
1108      * @param y         The Y coordinate of the pixel location.
1109      * @param iArray    The input samples in an int array.
1110      * @param data      The DataBuffer containing the image data.
1111      * @see #getPixel(int, int, int[], DataBuffer)
1112      *
1113      * @throws NullPointerException if iArray or data is null.
1114      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1115      * not in bounds, or if iArray is too small to hold the input.
1116      */
1117     public void setPixel(int x, int y, int iArray[], DataBuffer data) {
1118 
1119         for (int i=0; i<numBands; i++)
1120             setSample(x, y, i, iArray[i], data);
1121     }
1122 
1123     /**
1124      * Sets a pixel in the DataBuffer using a float array of samples for input.
1125      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1126      * not in bounds.
1127      * @param x         The X coordinate of the pixel location.
1128      * @param y         The Y coordinate of the pixel location.
1129      * @param fArray    The input samples in a float array.
1130      * @param data      The DataBuffer containing the image data.
1131      * @see #getPixel(int, int, float[], DataBuffer)
1132      *
1133      * @throws NullPointerException if fArray or data is null.
1134      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1135      * not in bounds, or if fArray is too small to hold the input.
1136      */
1137     public void setPixel(int x, int y, float fArray[], DataBuffer data) {
1138 
1139         for (int i=0; i<numBands; i++)
1140             setSample(x, y, i, fArray[i], data);
1141     }
1142 
1143     /**
1144      * Sets a pixel in the DataBuffer using a double array of samples
1145      * for input.
1146      * @param x         The X coordinate of the pixel location.
1147      * @param y         The Y coordinate of the pixel location.
1148      * @param dArray    The input samples in a double array.
1149      * @param data      The DataBuffer containing the image data.
1150      * @see #getPixel(int, int, double[], DataBuffer)
1151      *
1152      * @throws NullPointerException if dArray or data is null.
1153      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1154      * not in bounds, or if fArray is too small to hold the input.
1155      */
1156     public void setPixel(int x, int y, double dArray[], DataBuffer data) {
1157 
1158         for (int i=0; i<numBands; i++)
1159             setSample(x, y, i, dArray[i], data);
1160     }
1161 
1162     /**
1163      * Sets all samples for a rectangle of pixels from an int array containing
1164      * one sample per array element.
1165      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1166      * not in bounds.
1167      * @param x         The X coordinate of the upper left pixel location.
1168      * @param y         The Y coordinate of the upper left pixel location.
1169      * @param w         The width of the pixel rectangle.
1170      * @param h         The height of the pixel rectangle.
1171      * @param iArray    The input samples in an int array.
1172      * @param data      The DataBuffer containing the image data.
1173      * @see #getPixels(int, int, int, int, int[], DataBuffer)
1174      *
1175      * @throws NullPointerException if iArray or data is null.
1176      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1177      * not in bounds, or if iArray is too small to hold the input.
1178      */
1179     public void setPixels(int x, int y, int w, int h,
1180                           int iArray[], DataBuffer data) {
1181         int Offset=0;
1182         int x1 = x + w;
1183         int y1 = y + h;
1184 
1185         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
1186             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1187         {
1188             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1189         }
1190 
1191         for (int i=y; i<y1; i++) {
1192             for (int j=x; j<x1; j++) {
1193                 for (int k=0; k<numBands; k++) {
1194                     setSample(j, i, k, iArray[Offset++], data);
1195                 }
1196             }
1197         }
1198     }
1199 
1200     /**
1201      * Sets all samples for a rectangle of pixels from a float array containing
1202      * one sample per array element.
1203      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1204      * not in bounds.
1205      * @param x         The X coordinate of the upper left pixel location.
1206      * @param y         The Y coordinate of the upper left pixel location.
1207      * @param w         The width of the pixel rectangle.
1208      * @param h         The height of the pixel rectangle.
1209      * @param fArray    The input samples in a float array.
1210      * @param data      The DataBuffer containing the image data.
1211      * @see #getPixels(int, int, int, int, float[], DataBuffer)
1212      *
1213      * @throws NullPointerException if fArray or data is null.
1214      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1215      * not in bounds, or if fArray is too small to hold the input.
1216      */
1217     public void setPixels(int x, int y, int w, int h,
1218                           float fArray[], DataBuffer data) {
1219         int Offset=0;
1220         int x1 = x + w;
1221         int y1 = y + h;
1222 
1223         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width||
1224             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1225         {
1226             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1227         }
1228 
1229         for (int i=y; i<y1; i++) {
1230             for (int j=x; j<x1; j++) {
1231                 for(int k=0; k<numBands; k++) {
1232                     setSample(j, i, k, fArray[Offset++], data);
1233                 }
1234             }
1235         }
1236     }
1237 
1238     /**
1239      * Sets all samples for a rectangle of pixels from a double array
1240      * containing one sample per array element.
1241      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1242      * not in bounds.
1243      * @param x         The X coordinate of the upper left pixel location.
1244      * @param y         The Y coordinate of the upper left pixel location.
1245      * @param w         The width of the pixel rectangle.
1246      * @param h         The height of the pixel rectangle.
1247      * @param dArray    The input samples in a double array.
1248      * @param data      The DataBuffer containing the image data.
1249      * @see #getPixels(int, int, int, int, double[], DataBuffer)
1250      *
1251      * @throws NullPointerException if dArray or data is null.
1252      * @throws ArrayIndexOutOfBoundsException if the coordinates are
1253      * not in bounds, or if dArray is too small to hold the input.
1254      */
1255     public void setPixels(int x, int y, int w, int h,
1256                           double dArray[], DataBuffer data) {
1257         int Offset=0;
1258         int x1 = x + w;
1259         int y1 = y + h;
1260 
1261         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
1262             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1263         {
1264             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1265         }
1266 
1267         for (int i=y; i<y1; i++) {
1268             for (int j=x; j<x1; j++) {
1269                 for (int k=0; k<numBands; k++) {
1270                     setSample(j, i, k, dArray[Offset++], data);
1271                 }
1272             }
1273         }
1274     }
1275 
1276     /**
1277      * Sets a sample in the specified band for the pixel located at (x,y)
1278      * in the DataBuffer using an int for input.
1279      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1280      * not in bounds.
1281      * @param x         The X coordinate of the pixel location.
1282      * @param y         The Y coordinate of the pixel location.
1283      * @param b         The band to set.
1284      * @param s         The input sample as an int.
1285      * @param data      The DataBuffer containing the image data.
1286      * @see #getSample(int, int, int,  DataBuffer)
1287      *
1288      * @throws NullPointerException if data is null.
1289      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1290      * the band index are not in bounds.
1291      */
1292     public abstract void setSample(int x, int y, int b,
1293                                    int s,
1294                                    DataBuffer data);
1295 
1296     /**
1297      * Sets a sample in the specified band for the pixel located at (x,y)
1298      * in the DataBuffer using a float for input.
1299      * The default implementation of this method casts the input
1300      * float sample to an int and then calls the
1301      * <code>setSample(int, int, int, DataBuffer)</code> method using
1302      * that int value.
1303      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1304      * not in bounds.
1305      * @param x         The X coordinate of the pixel location.
1306      * @param y         The Y coordinate of the pixel location.
1307      * @param b         The band to set.
1308      * @param s         The input sample as a float.
1309      * @param data      The DataBuffer containing the image data.
1310      * @see #getSample(int, int, int, DataBuffer)
1311      *
1312      * @throws NullPointerException if data is null.
1313      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1314      * the band index are not in bounds.
1315      */
1316     public void setSample(int x, int y, int b,
1317                           float s ,
1318                           DataBuffer data) {
1319         int sample = (int)s;
1320 
1321         setSample(x, y, b, sample, data);
1322     }
1323 
1324     /**
1325      * Sets a sample in the specified band for the pixel located at (x,y)
1326      * in the DataBuffer using a double for input.
1327      * The default implementation of this method casts the input
1328      * double sample to an int and then calls the
1329      * <code>setSample(int, int, int, DataBuffer)</code> method using
1330      * that int value.
1331      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1332      * not in bounds.
1333      * @param x         The X coordinate of the pixel location.
1334      * @param y         The Y coordinate of the pixel location.
1335      * @param b         The band to set.
1336      * @param s         The input sample as a double.
1337      * @param data      The DataBuffer containing the image data.
1338      * @see #getSample(int, int, int, DataBuffer)
1339      *
1340      * @throws NullPointerException if data is null.
1341      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1342      * the band index are not in bounds.
1343      */
1344     public void setSample(int x, int y, int b,
1345                           double s,
1346                           DataBuffer data) {
1347         int sample = (int)s;
1348 
1349         setSample(x, y, b, sample, data);
1350     }
1351 
1352     /**
1353      * Sets the samples in the specified band for the specified rectangle
1354      * of pixels from an int array containing one sample per array element.
1355      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1356      * not in bounds.
1357      * @param x         The X coordinate of the upper left pixel location.
1358      * @param y         The Y coordinate of the upper left pixel location.
1359      * @param w         The width of the pixel rectangle.
1360      * @param h         The height of the pixel rectangle.
1361      * @param b         The band to set.
1362      * @param iArray    The input samples in an int array.
1363      * @param data      The DataBuffer containing the image data.
1364      * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
1365      *
1366      * @throws NullPointerException if iArray or data is null.
1367      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1368      * the band index are not in bounds, or if iArray is too small to
1369      * hold the input.
1370      */
1371     public void setSamples(int x, int y, int w, int h, int b,
1372                            int iArray[], DataBuffer data) {
1373 
1374         int Offset=0;
1375         int x1 = x + w;
1376         int y1 = y + h;
1377         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
1378             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1379         {
1380             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1381         }
1382 
1383         for (int i=y; i<y1; i++) {
1384             for (int j=x; j<x1; j++) {
1385                 setSample(j, i, b, iArray[Offset++], data);
1386             }
1387         }
1388     }
1389 
1390     /**
1391      * Sets the samples in the specified band for the specified rectangle
1392      * of pixels from a float array containing one sample per array element.
1393      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1394      * not in bounds.
1395      * @param x         The X coordinate of the upper left pixel location.
1396      * @param y         The Y coordinate of the upper left pixel location.
1397      * @param w         The width of the pixel rectangle.
1398      * @param h         The height of the pixel rectangle.
1399      * @param b         The band to set.
1400      * @param fArray    The input samples in a float array.
1401      * @param data      The DataBuffer containing the image data.
1402      * @see #getSamples(int, int, int, int, int, float[], DataBuffer)
1403      *
1404      * @throws NullPointerException if fArray or data is null.
1405      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1406      * the band index are not in bounds, or if fArray is too small to
1407      * hold the input.
1408      */
1409     public void setSamples(int x, int y, int w, int h, int b,
1410                            float fArray[], DataBuffer data) {
1411         int Offset=0;
1412         int x1 = x + w;
1413         int y1 = y + h;
1414 
1415         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
1416             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1417         {
1418             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1419         }
1420 
1421         for (int i=y; i<y1; i++) {
1422             for (int j=x; j<x1; j++) {
1423                 setSample(j, i, b, fArray[Offset++], data);
1424             }
1425         }
1426     }
1427 
1428     /**
1429      * Sets the samples in the specified band for the specified rectangle
1430      * of pixels from a double array containing one sample per array element.
1431      * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
1432      * not in bounds.
1433      * @param x         The X coordinate of the upper left pixel location.
1434      * @param y         The Y coordinate of the upper left pixel location.
1435      * @param w         The width of the pixel rectangle.
1436      * @param h         The height of the pixel rectangle.
1437      * @param b         The band to set.
1438      * @param dArray    The input samples in a double array.
1439      * @param data      The DataBuffer containing the image data.
1440      * @see #getSamples(int, int, int, int, int, double[], DataBuffer)
1441      *
1442      * @throws NullPointerException if dArray or data is null.
1443      * @throws ArrayIndexOutOfBoundsException if the coordinates or
1444      * the band index are not in bounds, or if dArray is too small to
1445      * hold the input.
1446      */
1447     public void setSamples(int x, int y, int w, int h, int b,
1448                            double dArray[], DataBuffer data) {
1449         int Offset=0;
1450         int x1 = x + w;
1451         int y1 = y + h;
1452 
1453 
1454         if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
1455             y < 0 || y >= height || h > height || y1 < 0 || y1 > height)
1456         {
1457             throw new ArrayIndexOutOfBoundsException("Invalid coordinates.");
1458         }
1459 
1460         for (int i=y; i<y1; i++) {
1461             for (int j=x; j<x1; j++) {
1462                 setSample(j, i, b, dArray[Offset++], data);
1463             }
1464         }
1465     }
1466 
1467     /**
1468      *  Creates a SampleModel which describes data in this SampleModel's
1469      *  format, but with a different width and height.
1470      *  @param w the width of the image data
1471      *  @param h the height of the image data
1472      *  @return a <code>SampleModel</code> describing the same image
1473      *          data as this <code>SampleModel</code>, but with a
1474      *          different size.
1475      */
1476     public abstract SampleModel createCompatibleSampleModel(int w, int h);
1477 
1478     /**
1479      * Creates a new SampleModel
1480      * with a subset of the bands of this
1481      * SampleModel.
1482      * @param bands the subset of bands of this <code>SampleModel</code>
1483      * @return a <code>SampleModel</code> with a subset of bands of this
1484      *         <code>SampleModel</code>.
1485      */
1486     public abstract SampleModel createSubsetSampleModel(int bands[]);
1487 
1488     /**
1489      * Creates a DataBuffer that corresponds to this SampleModel.
1490      * The DataBuffer's width and height will match this SampleModel's.
1491      * @return a <code>DataBuffer</code> corresponding to this
1492      *         <code>SampleModel</code>.
1493      */
1494     public abstract DataBuffer createDataBuffer();
1495 
1496     /** Returns the size in bits of samples for all bands.
1497      *  @return the size of samples for all bands.
1498      */
1499     public abstract int[] getSampleSize();
1500 
1501     /** Returns the size in bits of samples for the specified band.
1502      *  @param band the specified band
1503      *  @return the size of the samples of the specified band.
1504      */
1505     public abstract int getSampleSize(int band);
1506 
1507 }