/* Copyright (C) 2000, 2002, 2003, 2006,  Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.image;

import java.awt.Point;
import java.awt.Rectangle;

/**
 * A rectangular collection of pixels composed from a {@link DataBuffer} which
 * stores the pixel values, and a {@link SampleModel} which is used to retrieve
 * the pixel values.
 * 
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
 */
public class Raster
{
  /** The sample model used to access the pixel values. */
  protected SampleModel sampleModel;
  
  /** The data buffer used to store the pixel values. */
  protected DataBuffer dataBuffer;
  
  /** The x-coordinate of the top left corner of the raster. */
  protected int minX;
  
  /** The y-coordinate of the top left corner of the raster. */
  protected int minY;
  
  /** The width of the raster. */
  protected int width;
  
  /** The height of the raster. */
  protected int height;
  
  protected int sampleModelTranslateX;
  
  protected int sampleModelTranslateY;
  
  /** The number of bands. */
  protected int numBands;
  
  protected int numDataElements;
  
  /** The raster's parent. */
  protected Raster parent;
  
  /**
   * Creates a new raster.
   * 
   * @param sampleModel  the sample model.
   * @param origin  the origin.
   */
  protected Raster(SampleModel sampleModel, Point origin)
  {
    this(sampleModel, sampleModel.createDataBuffer(), origin);
  }
  
