001    /* Copyright (C) 2000, 2001, 2002, 2005, 2006,  Free Software Foundation
002    
003    This file is part of GNU Classpath.
004    
005    GNU Classpath is free software; you can redistribute it and/or modify
006    it under the terms of the GNU General Public License as published by
007    the Free Software Foundation; either version 2, or (at your option)
008    any later version.
009    
010    GNU Classpath is distributed in the hope that it will be useful, but
011    WITHOUT ANY WARRANTY; without even the implied warranty of
012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013    General Public License for more details.
014    
015    You should have received a copy of the GNU General Public License
016    along with GNU Classpath; see the file COPYING.  If not, write to the
017    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
018    02110-1301 USA.
019    
020    Linking this library statically or dynamically with other modules is
021    making a combined work based on this library.  Thus, the terms and
022    conditions of the GNU General Public License cover the whole
023    combination.
024    
025    As a special exception, the copyright holders of this library give you
026    permission to link this library with independent modules to produce an
027    executable, regardless of the license terms of these independent
028    modules, and to copy and distribute the resulting executable under
029    terms of your choice, provided that you also meet, for each linked
030    independent module, the terms and conditions of the license of that
031    module.  An independent module is a module which is not derived from
032    or based on this library.  If you modify this library, you may extend
033    this exception to your version of the library, but you are not
034    obligated to do so.  If you do not wish to do so, delete this
035    exception statement from your version. */
036    
037    package java.awt.image;
038    
039    /**
040     * A <code>SampleModel</code> is used to access pixel data from a 
041     * {@link DataBuffer}.  This is used by the {@link Raster} class.
042     * 
043     * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
044     */
045    public abstract class SampleModel
046    {
047      /** Width of image described. */
048      protected int width;
049      
050      /** Height of image described. */
051      protected int height;
052      
053      /** Number of bands in the image described.  Package-private here,
054          shadowed by ComponentSampleModel. */
055      protected int numBands;
056    
057      /** 
058       * The DataBuffer type that is used to store the data of the image
059       * described.
060       */
061      protected int dataType;
062    
063      /**
064       * Creates a new sample model with the specified attributes.
065       * 
066       * @param dataType  the data type (one of {@link DataBuffer#TYPE_BYTE},
067       *   {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_SHORT},
068       *   {@link DataBuffer#TYPE_INT}, {@link DataBuffer#TYPE_FLOAT}, 
069       *   {@link DataBuffer#TYPE_DOUBLE} or {@link DataBuffer#TYPE_UNDEFINED}).
070       * @param w  the width in pixels (must be greater than zero).
071       * @param h  the height in pixels (must be greater than zero).
072       * @param numBands  the number of bands (must be greater than zero).
073       * 
074       * @throws IllegalArgumentException if <code>dataType</code> is not one of 
075       *   the listed values.
076       * @throws IllegalArgumentException if <code>w</code> is less than or equal
077       *   to zero.
078       * @throws IllegalArgumentException if <code>h</code> is less than or equal 
079       *   to zero.
080       * @throws IllegalArgumentException if <code>w * h</code> is greater than
081       *   {@link Integer#MAX_VALUE}.
082       */
083      public SampleModel(int dataType, int w, int h, int numBands)
084      {
085        if (dataType != DataBuffer.TYPE_UNDEFINED)
086          if (dataType < DataBuffer.TYPE_BYTE || dataType > DataBuffer.TYPE_DOUBLE)
087            throw new IllegalArgumentException("Unrecognised 'dataType' argument.");
088        
089        if ((w <= 0) || (h <= 0)) 
090          throw new IllegalArgumentException((w <= 0 ? " width<=0" : " width is ok")
091              + (h <= 0 ? " height<=0" : " height is ok"));
092            
093        long area = (long) w * (long) h;
094        if (area > Integer.MAX_VALUE)
095          throw new IllegalArgumentException("w * h exceeds Integer.MAX_VALUE.");
096    
097        if (numBands <= 0)
098          throw new IllegalArgumentException("Requires numBands > 0.");
099          
100        this.dataType = dataType;
101        this.width = w;
102        this.height = h;
103        this.numBands = numBands;  
104      }
105      
106      /**
107       * Returns the width of the pixel data accessible via this 
108       * <code>SampleModel</code>.
109       * 
110       * @return The width.
111       * 
112       * @see #getHeight()
113       */
114      public final int getWidth()
115      {
116        return width;
117      }
118    
119      /**
120       * Returns the height of the pixel data accessible via this 
121       * <code>SampleModel</code>.
122       * 
123       * @return The height.
124       * 
125       * @see #getWidth()
126       */
127      public final int getHeight()
128      {
129        return height;
130      }
131    
132      /**
133       * Returns the number of bands for this <code>SampleModel</code>.
134       * 
135       * @return The number of bands.
136       */
137      public final int getNumBands()
138      {
139        return numBands;
140      }
141        
142      public abstract int getNumDataElements();
143      
144      /**
145       * Returns the type of the {@link DataBuffer} that this 
146       * <code>SampleModel</code> accesses.
147       * 
148       * @return The data buffer type.
149       */
150      public final int getDataType()
151      {
152        return dataType;
153      }
154    
155      public int getTransferType()
156      {
157        // FIXME: Is this a reasonable default implementation?
158        return dataType;
159      }
160    
161      /**
162       * Returns an array containing the samples for the pixel at (x, y) in the
163       * specified data buffer.  If <code>iArray</code> is not <code>null</code>,
164       * it will be populated with the sample values and returned as the result of
165       * this function (this avoids allocating a new array instance).
166       * 
167       * @param x  the x-coordinate of the pixel.
168       * @param y  the y-coordinate of the pixel.
169       * @param iArray  an array to populate with the sample values and return as 
170       *     the result (if <code>null</code>, a new array will be allocated).
171       * @param data  the data buffer (<code>null</code> not permitted).
172       * 
173       * @return The pixel sample values.
174       * 
175       * @throws NullPointerException if <code>data</code> is <code>null</code>.
176       */
177      public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
178      {
179        if (iArray == null) 
180          iArray = new int[numBands];
181        for (int b = 0; b < numBands; b++) 
182          iArray[b] = getSample(x, y, b, data);
183        return iArray;
184      }
185      
186      /**
187       *
188       * This method is provided as a faster alternative to getPixel(),
189       * that can be used when there is no need to decode the pixel into
190       * separate sample values.
191       *
192       * @param obj An array to return the pixel data in. If null, an
193       * array of the right type and size will be created.
194       *
195       * @return A single pixel as an array object of a primitive type,
196       * based on the transfer type. Eg. if transfer type is
197       * DataBuffer.TYPE_USHORT, then a short[] object is returned.
198       */
199      public abstract Object getDataElements(int x, int y, Object obj,
200                                             DataBuffer data);
201    
202        
203      public Object getDataElements(int x, int y, int w, int h, Object obj,
204                                    DataBuffer data)
205      {
206        int size = w * h;
207        int numDataElements = getNumDataElements();
208        int dataSize = numDataElements * size;
209        
210        if (obj == null)
211          {
212            switch (getTransferType())
213              {
214              case DataBuffer.TYPE_BYTE:
215                obj = new byte[dataSize];
216                break;
217              case DataBuffer.TYPE_USHORT:
218                obj = new short[dataSize];
219                break;
220              case DataBuffer.TYPE_INT:
221                obj = new int[dataSize];
222                break;
223              default:
224                // Seems like the only sensible thing to do.
225                throw new ClassCastException();
226              }
227          }
228        Object pixelData = null;
229        int outOffset = 0;
230        for (int yy = y; yy < (y + h); yy++)
231          {
232            for (int xx = x; xx < (x + w); xx++)
233              {
234                pixelData = getDataElements(xx, yy, pixelData, data);
235                System.arraycopy(pixelData, 0, obj, outOffset,
236                                 numDataElements);
237                outOffset += numDataElements;
238              }
239          }
240        return obj;
241      }
242    
243      public abstract void setDataElements(int x, int y, Object obj,
244                                           DataBuffer data);
245    
246      public void setDataElements(int x, int y, int w, int h,
247                                  Object obj, DataBuffer data)
248      {
249        int numDataElements = getNumDataElements();
250        
251        Object pixelData;
252        switch (getTransferType())
253          {
254          case DataBuffer.TYPE_BYTE:
255            pixelData = new byte[numDataElements];
256            break;
257          case DataBuffer.TYPE_USHORT:
258          case DataBuffer.TYPE_SHORT:
259            pixelData = new short[numDataElements];
260            break;
261          case DataBuffer.TYPE_INT:
262            pixelData = new int[numDataElements];
263            break;
264          case DataBuffer.TYPE_FLOAT:
265            pixelData = new float[numDataElements];
266            break;
267          case DataBuffer.TYPE_DOUBLE:
268            pixelData = new double[numDataElements];
269            break;
270          default:
271            // The RI silently igores invalid types.
272            pixelData = null;
273          }
274    
275        int inOffset = 0;
276        if (pixelData != null)
277          {
278            for (int yy=y; yy<(y+h); yy++)
279              {
280                for (int xx=x; xx<(x+w); xx++)
281                  {
282                    System.arraycopy(obj, inOffset, pixelData, 0, numDataElements);
283                    setDataElements(xx, yy, pixelData, data);
284                    inOffset += numDataElements;
285                  }
286              }
287          }
288      }
289    
290      /**
291       * Returns an array containing the samples for the pixel at (x, y) in the
292       * specified data buffer.  If <code>fArray</code> is not <code>null</code>,
293       * it will be populated with the sample values and returned as the result of
294       * this function (this avoids allocating a new array instance).
295       * 
296       * @param x  the x-coordinate of the pixel.
297       * @param y  the y-coordinate of the pixel.
298       * @param fArray  an array to populate with the sample values and return as 
299       *     the result (if <code>null</code>, a new array will be allocated).
300       * @param data  the data buffer (<code>null</code> not permitted).
301       * 
302       * @return The pixel sample values.
303       * 
304       * @throws NullPointerException if <code>data</code> is <code>null</code>.
305       */
306      public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
307      {
308        if (fArray == null) 
309          fArray = new float[numBands];
310        
311        for (int b = 0; b < numBands; b++)
312          {
313            fArray[b] = getSampleFloat(x, y, b, data);
314          }
315        return fArray;
316      }
317    
318      /**
319       * Returns an array containing the samples for the pixel at (x, y) in the
320       * specified data buffer.  If <code>dArray</code> is not <code>null</code>,
321       * it will be populated with the sample values and returned as the result of
322       * this function (this avoids allocating a new array instance).
323       * 
324       * @param x  the x-coordinate of the pixel.
325       * @param y  the y-coordinate of the pixel.
326       * @param dArray  an array to populate with the sample values and return as 
327       *     the result (if <code>null</code>, a new array will be allocated).
328       * @param data  the data buffer (<code>null</code> not permitted).
329       * 
330       * @return The pixel sample values.
331       * 
332       * @throws NullPointerException if <code>data</code> is <code>null</code>.
333       */
334      public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
335        if (dArray == null) 
336          dArray = new double[numBands];
337        for (int b = 0; b < numBands; b++)
338          {
339            dArray[b] = getSampleDouble(x, y, b, data);
340          }
341        return dArray;
342      }
343    
344      /**
345       * Returns an array containing the samples for the pixels in the region 
346       * specified by (x, y, w, h) in the specified data buffer.  The array is
347       * ordered by pixels (that is, all the samples for the first pixel are 
348       * grouped together, followed by all the samples for the second pixel, and so
349       * on).  If <code>iArray</code> is not <code>null</code>, it will be 
350       * populated with the sample values and returned as the result of this 
351       * function (this avoids allocating a new array instance).
352       * 
353       * @param x  the x-coordinate of the top-left pixel.
354       * @param y  the y-coordinate of the top-left pixel.
355       * @param w  the width of the region of pixels.
356       * @param h  the height of the region of pixels.
357       * @param iArray  an array to populate with the sample values and return as 
358       *     the result (if <code>null</code>, a new array will be allocated).
359       * @param data  the data buffer (<code>null</code> not permitted).
360       * 
361       * @return The pixel sample values.
362       * 
363       * @throws NullPointerException if <code>data</code> is <code>null</code>.
364       */
365      public int[] getPixels(int x, int y, int w, int h, int[] iArray,
366                             DataBuffer data)
367      {
368        int size = w * h;
369        int outOffset = 0;
370        int[] pixel = null;
371        if (iArray == null) 
372          iArray = new int[w * h * numBands];
373        for (int yy = y; yy < (y + h); yy++)
374          {
375            for (int xx = x; xx < (x + w); xx++)
376              {
377                pixel = getPixel(xx, yy, pixel, data);
378                System.arraycopy(pixel, 0, iArray, outOffset, numBands);
379                outOffset += numBands;
380              }
381          }
382        return iArray;
383      }
384    
385      /**
386       * Returns an array containing the samples for the pixels in the region 
387       * specified by (x, y, w, h) in the specified data buffer.  The array is
388       * ordered by pixels (that is, all the samples for the first pixel are 
389       * grouped together, followed by all the samples for the second pixel, and so
390       * on).  If <code>fArray</code> is not <code>null</code>, it will be 
391       * populated with the sample values and returned as the result of this 
392       * function (this avoids allocating a new array instance).
393       * 
394       * @param x  the x-coordinate of the top-left pixel.
395       * @param y  the y-coordinate of the top-left pixel.
396       * @param w  the width of the region of pixels.
397       * @param h  the height of the region of pixels.
398       * @param fArray  an array to populate with the sample values and return as 
399       *     the result (if <code>null</code>, a new array will be allocated).
400       * @param data  the data buffer (<code>null</code> not permitted).
401       * 
402       * @return The pixel sample values.
403       * 
404       * @throws NullPointerException if <code>data</code> is <code>null</code>.
405       */
406      public float[] getPixels(int x, int y, int w, int h, float[] fArray,
407                               DataBuffer data)
408      {
409        int size = w * h;
410        int outOffset = 0;
411        float[] pixel = null;
412        if (fArray == null) fArray = new float[w * h * numBands];
413        for (int yy = y; yy < (y + h); yy++)
414          {
415            for (int xx = x; xx < (x + w); xx++)
416              {
417                pixel = getPixel(xx, yy, pixel, data);
418                System.arraycopy(pixel, 0, fArray, outOffset, numBands);
419                outOffset += numBands;
420              }
421          }
422        return fArray;
423      }
424        
425      /**
426       * Returns an array containing the samples for the pixels in the region 
427       * specified by (x, y, w, h) in the specified data buffer.  The array is
428       * ordered by pixels (that is, all the samples for the first pixel are 
429       * grouped together, followed by all the samples for the second pixel, and so
430       * on).  If <code>dArray</code> is not <code>null</code>, it will be 
431       * populated with the sample values and returned as the result of this 
432       * function (this avoids allocating a new array instance).
433       * 
434       * @param x  the x-coordinate of the top-left pixel.
435       * @param y  the y-coordinate of the top-left pixel.
436       * @param w  the width of the region of pixels.
437       * @param h  the height of the region of pixels.
438       * @param dArray  an array to populate with the sample values and return as 
439       *     the result (if <code>null</code>, a new array will be allocated).
440       * @param data  the data buffer (<code>null</code> not permitted).
441       * 
442       * @return The pixel sample values.
443       * 
444       * @throws NullPointerException if <code>data</code> is <code>null</code>.
445       */
446      public double[] getPixels(int x, int y, int w, int h, double[] dArray,
447                                DataBuffer data)
448      {
449        int size = w * h;
450        int outOffset = 0;
451        double[] pixel = null;
452        if (dArray == null) 
453          dArray = new double[w * h * numBands];
454        for (int yy = y; yy < (y + h); yy++)
455          {
456            for (int xx = x; xx < (x + w); xx++)
457              {
458                pixel = getPixel(xx, yy, pixel, data);
459                System.arraycopy(pixel, 0, dArray, outOffset, numBands);
460                outOffset += numBands;
461              }
462          }
463        return dArray;
464      }
465    
466      /**
467       * Returns the sample value for the pixel at (x, y) in the specified data 
468       * buffer.
469       * 
470       * @param x  the x-coordinate of the pixel.
471       * @param y  the y-coordinate of the pixel.
472       * @param b  the band (in the range <code>0</code> to 
473       *     <code>getNumBands() - 1</code>).
474       * @param data  the data buffer (<code>null</code> not permitted).
475       * 
476       * @return The sample value.
477       * 
478       * @throws NullPointerException if <code>data</code> is <code>null</code>.
479       */
480      public abstract int getSample(int x, int y, int b, DataBuffer data);
481    
482      /**
483       * Returns the sample value for the pixel at (x, y) in the specified data 
484       * buffer.
485       * 
486       * @param x  the x-coordinate of the pixel.
487       * @param y  the y-coordinate of the pixel.
488       * @param b  the band (in the range <code>0</code> to 
489       *     <code>getNumBands() - 1</code>).
490       * @param data  the data buffer (<code>null</code> not permitted).
491       * 
492       * @return The sample value.
493       * 
494       * @throws NullPointerException if <code>data</code> is <code>null</code>.
495       * 
496       * @see #getSample(int, int, int, DataBuffer)
497       */
498      public float getSampleFloat(int x, int y, int b, DataBuffer data)
499      {
500        return getSample(x, y, b, data);
501      }
502    
503      /**
504       * Returns the sample value for the pixel at (x, y) in the specified data 
505       * buffer.
506       * 
507       * @param x  the x-coordinate of the pixel.
508       * @param y  the y-coordinate of the pixel.
509       * @param b  the band (in the range <code>0</code> to 
510       *     <code>getNumBands() - 1</code>).
511       * @param data  the data buffer (<code>null</code> not permitted).
512       * 
513       * @return The sample value.
514       * 
515       * @throws NullPointerException if <code>data</code> is <code>null</code>.
516       * 
517       * @see #getSample(int, int, int, DataBuffer)
518       */
519      public double getSampleDouble(int x, int y, int b, DataBuffer data)
520      {
521        return getSampleFloat(x, y, b, data);
522      }
523    
524      /**
525       * Returns an array containing the samples from one band for the pixels in 
526       * the region specified by (x, y, w, h) in the specified data buffer.  If 
527       * <code>iArray</code> is not <code>null</code>, it will be 
528       * populated with the sample values and returned as the result of this 
529       * function (this avoids allocating a new array instance).
530       * 
531       * @param x  the x-coordinate of the top-left pixel.
532       * @param y  the y-coordinate of the top-left pixel.
533       * @param w  the width of the region of pixels.
534       * @param h  the height of the region of pixels.
535       * @param b  the band (in the range <code>0</code> to 
536       *     </code>getNumBands() - 1</code>).
537       * @param iArray  an array to populate with the sample values and return as 
538       *     the result (if <code>null</code>, a new array will be allocated).
539       * @param data  the data buffer (<code>null</code> not permitted).
540       * 
541       * @return The sample values.
542       * 
543       * @throws NullPointerException if <code>data</code> is <code>null</code>.
544       */
545      public int[] getSamples(int x, int y, int w, int h, int b,
546                              int[] iArray, DataBuffer data)
547      {
548        int size = w * h;
549        int outOffset = 0;
550        if (iArray == null) 
551          iArray = new int[size];
552        for (int yy = y; yy < (y + h); yy++)
553          {
554            for (int xx = x; xx < (x + w); xx++)
555              {
556                iArray[outOffset++] = getSample(xx, yy, b, data);
557              }
558          }
559        return iArray;
560      }
561    
562      /**
563       * Returns an array containing the samples from one band for the pixels in 
564       * the region specified by (x, y, w, h) in the specified data buffer.  If 
565       * <code>fArray</code> is not <code>null</code>, it will be 
566       * populated with the sample values and returned as the result of this 
567       * function (this avoids allocating a new array instance).
568       * 
569       * @param x  the x-coordinate of the top-left pixel.
570       * @param y  the y-coordinate of the top-left pixel.
571       * @param w  the width of the region of pixels.
572       * @param h  the height of the region of pixels.
573       * @param b  the band (in the range <code>0</code> to 
574       *     </code>getNumBands() - 1</code>).
575       * @param fArray  an array to populate with the sample values and return as 
576       *     the result (if <code>null</code>, a new array will be allocated).
577       * @param data  the data buffer (<code>null</code> not permitted).
578       * 
579       * @return The sample values.
580       * 
581       * @throws NullPointerException if <code>data</code> is <code>null</code>.
582       */
583      public float[] getSamples(int x, int y, int w, int h, int b,
584                                float[] fArray, DataBuffer data)
585      {
586        int size = w * h;
587        int outOffset = 0;
588        if (fArray == null) 
589          fArray = new float[size];
590        for (int yy = y; yy < (y + h); yy++)
591          {
592            for (int xx = x; xx < (x + w); xx++)
593              {
594                fArray[outOffset++] = getSampleFloat(xx, yy, b, data);
595              }
596          }
597        return fArray;
598      }
599    
600      /**
601       * Returns an array containing the samples from one band for the pixels in 
602       * the region specified by (x, y, w, h) in the specified data buffer.  If 
603       * <code>dArray</code> is not <code>null</code>, it will be 
604       * populated with the sample values and returned as the result of this 
605       * function (this avoids allocating a new array instance).
606       * 
607       * @param x  the x-coordinate of the top-left pixel.
608       * @param y  the y-coordinate of the top-left pixel.
609       * @param w  the width of the region of pixels.
610       * @param h  the height of the region of pixels.
611       * @param b  the band (in the range <code>0</code> to 
612       *     </code>getNumBands() - 1</code>).
613       * @param dArray  an array to populate with the sample values and return as 
614       *     the result (if <code>null</code>, a new array will be allocated).
615       * @param data  the data buffer (<code>null</code> not permitted).
616       * 
617       * @return The sample values.
618       * 
619       * @throws NullPointerException if <code>data</code> is <code>null</code>.
620       */
621      public double[] getSamples(int x, int y, int w, int h, int b,
622                                 double[] dArray, DataBuffer data)
623      {
624        int size = w * h;
625        int outOffset = 0;
626        if (dArray == null) 
627          dArray = new double[size];
628        for (int yy = y; yy < (y + h); yy++)
629          {
630            for (int xx = x; xx < (x + w); xx++)
631              {
632                dArray[outOffset++] = getSampleDouble(xx, yy, b, data);
633              }
634          }
635        return dArray;
636      }
637      
638      /**
639       * Sets the samples for the pixel at (x, y) in the specified data buffer to
640       * the specified values. 
641       * 
642       * @param x  the x-coordinate of the pixel.
643       * @param y  the y-coordinate of the pixel.
644       * @param iArray  the sample values (<code>null</code> not permitted).
645       * @param data  the data buffer (<code>null</code> not permitted).
646       * 
647       * @throws NullPointerException if either <code>iArray</code> or 
648       *     <code>data</code> is <code>null</code>.
649       */
650      public void setPixel(int x, int y, int[] iArray, DataBuffer data)
651      {
652        for (int b = 0; b < numBands; b++) 
653          setSample(x, y, b, iArray[b], data);
654      }
655    
656      /**
657       * Sets the samples for the pixel at (x, y) in the specified data buffer to
658       * the specified values. 
659       * 
660       * @param x  the x-coordinate of the pixel.
661       * @param y  the y-coordinate of the pixel.
662       * @param fArray  the sample values (<code>null</code> not permitted).
663       * @param data  the data buffer (<code>null</code> not permitted).
664       * 
665       * @throws NullPointerException if either <code>fArray</code> or 
666       *     <code>data</code> is <code>null</code>.
667       */
668      public void setPixel(int x, int y, float[] fArray, DataBuffer data)
669      {
670        for (int b = 0; b < numBands; b++) 
671          setSample(x, y, b, fArray[b], data);
672      }
673    
674      /**
675       * Sets the samples for the pixel at (x, y) in the specified data buffer to
676       * the specified values. 
677       * 
678       * @param x  the x-coordinate of the pixel.
679       * @param y  the y-coordinate of the pixel.
680       * @param dArray  the sample values (<code>null</code> not permitted).
681       * @param data  the data buffer (<code>null</code> not permitted).
682       * 
683       * @throws NullPointerException if either <code>dArray</code> or 
684       *     <code>data</code> is <code>null</code>.
685       */
686      public void setPixel(int x, int y, double[] dArray, DataBuffer data)
687      {
688        for (int b = 0; b < numBands; b++) 
689          setSample(x, y, b, dArray[b], data);
690      }
691    
692      /**
693       * Sets the sample values for the pixels in the region specified by 
694       * (x, y, w, h) in the specified data buffer.  The array is
695       * ordered by pixels (that is, all the samples for the first pixel are 
696       * grouped together, followed by all the samples for the second pixel, and so
697       * on). 
698       *  
699       * @param x  the x-coordinate of the top-left pixel.
700       * @param y  the y-coordinate of the top-left pixel.
701       * @param w  the width of the region of pixels.
702       * @param h  the height of the region of pixels.
703       * @param iArray  the pixel sample values (<code>null</code> not permitted).
704       * @param data  the data buffer (<code>null</code> not permitted).
705       * 
706       * @throws NullPointerException if either <code>iArray</code> or 
707       *     <code>data</code> is <code>null</code>.
708       */
709      public void setPixels(int x, int y, int w, int h, int[] iArray,
710                            DataBuffer data)
711      {
712        int inOffset = 0;
713        int[] pixel = new int[numBands];
714        for (int yy = y; yy < (y + h); yy++)
715          {
716            for (int xx = x; xx < (x + w); xx++)
717              {
718                System.arraycopy(iArray, inOffset, pixel, 0, numBands);
719                setPixel(xx, yy, pixel, data);
720                inOffset += numBands;
721              }
722          }
723      }
724    
725      /**
726       * Sets the sample values for the pixels in the region specified by 
727       * (x, y, w, h) in the specified data buffer.  The array is
728       * ordered by pixels (that is, all the samples for the first pixel are 
729       * grouped together, followed by all the samples for the second pixel, and so
730       * on). 
731       *  
732       * @param x  the x-coordinate of the top-left pixel.
733       * @param y  the y-coordinate of the top-left pixel.
734       * @param w  the width of the region of pixels.
735       * @param h  the height of the region of pixels.
736       * @param fArray  the pixel sample values (<code>null</code> not permitted).
737       * @param data  the data buffer (<code>null</code> not permitted).
738       * 
739       * @throws NullPointerException if either <code>fArray</code> or 
740       *     <code>data</code> is <code>null</code>.
741       */
742      public void setPixels(int x, int y, int w, int h, float[] fArray,
743                            DataBuffer data)
744      {
745        int inOffset = 0;
746        float[] pixel = new float[numBands];
747        for (int yy = y; yy < (y + h); yy++)
748          {
749            for (int xx = x; xx < (x + w); xx++)
750              {
751                System.arraycopy(fArray, inOffset, pixel, 0, numBands);
752                setPixel(xx, yy, pixel, data);
753                inOffset += numBands;
754              }
755          }
756      }
757    
758      /**
759       * Sets the sample values for the pixels in the region specified by 
760       * (x, y, w, h) in the specified data buffer.  The array is
761       * ordered by pixels (that is, all the samples for the first pixel are 
762       * grouped together, followed by all the samples for the second pixel, and so
763       * on). 
764       *  
765       * @param x  the x-coordinate of the top-left pixel.
766       * @param y  the y-coordinate of the top-left pixel.
767       * @param w  the width of the region of pixels.
768       * @param h  the height of the region of pixels.
769       * @param dArray  the pixel sample values (<code>null</code> not permitted).
770       * @param data  the data buffer (<code>null</code> not permitted).
771       * 
772       * @throws NullPointerException if either <code>dArray</code> or 
773       *     <code>data</code> is <code>null</code>.
774       */
775      public void setPixels(int x, int y, int w, int h, double[] dArray,
776                            DataBuffer data)
777      {
778        int inOffset = 0;
779        double[] pixel = new double[numBands];
780        for (int yy = y; yy < (y + h); yy++)
781          {
782            for (int xx = x; xx < (x + w); xx++)
783              {
784                System.arraycopy(dArray, inOffset, pixel, 0, numBands);
785                setPixel(xx, yy, pixel, data);
786                inOffset += numBands;
787              }
788          }
789      }
790    
791      /**
792       * Sets the sample value for a band for the pixel at (x, y) in the 
793       * specified data buffer. 
794       * 
795       * @param x  the x-coordinate of the pixel.
796       * @param y  the y-coordinate of the pixel.
797       * @param b  the band (in the range <code>0</code> to 
798       *     <code>getNumBands() - 1</code>).
799       * @param s  the sample value.
800       * @param data  the data buffer (<code>null</code> not permitted).
801       * 
802       * @throws NullPointerException if <code>data</code> is <code>null</code>.
803       */
804      public abstract void setSample(int x, int y, int b, int s,
805                                     DataBuffer data);
806    
807      /**
808       * Sets the sample value for a band for the pixel at (x, y) in the 
809       * specified data buffer. 
810       * 
811       * @param x  the x-coordinate of the pixel.
812       * @param y  the y-coordinate of the pixel.
813       * @param b  the band (in the range <code>0</code> to 
814       *     <code>getNumBands() - 1</code>).
815       * @param s  the sample value.
816       * @param data  the data buffer (<code>null</code> not permitted).
817       * 
818       * @throws NullPointerException if <code>data</code> is <code>null</code>.
819       */
820      public void setSample(int x, int y, int b, float s,
821                            DataBuffer data)
822      {
823        setSample(x, y, b, (int) s, data);
824      }
825    
826      /**
827       * Sets the sample value for a band for the pixel at (x, y) in the 
828       * specified data buffer. 
829       * 
830       * @param x  the x-coordinate of the pixel.
831       * @param y  the y-coordinate of the pixel.
832       * @param b  the band (in the range <code>0</code> to 
833       *     <code>getNumBands() - 1</code>).
834       * @param s  the sample value.
835       * @param data  the data buffer (<code>null</code> not permitted).
836       * 
837       * @throws NullPointerException if <code>data</code> is <code>null</code>.
838       */
839      public void setSample(int x, int y, int b, double s,
840                            DataBuffer data)
841      {
842        setSample(x, y, b, (float) s, data);
843      }
844    
845      /**
846       * Sets the sample values for one band for the pixels in the region 
847       * specified by (x, y, w, h) in the specified data buffer. 
848       * 
849       * @param x  the x-coordinate of the top-left pixel.
850       * @param y  the y-coordinate of the top-left pixel.
851       * @param w  the width of the region of pixels.
852       * @param h  the height of the region of pixels.
853       * @param b  the band (in the range <code>0</code> to 
854       *     </code>getNumBands() - 1</code>).
855       * @param iArray  the sample values (<code>null</code> not permitted).
856       * @param data  the data buffer (<code>null</code> not permitted).
857       * 
858       * @throws NullPointerException if either <code>iArray</code> or 
859       *     <code>data</code> is <code>null</code>.
860       */
861      public void setSamples(int x, int y, int w, int h, int b,
862                             int[] iArray, DataBuffer data)
863      {
864        int size = w * h;
865        int inOffset = 0;
866        for (int yy = y; yy < (y + h); yy++)
867          for (int xx = x; xx < (x + w); xx++)
868            setSample(xx, yy, b, iArray[inOffset++], data);
869      }
870    
871      /**
872       * Sets the sample values for one band for the pixels in the region 
873       * specified by (x, y, w, h) in the specified data buffer. 
874       * 
875       * @param x  the x-coordinate of the top-left pixel.
876       * @param y  the y-coordinate of the top-left pixel.
877       * @param w  the width of the region of pixels.
878       * @param h  the height of the region of pixels.
879       * @param b  the band (in the range <code>0</code> to 
880       *     </code>getNumBands() - 1</code>).
881       * @param fArray  the sample values (<code>null</code> not permitted).
882       * @param data  the data buffer (<code>null</code> not permitted).
883       * 
884       * @throws NullPointerException if either <code>iArray</code> or 
885       *     <code>data</code> is <code>null</code>.
886       */
887      public void setSamples(int x, int y, int w, int h, int b,
888                             float[] fArray, DataBuffer data)
889      {
890        int size = w * h;
891        int inOffset = 0;
892        for (int yy = y; yy < (y + h); yy++)
893          for (int xx = x; xx < (x + w); xx++)
894            setSample(xx, yy, b, fArray[inOffset++], data);
895    
896      }
897    
898      /**
899       * Sets the sample values for one band for the pixels in the region 
900       * specified by (x, y, w, h) in the specified data buffer. 
901       * 
902       * @param x  the x-coordinate of the top-left pixel.
903       * @param y  the y-coordinate of the top-left pixel.
904       * @param w  the width of the region of pixels.
905       * @param h  the height of the region of pixels.
906       * @param b  the band (in the range <code>0</code> to 
907       *     </code>getNumBands() - 1</code>).
908       * @param dArray  the sample values (<code>null</code> not permitted).
909       * @param data  the data buffer (<code>null</code> not permitted).
910       * 
911       * @throws NullPointerException if either <code>iArray</code> or 
912       *     <code>data</code> is <code>null</code>.
913       */
914      public void setSamples(int x, int y, int w, int h, int b,
915                             double[] dArray, DataBuffer data) {
916        int size = w * h;
917        int inOffset = 0;
918        for (int yy = y; yy < (y + h); yy++)
919          for (int xx = x; xx < (x + w); xx++)
920            setSample(xx, yy, b, dArray[inOffset++], data);
921      }
922    
923      /**
924       * Creates a new <code>SampleModel</code> that is compatible with this
925       * model and has the specified width and height.
926       * 
927       * @param w  the width (in pixels).
928       * @param h  the height (in pixels).
929       * 
930       * @return The new sample model.
931       */
932      public abstract SampleModel createCompatibleSampleModel(int w, int h);
933    
934      /**
935       * Return a SampleModel with a subset of the bands in this model.
936       * 
937       * Selects bands.length bands from this sample model.  The bands chosen
938       * are specified in the indices of bands[].  This also permits permuting
939       * the bands as well as taking a subset.  Thus, giving an array with
940       * 1, 2, 3, ..., numbands, will give an identical sample model.
941       * 
942       * @param bands Array with band indices to include.
943       * @return A new sample model
944       */
945      public abstract SampleModel createSubsetSampleModel(int[] bands);
946    
947      /**
948       * Creates a new {@link DataBuffer} of the correct type and size for this 
949       * <code>SampleModel</code>.
950       * 
951       * @return The data buffer.
952       */
953      public abstract DataBuffer createDataBuffer();
954    
955      /**
956       * Returns an array containing the size (in bits) for each band accessed by
957       * the <code>SampleModel</code>.
958       * 
959       * @return An array.
960       * 
961       * @see #getSampleSize(int)
962       */
963      public abstract int[] getSampleSize();
964    
965      /**
966       * Returns the size (in bits) of the samples for the specified band.
967       * 
968       * @param band  the band (in the range <code>0</code> to 
969       *     <code>getNumBands() - 1</code>).
970       *     
971       * @return The sample size (in bits).
972       */
973      public abstract int getSampleSize(int band);
974    }