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