001/* Copyright (C) 2000, 2001, 2002, 2005, 2006,  Free Software Foundation
002
003This file is part of GNU Classpath.
004
005GNU Classpath is free software; you can redistribute it and/or modify
006it under the terms of the GNU General Public License as published by
007the Free Software Foundation; either version 2, or (at your option)
008any later version.
009
010GNU Classpath is distributed in the hope that it will be useful, but
011WITHOUT ANY WARRANTY; without even the implied warranty of
012MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013General Public License for more details.
014
015You should have received a copy of the GNU General Public License
016along with GNU Classpath; see the file COPYING.  If not, write to the
017Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01802110-1301 USA.
019
020Linking this library statically or dynamically with other modules is
021making a combined work based on this library.  Thus, the terms and
022conditions of the GNU General Public License cover the whole
023combination.
024
025As a special exception, the copyright holders of this library give you
026permission to link this library with independent modules to produce an
027executable, regardless of the license terms of these independent
028modules, and to copy and distribute the resulting executable under
029terms of your choice, provided that you also meet, for each linked
030independent module, the terms and conditions of the license of that
031module.  An independent module is a module which is not derived from
032or based on this library.  If you modify this library, you may extend
033this exception to your version of the library, but you are not
034obligated to do so.  If you do not wish to do so, delete this
035exception statement from your version. */
036
037package 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 */
045public 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}