  /**
   * Creates a new raster.
   * 
   * @param sampleModel  the sample model.
   * @param dataBuffer  the data buffer.
   * @param origin  the origin.
   */
  protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
                   Point origin)
  {
    this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
         sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
  }

  /**
   * Creates a new raster.
   * 
   * @param sampleModel  the sample model.
   * @param dataBuffer  the data buffer.
   * @param aRegion  the raster's bounds.
   * @param sampleModelTranslate  the translation (<code>null</code> permitted).
   * @param parent  the raster's parent.
   */
  protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
      Rectangle aRegion, Point sampleModelTranslate, Raster parent)
  {
    this.sampleModel = sampleModel;
    this.dataBuffer = dataBuffer;
    this.minX = aRegion.x;
    this.minY = aRegion.y;
    this.width = aRegion.width;
    this.height = aRegion.height;
    
    // If sampleModelTranslate is null, use (0,0).  Methods such as
    // Raster.createRaster are specified to allow for a null argument.
    if (sampleModelTranslate != null)
    {
      this.sampleModelTranslateX = sampleModelTranslate.x;
      this.sampleModelTranslateY = sampleModelTranslate.y;
    }

    this.numBands = sampleModel.getNumBands();
    this.numDataElements = sampleModel.getNumDataElements();
    this.parent = parent;
  }
    
  /**
   * Creates an interleaved raster using the specified data type.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createInterleavedRaster(int dataType,
      int w, int h, int bands, Point location)
  {
    int[] bandOffsets = new int[bands];
    // TODO: Maybe not generate this every time.
    for (int b = 0; b < bands; b++) 
      bandOffsets[b] = b;
    
    int scanlineStride = bands * w;
    return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
                                   bandOffsets, location);
  }

  /**
   * Creates an interleaved raster.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param scanlineStride  the number of data elements from a sample on one 
   *     row to the corresponding sample on the next row.
   * @param pixelStride  the number of elements from a sample in one pixel to
   *     the corresponding sample in the next pixel.
   * @param bandOffsets  the band offsets.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createInterleavedRaster(int dataType, 
      int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
      Point location)
  {
    SampleModel sm = new ComponentSampleModel(dataType, w, h, pixelStride,
        scanlineStride, bandOffsets);
    return createWritableRaster(sm, location);
  }

  /**
   * Creates a new banded raster.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
   * @param location  
   * 
   * @return The new raster.
   */
  public static WritableRaster createBandedRaster(int dataType, int w, int h, 
      int bands, Point location)
  {
    SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
    return createWritableRaster(sm, location);
  }

  /**
   * Creates a new banded raster.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param scanlineStride  the number of data elements from a sample on one 
   *     row to the corresponding sample on the next row.
   * @param bankIndices  the index for each bank.
   * @param bandOffsets  the offset for each band.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createBandedRaster(int dataType, int w, int h,
      int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)
  {
    SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
                                           bankIndices, bandOffsets);
    return createWritableRaster(sm, location);
  }
  
  /**
   * Creates a new packed raster.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bandMasks  the bit mask for each band.
   * @param location 
   * 
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(int dataType, int w, int h,
      int[] bandMasks, Point location)
  {
    SampleModel sm = new SinglePixelPackedSampleModel(dataType, w, h,
                                                     bandMasks);
    return createWritableRaster(sm, location);
  }

  /**
   * Creates a new raster.
   * 
   * @param dataType  the data type.
   * @param w  the width.
   * @param h  the height.
   * @param bands  the number of bands.
   * @param bitsPerBand  the number of bits per band.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(int dataType,
      int w, int h, int bands, int bitsPerBand, Point location)
  {
    if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
      throw new IllegalArgumentException();

    SampleModel sm;

    if (bands == 1)
      sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
    else
      {
        int[] bandMasks = new int[bands];
        int mask = 0x1;
        for (int bits = bitsPerBand; --bits != 0;)
          mask = (mask << 1) | 0x1;
        for (int i = 0; i < bands; i++)
          {
            bandMasks[i] = mask;
            mask <<= bitsPerBand;
          }
          
        sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
      }
    return createWritableRaster(sm, location);
  }

  /**
   * Creates a new interleaved raster.
   * 
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
   * @param scanlineStride  the number of data elements from a sample on one 
   *     row to the corresponding sample on the next row.
   * @param pixelStride  the number of elements from a sample in one pixel to
   *     the corresponding sample in the next pixel.
   * @param bandOffsets  the offset for each band.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer, 
      int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets, 
      Point location)
  {
    SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
        w, h, scanlineStride, pixelStride, bandOffsets);
    return createWritableRaster(sm, dataBuffer, location);
  }

  /**
   * Creates a new banded raster.
   * 
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
   * @param scanlineStride  the number of data elements from a sample on one 
   *     row to the corresponding sample on the next row.
   * @param bankIndices  the index for each bank.
   * @param bandOffsets  the band offsets.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
      int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets,
      Point location)
  {
    SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
        w, h, scanlineStride, bankIndices, bandOffsets);
    return createWritableRaster(sm, dataBuffer, location);
  }
  
  /**
   * Creates a new packed raster.
   * 
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
   * @param scanlineStride  the number of data elements from a sample on one 
   *     row to the corresponding sample on the next row.
   * @param bandMasks  the bit mask for each band.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
      int w, int h, int scanlineStride, int[] bandMasks, Point location)
 {
    SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
        w, h, scanlineStride, bandMasks);
    return createWritableRaster(sm, dataBuffer, location);
  }
  
  /**
   * Creates a new packed raster.
   * 
   * @param dataBuffer  the data buffer.
   * @param w  the width.
   * @param h  the height.
   * @param bitsPerPixel  the number of bits per pixel.
   * @param location
   * 
   * @return The new raster.
   */
  public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
      int w, int h, int bitsPerPixel, Point location)
  {
    SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
        w, h, bitsPerPixel);
    return createWritableRaster(sm, dataBuffer, location);
  }
    
  /**
   * Creates a new raster.
   * 
   * @param sm  the sample model.
   * @param db  the data buffer.
   * @param location
   * 
   * @return The new raster.
   */
  public static Raster createRaster(SampleModel sm, DataBuffer db,
                                    Point location)
  {
    return new Raster(sm, db, location);
  }

  /**
   * Creates a new writable raster.
   * 
   * @param sm  the sample model.
   * @param location
   * 
   * @return The new writable raster.
   */
  public static WritableRaster createWritableRaster(SampleModel sm,
                                                    Point location)
  {
    return new WritableRaster(sm, location);
  }

  /**
   * Creates a new writable raster.
   * 
   * @param sm  the sample model.
   * @param db  the data buffer.
   * @param location 
   * 
   * @return The new writable raster.
   */
  public static WritableRaster createWritableRaster(SampleModel sm,
      DataBuffer db, Point location)
  {
    return new WritableRaster(sm, db, location);
  }

  /**
   * Returns the raster's parent.
   * 
   * @return The raster's parent.
   */
  public Raster getParent()
  {
    return parent;
  }

  /**
   * Returns the x-translation.
   * 
   * @return The x-translation.
   */
  public final int getSampleModelTranslateX()
  {
    return sampleModelTranslateX;
  }

  /**
   * Returns the y-translation.
   * 
   * @return The y-translation.
   */
  public final int getSampleModelTranslateY()
  {
    return sampleModelTranslateY;
  }

  /**
   * Creates a new writable raster that is compatible with this raster.
   * 
   * @return A new writable raster.
   */
  public WritableRaster createCompatibleWritableRaster()
  {
    return new WritableRaster(getSampleModel(), new Point(minX, minY));
  }

  /**
   * Creates a new writable raster that is compatible with this raster.
   * 
   * @param w  the width.
   * @param h  the height.
   * 
   * @return A new writable raster.
   */
  public WritableRaster createCompatibleWritableRaster(int w, int h)
  {
    return createCompatibleWritableRaster(minX, minY, w, h);
  }

  /**
   * Creates a new writable raster that is compatible with this raster, with
   * the specified bounds.
   * 
   * @param rect  the raster bounds.
   * 
   * @return A new writable raster.
   */
  public WritableRaster createCompatibleWritableRaster(Rectangle rect)
  {
    return createCompatibleWritableRaster(rect.x, rect.y,
                                          rect.width, rect.height);
  }

  /**
   * Creates a new writable raster that is compatible with this raster, with
   * the specified bounds.
   * 
   * @param x  the x-coordinate of the top-left corner of the raster.
   * @param y  the y-coordinate of the top-left corner of the raster.
   * @param w  the raster width.
   * @param h  the raster height.
   * 
   * @return A new writable raster.
   */
  public WritableRaster createCompatibleWritableRaster(int x, int y,
                                                       int w, int h)
  {
    SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
    return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y));
  }

  public Raster createTranslatedChild(int childMinX, int childMinY) {
    int tcx = sampleModelTranslateX - minX + childMinX;
    int tcy = sampleModelTranslateY - minY + childMinY;
    
    return new Raster(sampleModel, dataBuffer,
                      new Rectangle(childMinX, childMinY, width, height),
                      new Point(tcx, tcy), this);
  }

  public Raster createChild(int parentX, int parentY, int width,
                            int height, int childMinX, int childMinY,
                            int[] bandList)
  {
    /* FIXME: Throw RasterFormatException if child bounds extends
       beyond the bounds of this raster. */

    SampleModel sm = (bandList == null) ?
      sampleModel :
      sampleModel.createSubsetSampleModel(bandList);

    /*
        data origin
       /
      +-------------------------
      |\. __ parent trans
      | \`.  
      |  \ `.    parent origin
      |   \  `. /
      |   /\   +-------- - -
      |trans\ /<\-- deltaTrans
      |child +-+-\---- - - 
      |     /|`|  \__ parent [x, y]
      |child | |`. \
      |origin| :  `.\
      |      |    / `\
      |      :   /    +
      | child [x, y] 

      parent_xy - parent_trans = child_xy - child_trans

      child_trans = parent_trans + child_xy - parent_xy
    */

    return new Raster(sm, dataBuffer,
        new Rectangle(childMinX, childMinY, width, height),
        new Point(sampleModelTranslateX + childMinX - parentX,
                  sampleModelTranslateY + childMinY - parentY),
        this);
  }

  /**
   * Returns a new rectangle containing the bounds of this raster.
   * 
   * @return A new rectangle containing the bounds of this raster.
   */
  public Rectangle getBounds()
  {
    return new Rectangle(minX, minY, width, height);
  }

  /**
   * Returns the x-coordinate of the top left corner of the raster.
   * 
   * @return The x-coordinate of the top left corner of the raster.
   */
  public final int getMinX()
  {
    return minX;
  }

  /**
   * Returns the t-coordinate of the top left corner of the raster.
   * 
   * @return The t-coordinate of the top left corner of the raster.
   */
  public final int getMinY()
  {
    return minY;
  }

  /**
   * Returns the width of the raster.
   * 
   * @return The width of the raster.
   */
  public final int getWidth()
  {
    return width;
  }

  /**
   * Returns the height of the raster.
   * 
   * @return The height of the raster.
   */
  public final int getHeight()
  {
    return height;
  }

  /**
   * Returns the number of bands for this raster.
   * 
   * @return The number of bands.
   */
  public final int getNumBands()
  {
    return numBands;
  }
    
  public final int getNumDataElements()
  {
    return numDataElements;
  }
  
  /**
   * Returns the transfer type for the raster (this is determined by the 
   * raster's sample model).
   * 
   * @return The transfer type.
   */
  public final int getTransferType()
  {
    return sampleModel.getTransferType();
  }

  /**
   * Returns the data buffer that stores the pixel data for this raster.
   * 
   * @return The data buffer.
   */
  public DataBuffer getDataBuffer()
  {
    return dataBuffer;
  }

  /**
   * Returns the sample model that accesses the data buffer (to extract pixel
   * data) for this raster.
   * 
   * @return The sample model.
   */
  public SampleModel getSampleModel()
  {
    return sampleModel;
  }

  public Object getDataElements(int x, int y, Object outData)
  {
    return sampleModel.getDataElements(x - sampleModelTranslateX,
        y - sampleModelTranslateY, outData, dataBuffer);
  }

  public Object getDataElements(int x, int y, int w, int h, Object outData)
  {
    return sampleModel.getDataElements(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, outData, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
   * raster.  If <code>iArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param iArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public int[] getPixel(int x, int y, int[] iArray)
  {
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, iArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
   * raster.  If <code>fArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param fArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public float[] getPixel(int x, int y, float[] fArray)
  {
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, fArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixel at (x, y) in the
   * raster.  If <code>dArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of
   * this function (this avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param dArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public double[] getPixel(int x, int y, double[] dArray)
  {
    return sampleModel.getPixel(x - sampleModelTranslateX,
        y - sampleModelTranslateY, dArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixels in the region 
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
   * (that is, all the samples for the first pixel are grouped together, 
   * followed by all the samples for the second pixel, and so on).  
   * If <code>iArray</code> is not <code>null</code>, it will be populated 
   * with the sample values and returned as the result of this function (this 
   * avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param iArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public int[] getPixels(int x, int y, int w, int h, int[] iArray)
  {
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, iArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixels in the region 
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
   * (that is, all the samples for the first pixel are grouped together, 
   * followed by all the samples for the second pixel, and so on).  
   * If <code>fArray</code> is not <code>null</code>, it will be populated 
   * with the sample values and returned as the result of this function (this 
   * avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param fArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public float[] getPixels(int x, int y, int w, int h, float[] fArray)
  {
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, fArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples for the pixels in the region 
   * specified by (x, y, w, h) in the raster.  The array is ordered by pixels 
   * (that is, all the samples for the first pixel are grouped together, 
   * followed by all the samples for the second pixel, and so on).  
   * If <code>dArray</code> is not <code>null</code>, it will be populated 
   * with the sample values and returned as the result of this function (this 
   * avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param dArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The pixel sample values.
   */
  public double[] getPixels(int x, int y, int w, int h, double[] dArray)
  {
    return sampleModel.getPixels(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, dArray, dataBuffer);
  }

  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param b  the band (in the range <code>0</code> to 
   *     <code>getNumBands() - 1</code>).
   * 
   * @return The sample value.
   */
  public int getSample(int x, int y, int b)
  {
    return sampleModel.getSample(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
  }

  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param b  the band (in the range <code>0</code> to 
   *     <code>getNumBands() - 1</code>).
   * 
   * @return The sample value.
   * 
   * @see #getSample(int, int, int)
   */
  public float getSampleFloat(int x, int y, int b)
  {
    return sampleModel.getSampleFloat(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
  }

  /**
   * Returns the sample value for the pixel at (x, y) in the raster.
   * 
   * @param x  the x-coordinate of the pixel.
   * @param y  the y-coordinate of the pixel.
   * @param b  the band (in the range <code>0</code> to 
   *     <code>getNumBands() - 1</code>).
   * 
   * @return The sample value.
   * 
   * @see #getSample(int, int, int)
   */
  public double getSampleDouble(int x, int y, int b)
  {
    return sampleModel.getSampleDouble(x - sampleModelTranslateX,
        y - sampleModelTranslateY, b, dataBuffer);
  }

  /**
   * Returns an array containing the samples from one band for the pixels in 
   * the region specified by (x, y, w, h) in the raster.  If 
   * <code>iArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of this 
   * function (this avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param b  the band (in the range <code>0</code> to 
   *     </code>getNumBands() - 1</code>).
   * @param iArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The sample values.
   */
  public int[] getSamples(int x, int y, int w, int h, int b,
                          int[] iArray)
  {
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples from one band for the pixels in 
   * the region specified by (x, y, w, h) in the raster.  If 
   * <code>fArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of this 
   * function (this avoids allocating a new array instance).
   *
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param b  the band (in the range <code>0</code> to 
   *     </code>getNumBands() - 1</code>).
   * @param fArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The sample values.
   */  
  public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray)
  {
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
  }

  /**
   * Returns an array containing the samples from one band for the pixels in 
   * the region specified by (x, y, w, h) in the raster.  If 
   * <code>dArray</code> is not <code>null</code>, it will be 
   * populated with the sample values and returned as the result of this 
   * function (this avoids allocating a new array instance).
   * 
   * @param x  the x-coordinate of the top-left pixel.
   * @param y  the y-coordinate of the top-left pixel.
   * @param w  the width of the region of pixels.
   * @param h  the height of the region of pixels.
   * @param b  the band (in the range <code>0</code> to 
   *     </code>getNumBands() - 1</code>).
   * @param dArray  an array to populate with the sample values and return as 
   *     the result (if <code>null</code>, a new array will be allocated).
   * 
   * @return The sample values.
   */
  public double[] getSamples(int x, int y, int w, int h, int b, 
                             double[] dArray)
  {
    return sampleModel.getSamples(x - sampleModelTranslateX,
        y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
  }
  
  /**
   * Create a String representing the state of this Raster.
   * 
   * @return A String representing the stat of this Raster.
   */
  public String toString()
  {
    StringBuffer result = new StringBuffer();
    
    result.append(getClass().getName());
    result.append("[(");
    result.append(minX).append(",").append(minY).append("), ");
    result.append(width).append(" x ").append(height).append(",");
    result.append(sampleModel).append(",");
    result.append(dataBuffer);
    result.append("]");
    
    return result.toString();
  }

  /**
   * Returns the number of bits used to represent the specified data type.  
   * Valid types are:
   * <ul>
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
   *   <li>{@link DataBuffer#TYPE_SHORT};</li>
   *   <li>{@link DataBuffer#TYPE_INT};</li>
   *   <li>{@link DataBuffer#TYPE_FLOAT};</li>
   *   <li>{@link DataBuffer#TYPE_DOUBLE};</li>
   * </ul>
   * This method returns 0 for invalid data types.
   * 
   * @param dataType  the data type.
   * 
   * @return The number of bits used to represent the specified data type.
   */
  private static int getTypeBits(int dataType)
  {
    switch (dataType)
      {
      case DataBuffer.TYPE_BYTE:
        return 8;
      case DataBuffer.TYPE_USHORT:
      case DataBuffer.TYPE_SHORT:
        return 16;
      case DataBuffer.TYPE_INT:
      case DataBuffer.TYPE_FLOAT:
        return 32;
      case DataBuffer.TYPE_DOUBLE:
        return 64;
      default:
        return 0;
      }
  }
}
