jdk/src/share/classes/java/awt/image/Raster.java
changeset 539 7952521a4ad3
child 715 f16baef3a20e
equal deleted inserted replaced
538:d95bc71a5732 539:7952521a4ad3
       
     1 /*
       
     2  * Portions Copyright 1997-2007 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any 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 
       
    37 package java.awt.image;
       
    38 import java.awt.Rectangle;
       
    39 import java.awt.Point;
       
    40 
       
    41 import sun.awt.image.ByteInterleavedRaster;
       
    42 import sun.awt.image.ShortInterleavedRaster;
       
    43 import sun.awt.image.IntegerInterleavedRaster;
       
    44 import sun.awt.image.ByteBandedRaster;
       
    45 import sun.awt.image.ShortBandedRaster;
       
    46 import sun.awt.image.BytePackedRaster;
       
    47 import sun.awt.image.SunWritableRaster;
       
    48 
       
    49 /**
       
    50  * A class representing a rectangular array of pixels.  A Raster
       
    51  * encapsulates a DataBuffer that stores the sample values and a
       
    52  * SampleModel that describes how to locate a given sample value in a
       
    53  * DataBuffer.
       
    54  * <p>
       
    55  * A Raster defines values for pixels occupying a particular
       
    56  * rectangular area of the plane, not necessarily including (0, 0).
       
    57  * The rectangle, known as the Raster's bounding rectangle and
       
    58  * available by means of the getBounds method, is defined by minX,
       
    59  * minY, width, and height values.  The minX and minY values define
       
    60  * the coordinate of the upper left corner of the Raster.  References
       
    61  * to pixels outside of the bounding rectangle may result in an
       
    62  * exception being thrown, or may result in references to unintended
       
    63  * elements of the Raster's associated DataBuffer.  It is the user's
       
    64  * responsibility to avoid accessing such pixels.
       
    65  * <p>
       
    66  * A SampleModel describes how samples of a Raster
       
    67  * are stored in the primitive array elements of a DataBuffer.
       
    68  * Samples may be stored one per data element, as in a
       
    69  * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
       
    70  * an element, as in a SinglePixelPackedSampleModel or
       
    71  * MultiPixelPackedSampleModel.  The SampleModel is also
       
    72  * controls whether samples are sign extended, allowing unsigned
       
    73  * data to be stored in signed Java data types such as byte, short, and
       
    74  * int.
       
    75  * <p>
       
    76  * Although a Raster may live anywhere in the plane, a SampleModel
       
    77  * makes use of a simple coordinate system that starts at (0, 0).  A
       
    78  * Raster therefore contains a translation factor that allows pixel
       
    79  * locations to be mapped between the Raster's coordinate system and
       
    80  * that of the SampleModel.  The translation from the SampleModel
       
    81  * coordinate system to that of the Raster may be obtained by the
       
    82  * getSampleModelTranslateX and getSampleModelTranslateY methods.
       
    83  * <p>
       
    84  * A Raster may share a DataBuffer with another Raster either by
       
    85  * explicit construction or by the use of the createChild and
       
    86  * createTranslatedChild methods.  Rasters created by these methods
       
    87  * can return a reference to the Raster they were created from by
       
    88  * means of the getParent method.  For a Raster that was not
       
    89  * constructed by means of a call to createTranslatedChild or
       
    90  * createChild, getParent will return null.
       
    91  * <p>
       
    92  * The createTranslatedChild method returns a new Raster that
       
    93  * shares all of the data of the current Raster, but occupies a
       
    94  * bounding rectangle of the same width and height but with a
       
    95  * different starting point.  For example, if the parent Raster
       
    96  * occupied the region (10, 10) to (100, 100), and the translated
       
    97  * Raster was defined to start at (50, 50), then pixel (20, 20) of the
       
    98  * parent and pixel (60, 60) of the child occupy the same location in
       
    99  * the DataBuffer shared by the two Rasters.  In the first case, (-10,
       
   100  * -10) should be added to a pixel coordinate to obtain the
       
   101  * corresponding SampleModel coordinate, and in the second case (-50,
       
   102  * -50) should be added.
       
   103  * <p>
       
   104  * The translation between a parent and child Raster may be
       
   105  * determined by subtracting the child's sampleModelTranslateX and
       
   106  * sampleModelTranslateY values from those of the parent.
       
   107  * <p>
       
   108  * The createChild method may be used to create a new Raster
       
   109  * occupying only a subset of its parent's bounding rectangle
       
   110  * (with the same or a translated coordinate system) or
       
   111  * with a subset of the bands of its parent.
       
   112  * <p>
       
   113  * All constructors are protected.  The correct way to create a
       
   114  * Raster is to use one of the static create methods defined in this
       
   115  * class.  These methods create instances of Raster that use the
       
   116  * standard Interleaved, Banded, and Packed SampleModels and that may
       
   117  * be processed more efficiently than a Raster created by combining
       
   118  * an externally generated SampleModel and DataBuffer.
       
   119  * @see java.awt.image.DataBuffer
       
   120  * @see java.awt.image.SampleModel
       
   121  * @see java.awt.image.PixelInterleavedSampleModel
       
   122  * @see java.awt.image.BandedSampleModel
       
   123  * @see java.awt.image.SinglePixelPackedSampleModel
       
   124  * @see java.awt.image.MultiPixelPackedSampleModel
       
   125  */
       
   126 public class Raster {
       
   127 
       
   128     /**
       
   129      * The SampleModel that describes how pixels from this Raster
       
   130      * are stored in the DataBuffer.
       
   131      */
       
   132     protected SampleModel sampleModel;
       
   133 
       
   134     /** The DataBuffer that stores the image data. */
       
   135     protected DataBuffer dataBuffer;
       
   136 
       
   137     /** The X coordinate of the upper-left pixel of this Raster. */
       
   138     protected int minX;
       
   139 
       
   140     /** The Y coordinate of the upper-left pixel of this Raster. */
       
   141     protected int minY;
       
   142 
       
   143     /** The width of this Raster. */
       
   144     protected int width;
       
   145 
       
   146     /** The height of this Raster. */
       
   147     protected int height;
       
   148 
       
   149     /**
       
   150      * The X translation from the coordinate space of the
       
   151      * Raster's SampleModel to that of the Raster.
       
   152      */
       
   153     protected int sampleModelTranslateX;
       
   154 
       
   155     /**
       
   156      * The Y translation from the coordinate space of the
       
   157      * Raster's SampleModel to that of the Raster.
       
   158      */
       
   159     protected int sampleModelTranslateY;
       
   160 
       
   161     /** The number of bands in the Raster. */
       
   162     protected int numBands;
       
   163 
       
   164     /** The number of DataBuffer data elements per pixel. */
       
   165     protected int numDataElements;
       
   166 
       
   167     /** The parent of this Raster, or null. */
       
   168     protected Raster parent;
       
   169 
       
   170     static private native void initIDs();
       
   171     static {
       
   172         ColorModel.loadLibraries();
       
   173         initIDs();
       
   174     }
       
   175 
       
   176     /**
       
   177      * Creates a Raster based on a PixelInterleavedSampleModel with the
       
   178      * specified data type, width, height, and number of bands.
       
   179      *
       
   180      * <p> The upper left corner of the Raster is given by the
       
   181      * location argument.  If location is null, (0, 0) will be used.
       
   182      * The dataType parameter should be one of the enumerated values
       
   183      * defined in the DataBuffer class.
       
   184      *
       
   185      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
       
   186      * Rasters are not supported.  To create a 1-band Raster of type
       
   187      * <code>DataBuffer.TYPE_INT</code>, use
       
   188      * Raster.createPackedRaster().
       
   189      * <p> The only dataTypes supported currently are TYPE_BYTE
       
   190      * and TYPE_USHORT.
       
   191      * @param dataType  the data type for storing samples
       
   192      * @param w         the width in pixels of the image data
       
   193      * @param h         the height in pixels of the image data
       
   194      * @param bands     the number of bands
       
   195      * @param location  the upper-left corner of the <code>Raster</code>
       
   196      * @return a WritableRaster object with the specified data type,
       
   197      *         width, height and number of bands.
       
   198      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   199      *         is less than or equal to zero, or computing either
       
   200      *         <code>location.x + w</code> or
       
   201      *         <code>location.y + h</code> results in integer
       
   202      *         overflow
       
   203      */
       
   204     public static WritableRaster createInterleavedRaster(int dataType,
       
   205                                                          int w, int h,
       
   206                                                          int bands,
       
   207                                                          Point location) {
       
   208         int[] bandOffsets = new int[bands];
       
   209         for (int i = 0; i < bands; i++) {
       
   210             bandOffsets[i] = i;
       
   211         }
       
   212         return createInterleavedRaster(dataType, w, h, w*bands, bands,
       
   213                                        bandOffsets, location);
       
   214     }
       
   215 
       
   216     /**
       
   217      * Creates a Raster based on a PixelInterleavedSampleModel with the
       
   218      * specified data type, width, height, scanline stride, pixel
       
   219      * stride, and band offsets.  The number of bands is inferred from
       
   220      * bandOffsets.length.
       
   221      *
       
   222      * <p> The upper left corner of the Raster is given by the
       
   223      * location argument.  If location is null, (0, 0) will be used.
       
   224      * The dataType parameter should be one of the enumerated values
       
   225      * defined in the DataBuffer class.
       
   226      *
       
   227      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
       
   228      * Rasters are not supported.  To create a 1-band Raster of type
       
   229      * <code>DataBuffer.TYPE_INT</code>, use
       
   230      * Raster.createPackedRaster().
       
   231      * <p> The only dataTypes supported currently are TYPE_BYTE
       
   232      * and TYPE_USHORT.
       
   233      * @param dataType  the data type for storing samples
       
   234      * @param w         the width in pixels of the image data
       
   235      * @param h         the height in pixels of the image data
       
   236      * @param scanlineStride the line stride of the image data
       
   237      * @param pixelStride the pixel stride of the image data
       
   238      * @param bandOffsets the offsets of all bands
       
   239      * @param location  the upper-left corner of the <code>Raster</code>
       
   240      * @return a WritableRaster object with the specified data type,
       
   241      *         width, height, scanline stride, pixel stride and band
       
   242      *         offsets.
       
   243      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   244      *         is less than or equal to zero, or computing either
       
   245      *         <code>location.x + w</code> or
       
   246      *         <code>location.y + h</code> results in integer
       
   247      *         overflow
       
   248      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   249      *         one of the supported data types, which are
       
   250      *         <code>DataBuffer.TYPE_BYTE</code>, or
       
   251      *         <code>DataBuffer.TYPE_USHORT</code>.
       
   252      */
       
   253     public static WritableRaster createInterleavedRaster(int dataType,
       
   254                                                          int w, int h,
       
   255                                                          int scanlineStride,
       
   256                                                          int pixelStride,
       
   257                                                          int bandOffsets[],
       
   258                                                          Point location) {
       
   259         DataBuffer d;
       
   260         int bands = bandOffsets.length;
       
   261 
       
   262         int maxBandOff = bandOffsets[0];
       
   263         for (int i=1; i < bands; i++) {
       
   264             if (bandOffsets[i] > maxBandOff) {
       
   265                 maxBandOff = bandOffsets[i];
       
   266             }
       
   267         }
       
   268         int size = maxBandOff + scanlineStride*(h-1) + pixelStride*(w-1) + 1;
       
   269         switch(dataType) {
       
   270         case DataBuffer.TYPE_BYTE:
       
   271             d = new DataBufferByte(size);
       
   272             break;
       
   273 
       
   274         case DataBuffer.TYPE_USHORT:
       
   275             d = new DataBufferUShort(size);
       
   276             break;
       
   277 
       
   278         default:
       
   279             throw new IllegalArgumentException("Unsupported data type " +
       
   280                                                 dataType);
       
   281         }
       
   282 
       
   283         return createInterleavedRaster(d, w, h, scanlineStride,
       
   284                                        pixelStride, bandOffsets, location);
       
   285     }
       
   286 
       
   287     /**
       
   288      * Creates a Raster based on a BandedSampleModel with the
       
   289      * specified data type, width, height, and number of bands.
       
   290      *
       
   291      * <p> The upper left corner of the Raster is given by the
       
   292      * location argument.  If location is null, (0, 0) will be used.
       
   293      * The dataType parameter should be one of the enumerated values
       
   294      * defined in the DataBuffer class.
       
   295      *
       
   296      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
       
   297      * and TYPE_INT.
       
   298      * @param dataType  the data type for storing samples
       
   299      * @param w         the width in pixels of the image data
       
   300      * @param h         the height in pixels of the image data
       
   301      * @param bands     the number of bands
       
   302      * @param location  the upper-left corner of the <code>Raster</code>
       
   303      * @return a WritableRaster object with the specified data type,
       
   304      *         width, height and number of bands.
       
   305      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   306      *         is less than or equal to zero, or computing either
       
   307      *         <code>location.x + w</code> or
       
   308      *         <code>location.y + h</code> results in integer
       
   309      *         overflow
       
   310      * @throws ArrayIndexOutOfBoundsException if <code>bands</code>
       
   311      *         is less than 1
       
   312      */
       
   313     public static WritableRaster createBandedRaster(int dataType,
       
   314                                                     int w, int h,
       
   315                                                     int bands,
       
   316                                                     Point location) {
       
   317         if (bands < 1) {
       
   318             throw new ArrayIndexOutOfBoundsException("Number of bands ("+
       
   319                                                      bands+") must"+
       
   320                                                      " be greater than 0");
       
   321         }
       
   322         int[] bankIndices = new int[bands];
       
   323         int[] bandOffsets = new int[bands];
       
   324         for (int i = 0; i < bands; i++) {
       
   325             bankIndices[i] = i;
       
   326             bandOffsets[i] = 0;
       
   327         }
       
   328 
       
   329         return createBandedRaster(dataType, w, h, w,
       
   330                                   bankIndices, bandOffsets,
       
   331                                   location);
       
   332     }
       
   333 
       
   334     /**
       
   335      * Creates a Raster based on a BandedSampleModel with the
       
   336      * specified data type, width, height, scanline stride, bank
       
   337      * indices and band offsets.  The number of bands is inferred from
       
   338      * bankIndices.length and bandOffsets.length, which must be the
       
   339      * same.
       
   340      *
       
   341      * <p> The upper left corner of the Raster is given by the
       
   342      * location argument.  The dataType parameter should be one of the
       
   343      * enumerated values defined in the DataBuffer class.
       
   344      *
       
   345      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
       
   346      * and TYPE_INT.
       
   347      * @param dataType  the data type for storing samples
       
   348      * @param w         the width in pixels of the image data
       
   349      * @param h         the height in pixels of the image data
       
   350      * @param scanlineStride the line stride of the image data
       
   351      * @param bankIndices the bank indices for each band
       
   352      * @param bandOffsets the offsets of all bands
       
   353      * @param location  the upper-left corner of the <code>Raster</code>
       
   354      * @return a WritableRaster object with the specified data type,
       
   355      *         width, height, scanline stride, bank indices and band
       
   356      *         offsets.
       
   357      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   358      *         is less than or equal to zero, or computing either
       
   359      *         <code>location.x + w</code> or
       
   360      *         <code>location.y + h</code> results in integer
       
   361      *         overflow
       
   362      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   363      *         one of the supported data types, which are
       
   364      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   365      *         <code>DataBuffer.TYPE_USHORT</code>
       
   366      *         or <code>DataBuffer.TYPE_INT</code>
       
   367      * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code>
       
   368      *         or <code>bandOffsets</code> is <code>null</code>
       
   369      */
       
   370     public static WritableRaster createBandedRaster(int dataType,
       
   371                                                     int w, int h,
       
   372                                                     int scanlineStride,
       
   373                                                     int bankIndices[],
       
   374                                                     int bandOffsets[],
       
   375                                                     Point location) {
       
   376         DataBuffer d;
       
   377         int bands = bandOffsets.length;
       
   378 
       
   379         if (bankIndices == null) {
       
   380             throw new
       
   381                 ArrayIndexOutOfBoundsException("Bank indices array is null");
       
   382         }
       
   383         if (bandOffsets == null) {
       
   384             throw new
       
   385                 ArrayIndexOutOfBoundsException("Band offsets array is null");
       
   386         }
       
   387 
       
   388         // Figure out the #banks and the largest band offset
       
   389         int maxBank = bankIndices[0];
       
   390         int maxBandOff = bandOffsets[0];
       
   391         for (int i = 1; i < bands; i++) {
       
   392             if (bankIndices[i] > maxBank) {
       
   393                 maxBank = bankIndices[i];
       
   394             }
       
   395             if (bandOffsets[i] > maxBandOff) {
       
   396                 maxBandOff = bandOffsets[i];
       
   397             }
       
   398         }
       
   399         int banks = maxBank + 1;
       
   400         int size = maxBandOff + scanlineStride*(h-1) + (w-1) + 1;
       
   401 
       
   402         switch(dataType) {
       
   403         case DataBuffer.TYPE_BYTE:
       
   404             d = new DataBufferByte(size, banks);
       
   405             break;
       
   406 
       
   407         case DataBuffer.TYPE_USHORT:
       
   408             d = new DataBufferUShort(size, banks);
       
   409             break;
       
   410 
       
   411         case DataBuffer.TYPE_INT:
       
   412             d = new DataBufferInt(size, banks);
       
   413             break;
       
   414 
       
   415         default:
       
   416             throw new IllegalArgumentException("Unsupported data type " +
       
   417                                                 dataType);
       
   418         }
       
   419 
       
   420         return createBandedRaster(d, w, h, scanlineStride,
       
   421                                   bankIndices, bandOffsets, location);
       
   422     }
       
   423 
       
   424     /**
       
   425      * Creates a Raster based on a SinglePixelPackedSampleModel with
       
   426      * the specified data type, width, height, and band masks.
       
   427      * The number of bands is inferred from bandMasks.length.
       
   428      *
       
   429      * <p> The upper left corner of the Raster is given by the
       
   430      * location argument.  If location is null, (0, 0) will be used.
       
   431      * The dataType parameter should be one of the enumerated values
       
   432      * defined in the DataBuffer class.
       
   433      *
       
   434      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
       
   435      * and TYPE_INT.
       
   436      * @param dataType  the data type for storing samples
       
   437      * @param w         the width in pixels of the image data
       
   438      * @param h         the height in pixels of the image data
       
   439      * @param bandMasks an array containing an entry for each band
       
   440      * @param location  the upper-left corner of the <code>Raster</code>
       
   441      * @return a WritableRaster object with the specified data type,
       
   442      *         width, height, and band masks.
       
   443      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   444      *         is less than or equal to zero, or computing either
       
   445      *         <code>location.x + w</code> or
       
   446      *         <code>location.y + h</code> results in integer
       
   447      *         overflow
       
   448      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   449      *         one of the supported data types, which are
       
   450      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   451      *         <code>DataBuffer.TYPE_USHORT</code>
       
   452      *         or <code>DataBuffer.TYPE_INT</code>
       
   453      */
       
   454     public static WritableRaster createPackedRaster(int dataType,
       
   455                                                     int w, int h,
       
   456                                                     int bandMasks[],
       
   457                                                     Point location) {
       
   458         DataBuffer d;
       
   459 
       
   460         switch(dataType) {
       
   461         case DataBuffer.TYPE_BYTE:
       
   462             d = new DataBufferByte(w*h);
       
   463             break;
       
   464 
       
   465         case DataBuffer.TYPE_USHORT:
       
   466             d = new DataBufferUShort(w*h);
       
   467             break;
       
   468 
       
   469         case DataBuffer.TYPE_INT:
       
   470             d = new DataBufferInt(w*h);
       
   471             break;
       
   472 
       
   473         default:
       
   474             throw new IllegalArgumentException("Unsupported data type " +
       
   475                                                 dataType);
       
   476         }
       
   477 
       
   478         return createPackedRaster(d, w, h, w, bandMasks, location);
       
   479     }
       
   480 
       
   481     /**
       
   482      * Creates a Raster based on a packed SampleModel with the
       
   483      * specified data type, width, height, number of bands, and bits
       
   484      * per band.  If the number of bands is one, the SampleModel will
       
   485      * be a MultiPixelPackedSampleModel.
       
   486      *
       
   487      * <p> If the number of bands is more than one, the SampleModel
       
   488      * will be a SinglePixelPackedSampleModel, with each band having
       
   489      * bitsPerBand bits.  In either case, the requirements on dataType
       
   490      * and bitsPerBand imposed by the corresponding SampleModel must
       
   491      * be met.
       
   492      *
       
   493      * <p> The upper left corner of the Raster is given by the
       
   494      * location argument.  If location is null, (0, 0) will be used.
       
   495      * The dataType parameter should be one of the enumerated values
       
   496      * defined in the DataBuffer class.
       
   497      *
       
   498      * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
       
   499      * and TYPE_INT.
       
   500      * @param dataType  the data type for storing samples
       
   501      * @param w         the width in pixels of the image data
       
   502      * @param h         the height in pixels of the image data
       
   503      * @param bands     the number of bands
       
   504      * @param bitsPerBand the number of bits per band
       
   505      * @param location  the upper-left corner of the <code>Raster</code>
       
   506      * @return a WritableRaster object with the specified data type,
       
   507      *         width, height, number of bands, and bits per band.
       
   508      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   509      *         is less than or equal to zero, or computing either
       
   510      *         <code>location.x + w</code> or
       
   511      *         <code>location.y + h</code> results in integer
       
   512      *         overflow
       
   513      * @throws IllegalArgumentException if the product of
       
   514      *         <code>bitsPerBand</code> and <code>bands</code> is
       
   515      *         greater than the number of bits held by
       
   516      *         <code>dataType</code>
       
   517      * @throws IllegalArgumentException if <code>bitsPerBand</code> or
       
   518      *         <code>bands</code> is not greater than zero
       
   519      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   520      *         one of the supported data types, which are
       
   521      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   522      *         <code>DataBuffer.TYPE_USHORT</code>
       
   523      *         or <code>DataBuffer.TYPE_INT</code>
       
   524      */
       
   525     public static WritableRaster createPackedRaster(int dataType,
       
   526                                                     int w, int h,
       
   527                                                     int bands,
       
   528                                                     int bitsPerBand,
       
   529                                                     Point location) {
       
   530         DataBuffer d;
       
   531 
       
   532         if (bands <= 0) {
       
   533             throw new IllegalArgumentException("Number of bands ("+bands+
       
   534                                                ") must be greater than 0");
       
   535         }
       
   536 
       
   537         if (bitsPerBand <= 0) {
       
   538             throw new IllegalArgumentException("Bits per band ("+bitsPerBand+
       
   539                                                ") must be greater than 0");
       
   540         }
       
   541 
       
   542         if (bands != 1) {
       
   543             int[] masks = new int[bands];
       
   544             int mask = (1 << bitsPerBand) - 1;
       
   545             int shift = (bands-1)*bitsPerBand;
       
   546 
       
   547             /* Make sure the total mask size will fit in the data type */
       
   548             if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
       
   549                 throw new IllegalArgumentException("bitsPerBand("+
       
   550                                                    bitsPerBand+") * bands is "+
       
   551                                                    " greater than data type "+
       
   552                                                    "size.");
       
   553             }
       
   554             switch(dataType) {
       
   555             case DataBuffer.TYPE_BYTE:
       
   556             case DataBuffer.TYPE_USHORT:
       
   557             case DataBuffer.TYPE_INT:
       
   558                 break;
       
   559             default:
       
   560                 throw new IllegalArgumentException("Unsupported data type " +
       
   561                                                     dataType);
       
   562             }
       
   563 
       
   564             for (int i = 0; i < bands; i++) {
       
   565                 masks[i] = mask << shift;
       
   566                 shift = shift - bitsPerBand;
       
   567             }
       
   568 
       
   569             return createPackedRaster(dataType, w, h, masks, location);
       
   570         }
       
   571         else {
       
   572             double fw = w;
       
   573             switch(dataType) {
       
   574             case DataBuffer.TYPE_BYTE:
       
   575                 d = new DataBufferByte((int)(Math.ceil(fw/(8/bitsPerBand)))*h);
       
   576                 break;
       
   577 
       
   578             case DataBuffer.TYPE_USHORT:
       
   579                 d = new DataBufferUShort((int)(Math.ceil(fw/(16/bitsPerBand)))*h);
       
   580                 break;
       
   581 
       
   582             case DataBuffer.TYPE_INT:
       
   583                 d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h);
       
   584                 break;
       
   585 
       
   586             default:
       
   587                 throw new IllegalArgumentException("Unsupported data type " +
       
   588                                                    dataType);
       
   589             }
       
   590 
       
   591             return createPackedRaster(d, w, h, bitsPerBand, location);
       
   592         }
       
   593     }
       
   594 
       
   595     /**
       
   596      * Creates a Raster based on a PixelInterleavedSampleModel with the
       
   597      * specified DataBuffer, width, height, scanline stride, pixel
       
   598      * stride, and band offsets.  The number of bands is inferred from
       
   599      * bandOffsets.length.  The upper left corner of the Raster
       
   600      * is given by the location argument.  If location is null, (0, 0)
       
   601      * will be used.
       
   602      * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
       
   603      * Rasters are not supported.  To create a 1-band Raster of type
       
   604      * <code>DataBuffer.TYPE_INT</code>, use
       
   605      * Raster.createPackedRaster().
       
   606      * @param dataBuffer the <code>DataBuffer</code> that contains the
       
   607      *        image data
       
   608      * @param w         the width in pixels of the image data
       
   609      * @param h         the height in pixels of the image data
       
   610      * @param scanlineStride the line stride of the image data
       
   611      * @param pixelStride the pixel stride of the image data
       
   612      * @param bandOffsets the offsets of all bands
       
   613      * @param location  the upper-left corner of the <code>Raster</code>
       
   614      * @return a WritableRaster object with the specified
       
   615      *         <code>DataBuffer</code>, width, height, scanline stride,
       
   616      *         pixel stride and band offsets.
       
   617      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   618      *         is less than or equal to zero, or computing either
       
   619      *         <code>location.x + w</code> or
       
   620      *         <code>location.y + h</code> results in integer
       
   621      *         overflow
       
   622      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   623      *         one of the supported data types, which are
       
   624      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   625      *         <code>DataBuffer.TYPE_USHORT</code>
       
   626      * @throws RasterFormatException if <code>dataBuffer</code> has more
       
   627      *         than one bank.
       
   628      * @throws NullPointerException if <code>dataBuffer</code> is null
       
   629      */
       
   630     public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
       
   631                                                          int w, int h,
       
   632                                                          int scanlineStride,
       
   633                                                          int pixelStride,
       
   634                                                          int bandOffsets[],
       
   635                                                          Point location) {
       
   636         if (dataBuffer == null) {
       
   637             throw new NullPointerException("DataBuffer cannot be null");
       
   638         }
       
   639         if (location == null) {
       
   640             location = new Point(0, 0);
       
   641         }
       
   642         int dataType = dataBuffer.getDataType();
       
   643 
       
   644         PixelInterleavedSampleModel csm =
       
   645             new PixelInterleavedSampleModel(dataType, w, h,
       
   646                                             pixelStride,
       
   647                                             scanlineStride,
       
   648                                             bandOffsets);
       
   649         switch(dataType) {
       
   650         case DataBuffer.TYPE_BYTE:
       
   651             return new ByteInterleavedRaster(csm, dataBuffer, location);
       
   652 
       
   653         case DataBuffer.TYPE_USHORT:
       
   654             return new ShortInterleavedRaster(csm, dataBuffer, location);
       
   655 
       
   656         default:
       
   657             throw new IllegalArgumentException("Unsupported data type " +
       
   658                                                 dataType);
       
   659         }
       
   660     }
       
   661 
       
   662     /**
       
   663      * Creates a Raster based on a BandedSampleModel with the
       
   664      * specified DataBuffer, width, height, scanline stride, bank
       
   665      * indices, and band offsets.  The number of bands is inferred
       
   666      * from bankIndices.length and bandOffsets.length, which must be
       
   667      * the same.  The upper left corner of the Raster is given by the
       
   668      * location argument.  If location is null, (0, 0) will be used.
       
   669      * @param dataBuffer the <code>DataBuffer</code> that contains the
       
   670      *        image data
       
   671      * @param w         the width in pixels of the image data
       
   672      * @param h         the height in pixels of the image data
       
   673      * @param scanlineStride the line stride of the image data
       
   674      * @param bankIndices the bank indices for each band
       
   675      * @param bandOffsets the offsets of all bands
       
   676      * @param location  the upper-left corner of the <code>Raster</code>
       
   677      * @return a WritableRaster object with the specified
       
   678      *         <code>DataBuffer</code>, width, height, scanline stride,
       
   679      *         bank indices and band offsets.
       
   680      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   681      *         is less than or equal to zero, or computing either
       
   682      *         <code>location.x + w</code> or
       
   683      *         <code>location.y + h</code> results in integer
       
   684      *         overflow
       
   685      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   686      *         one of the supported data types, which are
       
   687      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   688      *         <code>DataBuffer.TYPE_USHORT</code>
       
   689      *         or <code>DataBuffer.TYPE_INT</code>
       
   690      * @throws NullPointerException if <code>dataBuffer</code> is null
       
   691      */
       
   692     public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
       
   693                                                     int w, int h,
       
   694                                                     int scanlineStride,
       
   695                                                     int bankIndices[],
       
   696                                                     int bandOffsets[],
       
   697                                                     Point location) {
       
   698         if (dataBuffer == null) {
       
   699             throw new NullPointerException("DataBuffer cannot be null");
       
   700         }
       
   701         if (location == null) {
       
   702            location = new Point(0,0);
       
   703         }
       
   704         int dataType = dataBuffer.getDataType();
       
   705 
       
   706         int bands = bankIndices.length;
       
   707         if (bandOffsets.length != bands) {
       
   708             throw new IllegalArgumentException(
       
   709                                    "bankIndices.length != bandOffsets.length");
       
   710         }
       
   711 
       
   712         BandedSampleModel bsm =
       
   713             new BandedSampleModel(dataType, w, h,
       
   714                                   scanlineStride,
       
   715                                   bankIndices, bandOffsets);
       
   716 
       
   717         switch(dataType) {
       
   718         case DataBuffer.TYPE_BYTE:
       
   719             return new ByteBandedRaster(bsm, dataBuffer, location);
       
   720 
       
   721         case DataBuffer.TYPE_USHORT:
       
   722             return new ShortBandedRaster(bsm, dataBuffer, location);
       
   723 
       
   724         case DataBuffer.TYPE_INT:
       
   725             return new SunWritableRaster(bsm, dataBuffer, location);
       
   726 
       
   727         default:
       
   728             throw new IllegalArgumentException("Unsupported data type " +
       
   729                                                 dataType);
       
   730         }
       
   731     }
       
   732 
       
   733     /**
       
   734      * Creates a Raster based on a SinglePixelPackedSampleModel with
       
   735      * the specified DataBuffer, width, height, scanline stride, and
       
   736      * band masks.  The number of bands is inferred from bandMasks.length.
       
   737      * The upper left corner of the Raster is given by
       
   738      * the location argument.  If location is null, (0, 0) will be used.
       
   739      * @param dataBuffer the <code>DataBuffer</code> that contains the
       
   740      *        image data
       
   741      * @param w         the width in pixels of the image data
       
   742      * @param h         the height in pixels of the image data
       
   743      * @param scanlineStride the line stride of the image data
       
   744      * @param bandMasks an array containing an entry for each band
       
   745      * @param location  the upper-left corner of the <code>Raster</code>
       
   746      * @return a WritableRaster object with the specified
       
   747      *         <code>DataBuffer</code>, width, height, scanline stride,
       
   748      *         and band masks.
       
   749      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   750      *         is less than or equal to zero, or computing either
       
   751      *         <code>location.x + w</code> or
       
   752      *         <code>location.y + h</code> results in integer
       
   753      *         overflow
       
   754      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   755      *         one of the supported data types, which are
       
   756      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   757      *         <code>DataBuffer.TYPE_USHORT</code>
       
   758      *         or <code>DataBuffer.TYPE_INT</code>
       
   759      * @throws RasterFormatException if <code>dataBuffer</code> has more
       
   760      *         than one bank.
       
   761      * @throws NullPointerException if <code>dataBuffer</code> is null
       
   762      */
       
   763     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
       
   764                                                     int w, int h,
       
   765                                                     int scanlineStride,
       
   766                                                     int bandMasks[],
       
   767                                                     Point location) {
       
   768         if (dataBuffer == null) {
       
   769             throw new NullPointerException("DataBuffer cannot be null");
       
   770         }
       
   771         if (location == null) {
       
   772            location = new Point(0,0);
       
   773         }
       
   774         int dataType = dataBuffer.getDataType();
       
   775 
       
   776         SinglePixelPackedSampleModel sppsm =
       
   777             new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride,
       
   778                                              bandMasks);
       
   779 
       
   780         switch(dataType) {
       
   781         case DataBuffer.TYPE_BYTE:
       
   782             return new ByteInterleavedRaster(sppsm, dataBuffer, location);
       
   783 
       
   784         case DataBuffer.TYPE_USHORT:
       
   785             return new ShortInterleavedRaster(sppsm, dataBuffer, location);
       
   786 
       
   787         case DataBuffer.TYPE_INT:
       
   788             return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
       
   789 
       
   790         default:
       
   791             throw new IllegalArgumentException("Unsupported data type " +
       
   792                                                 dataType);
       
   793         }
       
   794     }
       
   795 
       
   796     /**
       
   797      * Creates a Raster based on a MultiPixelPackedSampleModel with the
       
   798      * specified DataBuffer, width, height, and bits per pixel.  The upper
       
   799      * left corner of the Raster is given by the location argument.  If
       
   800      * location is null, (0, 0) will be used.
       
   801      * @param dataBuffer the <code>DataBuffer</code> that contains the
       
   802      *        image data
       
   803      * @param w         the width in pixels of the image data
       
   804      * @param h         the height in pixels of the image data
       
   805      * @param bitsPerPixel the number of bits for each pixel
       
   806      * @param location  the upper-left corner of the <code>Raster</code>
       
   807      * @return a WritableRaster object with the specified
       
   808      *         <code>DataBuffer</code>, width, height, and
       
   809      *         bits per pixel.
       
   810      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
   811      *         is less than or equal to zero, or computing either
       
   812      *         <code>location.x + w</code> or
       
   813      *         <code>location.y + h</code> results in integer
       
   814      *         overflow
       
   815      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   816      *         one of the supported data types, which are
       
   817      *         <code>DataBuffer.TYPE_BYTE</code>,
       
   818      *         <code>DataBuffer.TYPE_USHORT</code>
       
   819      *         or <code>DataBuffer.TYPE_INT</code>
       
   820      * @throws RasterFormatException if <code>dataBuffer</code> has more
       
   821      *         than one bank.
       
   822      * @throws NullPointerException if <code>dataBuffer</code> is null
       
   823      */
       
   824     public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
       
   825                                                     int w, int h,
       
   826                                                     int bitsPerPixel,
       
   827                                                     Point location) {
       
   828         if (dataBuffer == null) {
       
   829             throw new NullPointerException("DataBuffer cannot be null");
       
   830         }
       
   831         if (location == null) {
       
   832            location = new Point(0,0);
       
   833         }
       
   834         int dataType = dataBuffer.getDataType();
       
   835 
       
   836         if (dataType != DataBuffer.TYPE_BYTE &&
       
   837             dataType != DataBuffer.TYPE_USHORT &&
       
   838             dataType != DataBuffer.TYPE_INT) {
       
   839             throw new IllegalArgumentException("Unsupported data type " +
       
   840                                                dataType);
       
   841         }
       
   842 
       
   843         if (dataBuffer.getNumBanks() != 1) {
       
   844             throw new
       
   845                 RasterFormatException("DataBuffer for packed Rasters"+
       
   846                                       " must only have 1 bank.");
       
   847         }
       
   848 
       
   849         MultiPixelPackedSampleModel mppsm =
       
   850                 new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
       
   851 
       
   852         if (dataType == DataBuffer.TYPE_BYTE &&
       
   853             (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
       
   854             return new BytePackedRaster(mppsm, dataBuffer, location);
       
   855         } else {
       
   856             return new SunWritableRaster(mppsm, dataBuffer, location);
       
   857         }
       
   858     }
       
   859 
       
   860 
       
   861     /**
       
   862      *  Creates a Raster with the specified SampleModel and DataBuffer.
       
   863      *  The upper left corner of the Raster is given by the location argument.
       
   864      *  If location is null, (0, 0) will be used.
       
   865      *  @param sm the specified <code>SampleModel</code>
       
   866      *  @param db the specified <code>DataBuffer</code>
       
   867      *  @param location the upper-left corner of the <code>Raster</code>
       
   868      *  @return a <code>Raster</code> with the specified
       
   869      *          <code>SampleModel</code>, <code>DataBuffer</code>, and
       
   870      *          location.
       
   871      * @throws RasterFormatException if computing either
       
   872      *         <code>location.x + sm.getWidth()</code> or
       
   873      *         <code>location.y + sm.getHeight()</code> results in integer
       
   874      *         overflow
       
   875      * @throws RasterFormatException if <code>db</code> has more
       
   876      *         than one bank and <code>sm</code> is a
       
   877      *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
       
   878      *         or MultiPixelPackedSampleModel.
       
   879      *  @throws NullPointerException if either SampleModel or DataBuffer is
       
   880      *          null
       
   881      */
       
   882     public static Raster createRaster(SampleModel sm,
       
   883                                       DataBuffer db,
       
   884                                       Point location) {
       
   885         if ((sm == null) || (db == null)) {
       
   886             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
       
   887         }
       
   888 
       
   889         if (location == null) {
       
   890            location = new Point(0,0);
       
   891         }
       
   892         int dataType = sm.getDataType();
       
   893 
       
   894         if (sm instanceof PixelInterleavedSampleModel) {
       
   895             switch(dataType) {
       
   896                 case DataBuffer.TYPE_BYTE:
       
   897                     return new ByteInterleavedRaster(sm, db, location);
       
   898 
       
   899                 case DataBuffer.TYPE_USHORT:
       
   900                     return new ShortInterleavedRaster(sm, db, location);
       
   901             }
       
   902         } else if (sm instanceof SinglePixelPackedSampleModel) {
       
   903             switch(dataType) {
       
   904                 case DataBuffer.TYPE_BYTE:
       
   905                     return new ByteInterleavedRaster(sm, db, location);
       
   906 
       
   907                 case DataBuffer.TYPE_USHORT:
       
   908                     return new ShortInterleavedRaster(sm, db, location);
       
   909 
       
   910                 case DataBuffer.TYPE_INT:
       
   911                     return new IntegerInterleavedRaster(sm, db, location);
       
   912             }
       
   913         } else if (sm instanceof MultiPixelPackedSampleModel &&
       
   914                    dataType == DataBuffer.TYPE_BYTE &&
       
   915                    sm.getSampleSize(0) < 8) {
       
   916             return new BytePackedRaster(sm, db, location);
       
   917         }
       
   918 
       
   919         // we couldn't do anything special - do the generic thing
       
   920 
       
   921         return new Raster(sm,db,location);
       
   922     }
       
   923 
       
   924     /**
       
   925      *  Creates a WritableRaster with the specified SampleModel.
       
   926      *  The upper left corner of the Raster is given by the location argument.
       
   927      *  If location is null, (0, 0) will be used.
       
   928      *  @param sm the specified <code>SampleModel</code>
       
   929      *  @param location the upper-left corner of the
       
   930      *         <code>WritableRaster</code>
       
   931      *  @return a <code>WritableRaster</code> with the specified
       
   932      *          <code>SampleModel</code> and location.
       
   933      *  @throws RasterFormatException if computing either
       
   934      *          <code>location.x + sm.getWidth()</code> or
       
   935      *          <code>location.y + sm.getHeight()</code> results in integer
       
   936      *          overflow
       
   937      */
       
   938     public static WritableRaster createWritableRaster(SampleModel sm,
       
   939                                                       Point location) {
       
   940         if (location == null) {
       
   941            location = new Point(0,0);
       
   942         }
       
   943 
       
   944         return createWritableRaster(sm, sm.createDataBuffer(), location);
       
   945     }
       
   946 
       
   947     /**
       
   948      *  Creates a WritableRaster with the specified SampleModel and DataBuffer.
       
   949      *  The upper left corner of the Raster is given by the location argument.
       
   950      *  If location is null, (0, 0) will be used.
       
   951      *  @param sm the specified <code>SampleModel</code>
       
   952      *  @param db the specified <code>DataBuffer</code>
       
   953      *  @param location the upper-left corner of the
       
   954      *         <code>WritableRaster</code>
       
   955      *  @return a <code>WritableRaster</code> with the specified
       
   956      *          <code>SampleModel</code>, <code>DataBuffer</code>, and
       
   957      *          location.
       
   958      * @throws RasterFormatException if computing either
       
   959      *         <code>location.x + sm.getWidth()</code> or
       
   960      *         <code>location.y + sm.getHeight()</code> results in integer
       
   961      *         overflow
       
   962      * @throws RasterFormatException if <code>db</code> has more
       
   963      *         than one bank and <code>sm</code> is a
       
   964      *         PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
       
   965      *         or MultiPixelPackedSampleModel.
       
   966      * @throws NullPointerException if either SampleModel or DataBuffer is null
       
   967      */
       
   968     public static WritableRaster createWritableRaster(SampleModel sm,
       
   969                                                       DataBuffer db,
       
   970                                                       Point location) {
       
   971         if ((sm == null) || (db == null)) {
       
   972             throw new NullPointerException("SampleModel and DataBuffer cannot be null");
       
   973         }
       
   974         if (location == null) {
       
   975            location = new Point(0,0);
       
   976         }
       
   977 
       
   978         int dataType = sm.getDataType();
       
   979 
       
   980         if (sm instanceof PixelInterleavedSampleModel) {
       
   981             switch(dataType) {
       
   982                 case DataBuffer.TYPE_BYTE:
       
   983                     return new ByteInterleavedRaster(sm, db, location);
       
   984 
       
   985                 case DataBuffer.TYPE_USHORT:
       
   986                     return new ShortInterleavedRaster(sm, db, location);
       
   987             }
       
   988         } else if (sm instanceof SinglePixelPackedSampleModel) {
       
   989             switch(dataType) {
       
   990                 case DataBuffer.TYPE_BYTE:
       
   991                     return new ByteInterleavedRaster(sm, db, location);
       
   992 
       
   993                 case DataBuffer.TYPE_USHORT:
       
   994                     return new ShortInterleavedRaster(sm, db, location);
       
   995 
       
   996                 case DataBuffer.TYPE_INT:
       
   997                     return new IntegerInterleavedRaster(sm, db, location);
       
   998             }
       
   999         } else if (sm instanceof MultiPixelPackedSampleModel &&
       
  1000                    dataType == DataBuffer.TYPE_BYTE &&
       
  1001                    sm.getSampleSize(0) < 8) {
       
  1002             return new BytePackedRaster(sm, db, location);
       
  1003         }
       
  1004 
       
  1005         // we couldn't do anything special - do the generic thing
       
  1006 
       
  1007         return new SunWritableRaster(sm,db,location);
       
  1008     }
       
  1009 
       
  1010     /**
       
  1011      *  Constructs a Raster with the given SampleModel.  The Raster's
       
  1012      *  upper left corner is origin and it is the same size as the
       
  1013      *  SampleModel.  A DataBuffer large enough to describe the
       
  1014      *  Raster is automatically created.
       
  1015      *  @param sampleModel     The SampleModel that specifies the layout
       
  1016      *  @param origin          The Point that specified the origin
       
  1017      *  @throws RasterFormatException if computing either
       
  1018      *          <code>origin.x + sampleModel.getWidth()</code> or
       
  1019      *          <code>origin.y + sampleModel.getHeight()</code> results in
       
  1020      *          integer overflow
       
  1021      *  @throws NullPointerException either <code>sampleModel</code> or
       
  1022      *          <code>origin</code> is null
       
  1023      */
       
  1024     protected Raster(SampleModel sampleModel,
       
  1025                      Point origin) {
       
  1026         this(sampleModel,
       
  1027              sampleModel.createDataBuffer(),
       
  1028              new Rectangle(origin.x,
       
  1029                            origin.y,
       
  1030                            sampleModel.getWidth(),
       
  1031                            sampleModel.getHeight()),
       
  1032              origin,
       
  1033              null);
       
  1034     }
       
  1035 
       
  1036     /**
       
  1037      *  Constructs a Raster with the given SampleModel and DataBuffer.
       
  1038      *  The Raster's upper left corner is origin and it is the same size
       
  1039      *  as the SampleModel.  The DataBuffer is not initialized and must
       
  1040      *  be compatible with SampleModel.
       
  1041      *  @param sampleModel     The SampleModel that specifies the layout
       
  1042      *  @param dataBuffer      The DataBuffer that contains the image data
       
  1043      *  @param origin          The Point that specifies the origin
       
  1044      *  @throws RasterFormatException if computing either
       
  1045      *          <code>origin.x + sampleModel.getWidth()</code> or
       
  1046      *          <code>origin.y + sampleModel.getHeight()</code> results in
       
  1047      *          integer overflow
       
  1048      *  @throws NullPointerException either <code>sampleModel</code> or
       
  1049      *          <code>origin</code> is null
       
  1050      */
       
  1051     protected Raster(SampleModel sampleModel,
       
  1052                      DataBuffer dataBuffer,
       
  1053                      Point origin) {
       
  1054         this(sampleModel,
       
  1055              dataBuffer,
       
  1056              new Rectangle(origin.x,
       
  1057                            origin.y,
       
  1058                            sampleModel.getWidth(),
       
  1059                            sampleModel.getHeight()),
       
  1060              origin,
       
  1061              null);
       
  1062     }
       
  1063 
       
  1064     /**
       
  1065      * Constructs a Raster with the given SampleModel, DataBuffer, and
       
  1066      * parent.  aRegion specifies the bounding rectangle of the new
       
  1067      * Raster.  When translated into the base Raster's coordinate
       
  1068      * system, aRegion must be contained by the base Raster.
       
  1069      * (The base Raster is the Raster's ancestor which has no parent.)
       
  1070      * sampleModelTranslate specifies the sampleModelTranslateX and
       
  1071      * sampleModelTranslateY values of the new Raster.
       
  1072      *
       
  1073      * Note that this constructor should generally be called by other
       
  1074      * constructors or create methods, it should not be used directly.
       
  1075      * @param sampleModel     The SampleModel that specifies the layout
       
  1076      * @param dataBuffer      The DataBuffer that contains the image data
       
  1077      * @param aRegion         The Rectangle that specifies the image area
       
  1078      * @param sampleModelTranslate  The Point that specifies the translation
       
  1079      *                        from SampleModel to Raster coordinates
       
  1080      * @param parent          The parent (if any) of this raster
       
  1081      * @throws NullPointerException if any of <code>sampleModel</code>,
       
  1082      *         <code>dataBuffer</code>, <code>aRegion</code> or
       
  1083      *         <code>sampleModelTranslate</code> is null
       
  1084      * @throws RasterFormatException if <code>aRegion</code> has width
       
  1085      *         or height less than or equal to zero, or computing either
       
  1086      *         <code>aRegion.x + aRegion.width</code> or
       
  1087      *         <code>aRegion.y + aRegion.height</code> results in integer
       
  1088      *         overflow
       
  1089      */
       
  1090     protected Raster(SampleModel sampleModel,
       
  1091                      DataBuffer dataBuffer,
       
  1092                      Rectangle aRegion,
       
  1093                      Point sampleModelTranslate,
       
  1094                      Raster parent) {
       
  1095 
       
  1096         if ((sampleModel == null) || (dataBuffer == null) ||
       
  1097             (aRegion == null) || (sampleModelTranslate == null)) {
       
  1098             throw new NullPointerException("SampleModel, dataBuffer, aRegion and " +
       
  1099                                            "sampleModelTranslate cannot be null");
       
  1100         }
       
  1101        this.sampleModel = sampleModel;
       
  1102        this.dataBuffer = dataBuffer;
       
  1103        minX = aRegion.x;
       
  1104        minY = aRegion.y;
       
  1105        width = aRegion.width;
       
  1106        height = aRegion.height;
       
  1107        if (width <= 0 || height <= 0) {
       
  1108            throw new RasterFormatException("negative or zero " +
       
  1109                ((width <= 0) ? "width" : "height"));
       
  1110        }
       
  1111        if ((minX + width) < minX) {
       
  1112            throw new RasterFormatException(
       
  1113                "overflow condition for X coordinates of Raster");
       
  1114        }
       
  1115        if ((minY + height) < minY) {
       
  1116            throw new RasterFormatException(
       
  1117                "overflow condition for Y coordinates of Raster");
       
  1118        }
       
  1119 
       
  1120        sampleModelTranslateX = sampleModelTranslate.x;
       
  1121        sampleModelTranslateY = sampleModelTranslate.y;
       
  1122 
       
  1123        numBands = sampleModel.getNumBands();
       
  1124        numDataElements = sampleModel.getNumDataElements();
       
  1125        this.parent = parent;
       
  1126     }
       
  1127 
       
  1128 
       
  1129     /**
       
  1130      * Returns the parent Raster (if any) of this Raster or null.
       
  1131      * @return the parent Raster or <code>null</code>.
       
  1132      */
       
  1133     public Raster getParent() {
       
  1134         return parent;
       
  1135     }
       
  1136 
       
  1137     /**
       
  1138      * Returns the X translation from the coordinate system of the
       
  1139      * SampleModel to that of the Raster.  To convert a pixel's X
       
  1140      * coordinate from the Raster coordinate system to the SampleModel
       
  1141      * coordinate system, this value must be subtracted.
       
  1142      * @return the X translation from the coordinate space of the
       
  1143      *         Raster's SampleModel to that of the Raster.
       
  1144      */
       
  1145     final public int getSampleModelTranslateX() {
       
  1146         return sampleModelTranslateX;
       
  1147     }
       
  1148 
       
  1149     /**
       
  1150      * Returns the Y translation from the coordinate system of the
       
  1151      * SampleModel to that of the Raster.  To convert a pixel's Y
       
  1152      * coordinate from the Raster coordinate system to the SampleModel
       
  1153      * coordinate system, this value must be subtracted.
       
  1154      * @return the Y translation from the coordinate space of the
       
  1155      *         Raster's SampleModel to that of the Raster.
       
  1156      */
       
  1157     final public int getSampleModelTranslateY() {
       
  1158         return sampleModelTranslateY;
       
  1159     }
       
  1160 
       
  1161     /**
       
  1162      * Create a compatible WritableRaster the same size as this Raster with
       
  1163      * the same SampleModel and a new initialized DataBuffer.
       
  1164      * @return a compatible <code>WritableRaster</code> with the same sample
       
  1165      *         model and a new data buffer.
       
  1166      */
       
  1167     public WritableRaster createCompatibleWritableRaster() {
       
  1168         return new SunWritableRaster(sampleModel, new Point(0,0));
       
  1169     }
       
  1170 
       
  1171     /**
       
  1172      * Create a compatible WritableRaster with the specified size, a new
       
  1173      * SampleModel, and a new initialized DataBuffer.
       
  1174      * @param w the specified width of the new <code>WritableRaster</code>
       
  1175      * @param h the specified height of the new <code>WritableRaster</code>
       
  1176      * @return a compatible <code>WritableRaster</code> with the specified
       
  1177      *         size and a new sample model and data buffer.
       
  1178      * @exception RasterFormatException if the width or height is less than
       
  1179      *                               or equal to zero.
       
  1180      */
       
  1181     public WritableRaster createCompatibleWritableRaster(int w, int h) {
       
  1182         if (w <= 0 || h <=0) {
       
  1183             throw new RasterFormatException("negative " +
       
  1184                                           ((w <= 0) ? "width" : "height"));
       
  1185         }
       
  1186 
       
  1187         SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
       
  1188 
       
  1189         return new SunWritableRaster(sm, new Point(0,0));
       
  1190     }
       
  1191 
       
  1192     /**
       
  1193      * Create a compatible WritableRaster with location (minX, minY)
       
  1194      * and size (width, height) specified by rect, a
       
  1195      * new SampleModel, and a new initialized DataBuffer.
       
  1196      * @param rect a <code>Rectangle</code> that specifies the size and
       
  1197      *        location of the <code>WritableRaster</code>
       
  1198      * @return a compatible <code>WritableRaster</code> with the specified
       
  1199      *         size and location and a new sample model and data buffer.
       
  1200      * @throws RasterFormatException if <code>rect</code> has width
       
  1201      *         or height less than or equal to zero, or computing either
       
  1202      *         <code>rect.x + rect.width</code> or
       
  1203      *         <code>rect.y + rect.height</code> results in integer
       
  1204      *         overflow
       
  1205      * @throws NullPointerException if <code>rect</code> is null
       
  1206      */
       
  1207     public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
       
  1208         if (rect == null) {
       
  1209             throw new NullPointerException("Rect cannot be null");
       
  1210         }
       
  1211         return createCompatibleWritableRaster(rect.x, rect.y,
       
  1212                                               rect.width, rect.height);
       
  1213     }
       
  1214 
       
  1215     /**
       
  1216      * Create a compatible WritableRaster with the specified
       
  1217      * location (minX, minY) and size (width, height), a
       
  1218      * new SampleModel, and a new initialized DataBuffer.
       
  1219      * @param x the X coordinate of the upper-left corner of
       
  1220      *        the <code>WritableRaster</code>
       
  1221      * @param y the Y coordinate of the upper-left corner of
       
  1222      *        the <code>WritableRaster</code>
       
  1223      * @param w the specified width of the <code>WritableRaster</code>
       
  1224      * @param h the specified height of the <code>WritableRaster</code>
       
  1225      * @return a compatible <code>WritableRaster</code> with the specified
       
  1226      *         size and location and a new sample model and data buffer.
       
  1227      * @throws RasterFormatException if <code>w</code> or <code>h</code>
       
  1228      *         is less than or equal to zero, or computing either
       
  1229      *         <code>x + w</code> or
       
  1230      *         <code>y + h</code> results in integer
       
  1231      *         overflow
       
  1232      */
       
  1233     public WritableRaster createCompatibleWritableRaster(int x, int y,
       
  1234                                                          int w, int h) {
       
  1235         WritableRaster ret = createCompatibleWritableRaster(w, h);
       
  1236         return ret.createWritableChild(0,0,w,h,x,y,null);
       
  1237     }
       
  1238 
       
  1239     /**
       
  1240      * Create a Raster with the same size, SampleModel and DataBuffer
       
  1241      * as this one, but with a different location.  The new Raster
       
  1242      * will possess a reference to the current Raster, accessible
       
  1243      * through its getParent() method.
       
  1244      *
       
  1245      * @param childMinX the X coordinate of the upper-left
       
  1246      *        corner of the new <code>Raster</code>
       
  1247      * @param childMinY the Y coordinate of the upper-left
       
  1248      *        corner of the new <code>Raster</code>
       
  1249      * @return a new <code>Raster</code> with the same size, SampleModel,
       
  1250      *         and DataBuffer as this <code>Raster</code>, but with the
       
  1251      *         specified location.
       
  1252      * @throws RasterFormatException if  computing either
       
  1253      *         <code>childMinX + this.getWidth()</code> or
       
  1254      *         <code>childMinY + this.getHeight()</code> results in integer
       
  1255      *         overflow
       
  1256      */
       
  1257     public Raster createTranslatedChild(int childMinX, int childMinY) {
       
  1258         return createChild(minX,minY,width,height,
       
  1259                            childMinX,childMinY,null);
       
  1260     }
       
  1261 
       
  1262     /**
       
  1263      * Returns a new Raster which shares all or part of this Raster's
       
  1264      * DataBuffer.  The new Raster will possess a reference to the
       
  1265      * current Raster, accessible through its getParent() method.
       
  1266      *
       
  1267      * <p> The parentX, parentY, width and height parameters
       
  1268      * form a Rectangle in this Raster's coordinate space,
       
  1269      * indicating the area of pixels to be shared.  An error will
       
  1270      * be thrown if this Rectangle is not contained with the bounds
       
  1271      * of the current Raster.
       
  1272      *
       
  1273      * <p> The new Raster may additionally be translated to a
       
  1274      * different coordinate system for the plane than that used by the current
       
  1275      * Raster.  The childMinX and childMinY parameters give the new
       
  1276      * (x, y) coordinate of the upper-left pixel of the returned
       
  1277      * Raster; the coordinate (childMinX, childMinY) in the new Raster
       
  1278      * will map to the same pixel as the coordinate (parentX, parentY)
       
  1279      * in the current Raster.
       
  1280      *
       
  1281      * <p> The new Raster may be defined to contain only a subset of
       
  1282      * the bands of the current Raster, possibly reordered, by means
       
  1283      * of the bandList parameter.  If bandList is null, it is taken to
       
  1284      * include all of the bands of the current Raster in their current
       
  1285      * order.
       
  1286      *
       
  1287      * <p> To create a new Raster that contains a subregion of the current
       
  1288      * Raster, but shares its coordinate system and bands,
       
  1289      * this method should be called with childMinX equal to parentX,
       
  1290      * childMinY equal to parentY, and bandList equal to null.
       
  1291      *
       
  1292      * @param parentX The X coordinate of the upper-left corner
       
  1293      *        in this Raster's coordinates
       
  1294      * @param parentY The Y coordinate of the upper-left corner
       
  1295      *        in this Raster's coordinates
       
  1296      * @param width      Width of the region starting at (parentX, parentY)
       
  1297      * @param height     Height of the region starting at (parentX, parentY).
       
  1298      * @param childMinX The X coordinate of the upper-left corner
       
  1299      *                   of the returned Raster
       
  1300      * @param childMinY The Y coordinate of the upper-left corner
       
  1301      *                   of the returned Raster
       
  1302      * @param bandList   Array of band indices, or null to use all bands
       
  1303      * @return a new <code>Raster</code>.
       
  1304      * @exception RasterFormatException if the specified subregion is outside
       
  1305      *                               of the raster bounds.
       
  1306      * @throws RasterFormatException if <code>width</code> or
       
  1307      *         <code>height</code>
       
  1308      *         is less than or equal to zero, or computing any of
       
  1309      *         <code>parentX + width</code>, <code>parentY + height</code>,
       
  1310      *         <code>childMinX + width</code>, or
       
  1311      *         <code>childMinY + height</code> results in integer
       
  1312      *         overflow
       
  1313      */
       
  1314     public Raster createChild(int parentX, int parentY,
       
  1315                               int width, int height,
       
  1316                               int childMinX, int childMinY,
       
  1317                               int bandList[]) {
       
  1318         if (parentX < this.minX) {
       
  1319             throw new RasterFormatException("parentX lies outside raster");
       
  1320         }
       
  1321         if (parentY < this.minY) {
       
  1322             throw new RasterFormatException("parentY lies outside raster");
       
  1323         }
       
  1324         if ((parentX + width < parentX) ||
       
  1325             (parentX + width > this.width + this.minX)) {
       
  1326             throw new RasterFormatException("(parentX + width) is outside raster");
       
  1327         }
       
  1328         if ((parentY + height < parentY) ||
       
  1329             (parentY + height > this.height + this.minY)) {
       
  1330             throw new RasterFormatException("(parentY + height) is outside raster");
       
  1331         }
       
  1332 
       
  1333         SampleModel subSampleModel;
       
  1334         // Note: the SampleModel for the child Raster should have the same
       
  1335         // width and height as that for the parent, since it represents
       
  1336         // the physical layout of the pixel data.  The child Raster's width
       
  1337         // and height represent a "virtual" view of the pixel data, so
       
  1338         // they may be different than those of the SampleModel.
       
  1339         if (bandList == null) {
       
  1340             subSampleModel = sampleModel;
       
  1341         } else {
       
  1342             subSampleModel = sampleModel.createSubsetSampleModel(bandList);
       
  1343         }
       
  1344 
       
  1345         int deltaX = childMinX - parentX;
       
  1346         int deltaY = childMinY - parentY;
       
  1347 
       
  1348         return new Raster(subSampleModel, getDataBuffer(),
       
  1349                           new Rectangle(childMinX, childMinY, width, height),
       
  1350                           new Point(sampleModelTranslateX + deltaX,
       
  1351                                     sampleModelTranslateY + deltaY), this);
       
  1352     }
       
  1353 
       
  1354     /**
       
  1355      * Returns the bounding Rectangle of this Raster. This function returns
       
  1356      * the same information as getMinX/MinY/Width/Height.
       
  1357      * @return the bounding box of this <code>Raster</code>.
       
  1358      */
       
  1359     public Rectangle getBounds() {
       
  1360         return new Rectangle(minX, minY, width, height);
       
  1361     }
       
  1362 
       
  1363     /** Returns the minimum valid X coordinate of the Raster.
       
  1364      *  @return the minimum x coordinate of this <code>Raster</code>.
       
  1365      */
       
  1366     final public int getMinX() {
       
  1367         return minX;
       
  1368     }
       
  1369 
       
  1370     /** Returns the minimum valid Y coordinate of the Raster.
       
  1371      *  @return the minimum y coordinate of this <code>Raster</code>.
       
  1372      */
       
  1373     final public int getMinY() {
       
  1374         return minY;
       
  1375     }
       
  1376 
       
  1377     /** Returns the width in pixels of the Raster.
       
  1378      *  @return the width of this <code>Raster</code>.
       
  1379      */
       
  1380     final public int getWidth() {
       
  1381         return width;
       
  1382     }
       
  1383 
       
  1384     /** Returns the height in pixels of the Raster.
       
  1385      *  @return the height of this <code>Raster</code>.
       
  1386      */
       
  1387     final public int getHeight() {
       
  1388         return height;
       
  1389     }
       
  1390 
       
  1391     /** Returns the number of bands (samples per pixel) in this Raster.
       
  1392      *  @return the number of bands of this <code>Raster</code>.
       
  1393      */
       
  1394     final public int getNumBands() {
       
  1395         return numBands;
       
  1396     }
       
  1397 
       
  1398     /**
       
  1399      *  Returns the number of data elements needed to transfer one pixel
       
  1400      *  via the getDataElements and setDataElements methods.  When pixels
       
  1401      *  are transferred via these methods, they may be transferred in a
       
  1402      *  packed or unpacked format, depending on the implementation of the
       
  1403      *  underlying SampleModel.  Using these methods, pixels are transferred
       
  1404      *  as an array of getNumDataElements() elements of a primitive type given
       
  1405      *  by getTransferType().  The TransferType may or may not be the same
       
  1406      *  as the storage data type of the DataBuffer.
       
  1407      *  @return the number of data elements.
       
  1408      */
       
  1409     final public int getNumDataElements() {
       
  1410         return sampleModel.getNumDataElements();
       
  1411     }
       
  1412 
       
  1413     /**
       
  1414      *  Returns the TransferType used to transfer pixels via the
       
  1415      *  getDataElements and setDataElements methods.  When pixels
       
  1416      *  are transferred via these methods, they may be transferred in a
       
  1417      *  packed or unpacked format, depending on the implementation of the
       
  1418      *  underlying SampleModel.  Using these methods, pixels are transferred
       
  1419      *  as an array of getNumDataElements() elements of a primitive type given
       
  1420      *  by getTransferType().  The TransferType may or may not be the same
       
  1421      *  as the storage data type of the DataBuffer.  The TransferType will
       
  1422      *  be one of the types defined in DataBuffer.
       
  1423      *  @return this transfer type.
       
  1424      */
       
  1425     final public int getTransferType() {
       
  1426         return sampleModel.getTransferType();
       
  1427     }
       
  1428 
       
  1429     /** Returns the DataBuffer associated with this Raster.
       
  1430      *  @return the <code>DataBuffer</code> of this <code>Raster</code>.
       
  1431      */
       
  1432     public DataBuffer getDataBuffer() {
       
  1433         return dataBuffer;
       
  1434     }
       
  1435 
       
  1436     /** Returns the SampleModel that describes the layout of the image data.
       
  1437      *  @return the <code>SampleModel</code> of this <code>Raster</code>.
       
  1438      */
       
  1439     public SampleModel getSampleModel() {
       
  1440         return sampleModel;
       
  1441     }
       
  1442 
       
  1443     /**
       
  1444      * Returns data for a single pixel in a primitive array of type
       
  1445      * TransferType.  For image data supported by the Java 2D(tm) API,
       
  1446      * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
       
  1447      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
       
  1448      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
       
  1449      * thus increasing efficiency for data transfers.
       
  1450      * An ArrayIndexOutOfBoundsException may be thrown
       
  1451      * if the coordinates are not in bounds.  However, explicit bounds
       
  1452      * checking is not guaranteed.
       
  1453      * A ClassCastException will be thrown if the input object is non null
       
  1454      * and references anything other than an array of TransferType.
       
  1455      * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
       
  1456      * @param x        The X coordinate of the pixel location
       
  1457      * @param y        The Y coordinate of the pixel location
       
  1458      * @param outData  An object reference to an array of type defined by
       
  1459      *                 getTransferType() and length getNumDataElements().
       
  1460      *                 If null, an array of appropriate type and size will be
       
  1461      *                 allocated
       
  1462      * @return         An object reference to an array of type defined by
       
  1463      *                 getTransferType() with the requested pixel data.
       
  1464      *
       
  1465      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1466      * in bounds, or if outData is too small to hold the output.
       
  1467      */
       
  1468     public Object getDataElements(int x, int y, Object outData) {
       
  1469         return sampleModel.getDataElements(x - sampleModelTranslateX,
       
  1470                                            y - sampleModelTranslateY,
       
  1471                                            outData, dataBuffer);
       
  1472     }
       
  1473 
       
  1474     /**
       
  1475      * Returns the pixel data for the specified rectangle of pixels in a
       
  1476      * primitive array of type TransferType.
       
  1477      * For image data supported by the Java 2D API, this
       
  1478      * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
       
  1479      * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
       
  1480      * or DataBuffer.TYPE_DOUBLE.  Data may be returned in a packed format,
       
  1481      * thus increasing efficiency for data transfers.
       
  1482      * An ArrayIndexOutOfBoundsException may be thrown
       
  1483      * if the coordinates are not in bounds.  However, explicit bounds
       
  1484      * checking is not guaranteed.
       
  1485      * A ClassCastException will be thrown if the input object is non null
       
  1486      * and references anything other than an array of TransferType.
       
  1487      * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
       
  1488      * @param x    The X coordinate of the upper-left pixel location
       
  1489      * @param y    The Y coordinate of the upper-left pixel location
       
  1490      * @param w    Width of the pixel rectangle
       
  1491      * @param h   Height of the pixel rectangle
       
  1492      * @param outData  An object reference to an array of type defined by
       
  1493      *                 getTransferType() and length w*h*getNumDataElements().
       
  1494      *                 If null, an array of appropriate type and size will be
       
  1495      *                 allocated.
       
  1496      * @return         An object reference to an array of type defined by
       
  1497      *                 getTransferType() with the requested pixel data.
       
  1498      *
       
  1499      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1500      * in bounds, or if outData is too small to hold the output.
       
  1501      */
       
  1502     public Object getDataElements(int x, int y, int w, int h, Object outData) {
       
  1503         return sampleModel.getDataElements(x - sampleModelTranslateX,
       
  1504                                            y - sampleModelTranslateY,
       
  1505                                            w, h, outData, dataBuffer);
       
  1506     }
       
  1507 
       
  1508     /**
       
  1509      * Returns the samples in an array of int for the specified pixel.
       
  1510      * An ArrayIndexOutOfBoundsException may be thrown
       
  1511      * if the coordinates are not in bounds.  However, explicit bounds
       
  1512      * checking is not guaranteed.
       
  1513      * @param x The X coordinate of the pixel location
       
  1514      * @param y The Y coordinate of the pixel location
       
  1515      * @param iArray An optionally preallocated int array
       
  1516      * @return the samples for the specified pixel.
       
  1517      *
       
  1518      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1519      * in bounds, or if iArray is too small to hold the output.
       
  1520      */
       
  1521     public int[] getPixel(int x, int y, int iArray[]) {
       
  1522         return sampleModel.getPixel(x - sampleModelTranslateX,
       
  1523                                     y - sampleModelTranslateY,
       
  1524                                     iArray, dataBuffer);
       
  1525     }
       
  1526 
       
  1527     /**
       
  1528      * Returns the samples in an array of float for the
       
  1529      * specified pixel.
       
  1530      * An ArrayIndexOutOfBoundsException may be thrown
       
  1531      * if the coordinates are not in bounds.  However, explicit bounds
       
  1532      * checking is not guaranteed.
       
  1533      * @param x The X coordinate of the pixel location
       
  1534      * @param y The Y coordinate of the pixel location
       
  1535      * @param fArray An optionally preallocated float array
       
  1536      * @return the samples for the specified pixel.
       
  1537      *
       
  1538      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1539      * in bounds, or if fArray is too small to hold the output.
       
  1540      */
       
  1541     public float[] getPixel(int x, int y, float fArray[]) {
       
  1542         return sampleModel.getPixel(x - sampleModelTranslateX,
       
  1543                                     y - sampleModelTranslateY,
       
  1544                                     fArray, dataBuffer);
       
  1545     }
       
  1546 
       
  1547     /**
       
  1548      * Returns the samples in an array of double for the specified pixel.
       
  1549      * An ArrayIndexOutOfBoundsException may be thrown
       
  1550      * if the coordinates are not in bounds.  However, explicit bounds
       
  1551      * checking is not guaranteed.
       
  1552      * @param x The X coordinate of the pixel location
       
  1553      * @param y The Y coordinate of the pixel location
       
  1554      * @param dArray An optionally preallocated double array
       
  1555      * @return the samples for the specified pixel.
       
  1556      *
       
  1557      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1558      * in bounds, or if dArray is too small to hold the output.
       
  1559      */
       
  1560     public double[] getPixel(int x, int y, double dArray[]) {
       
  1561         return sampleModel.getPixel(x - sampleModelTranslateX,
       
  1562                                     y - sampleModelTranslateY,
       
  1563                                     dArray, dataBuffer);
       
  1564     }
       
  1565 
       
  1566     /**
       
  1567      * Returns an int array containing all samples for a rectangle of pixels,
       
  1568      * one sample per array element.
       
  1569      * An ArrayIndexOutOfBoundsException may be thrown
       
  1570      * if the coordinates are not in bounds.  However, explicit bounds
       
  1571      * checking is not guaranteed.
       
  1572      * @param x      The X coordinate of the upper-left pixel location
       
  1573      * @param y      The Y coordinate of the upper-left pixel location
       
  1574      * @param w      Width of the pixel rectangle
       
  1575      * @param h      Height of the pixel rectangle
       
  1576      * @param iArray An optionally pre-allocated int array
       
  1577      * @return the samples for the specified rectangle of pixels.
       
  1578      *
       
  1579      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1580      * in bounds, or if iArray is too small to hold the output.
       
  1581      */
       
  1582     public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
       
  1583         return sampleModel.getPixels(x - sampleModelTranslateX,
       
  1584                                      y - sampleModelTranslateY, w, h,
       
  1585                                      iArray, dataBuffer);
       
  1586     }
       
  1587 
       
  1588     /**
       
  1589      * Returns a float array containing all samples for a rectangle of pixels,
       
  1590      * one sample per array element.
       
  1591      * An ArrayIndexOutOfBoundsException may be thrown
       
  1592      * if the coordinates are not in bounds.  However, explicit bounds
       
  1593      * checking is not guaranteed.
       
  1594      * @param x        The X coordinate of the pixel location
       
  1595      * @param y        The Y coordinate of the pixel location
       
  1596      * @param w        Width of the pixel rectangle
       
  1597      * @param h        Height of the pixel rectangle
       
  1598      * @param fArray   An optionally pre-allocated float array
       
  1599      * @return the samples for the specified rectangle of pixels.
       
  1600      *
       
  1601      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1602      * in bounds, or if fArray is too small to hold the output.
       
  1603      */
       
  1604     public float[] getPixels(int x, int y, int w, int h,
       
  1605                              float fArray[]) {
       
  1606         return sampleModel.getPixels(x - sampleModelTranslateX,
       
  1607                                      y - sampleModelTranslateY, w, h,
       
  1608                                      fArray, dataBuffer);
       
  1609     }
       
  1610 
       
  1611     /**
       
  1612      * Returns a double array containing all samples for a rectangle of pixels,
       
  1613      * one sample per array element.
       
  1614      * An ArrayIndexOutOfBoundsException may be thrown
       
  1615      * if the coordinates are not in bounds.  However, explicit bounds
       
  1616      * checking is not guaranteed.
       
  1617      * @param x        The X coordinate of the upper-left pixel location
       
  1618      * @param y        The Y coordinate of the upper-left pixel location
       
  1619      * @param w        Width of the pixel rectangle
       
  1620      * @param h        Height of the pixel rectangle
       
  1621      * @param dArray   An optionally pre-allocated double array
       
  1622      * @return the samples for the specified rectangle of pixels.
       
  1623      *
       
  1624      * @throws ArrayIndexOutOfBoundsException if the coordinates are not
       
  1625      * in bounds, or if dArray is too small to hold the output.
       
  1626      */
       
  1627     public double[] getPixels(int x, int y, int w, int h,
       
  1628                               double dArray[]) {
       
  1629         return sampleModel.getPixels(x - sampleModelTranslateX,
       
  1630                                      y - sampleModelTranslateY,
       
  1631                                      w, h, dArray, dataBuffer);
       
  1632     }
       
  1633 
       
  1634 
       
  1635     /**
       
  1636      * Returns the sample in a specified band for the pixel located
       
  1637      * at (x,y) as an int.
       
  1638      * An ArrayIndexOutOfBoundsException may be thrown
       
  1639      * if the coordinates are not in bounds.  However, explicit bounds
       
  1640      * checking is not guaranteed.
       
  1641      * @param x        The X coordinate of the pixel location
       
  1642      * @param y        The Y coordinate of the pixel location
       
  1643      * @param b        The band to return
       
  1644      * @return the sample in the specified band for the pixel at the
       
  1645      *         specified coordinate.
       
  1646      *
       
  1647      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1648      * the band index are not in bounds.
       
  1649      */
       
  1650     public int getSample(int x, int y, int b) {
       
  1651         return sampleModel.getSample(x - sampleModelTranslateX,
       
  1652                                      y - sampleModelTranslateY, b,
       
  1653                                      dataBuffer);
       
  1654     }
       
  1655 
       
  1656     /**
       
  1657      * Returns the sample in a specified band
       
  1658      * for the pixel located at (x,y) as a float.
       
  1659      * An ArrayIndexOutOfBoundsException may be thrown
       
  1660      * if the coordinates are not in bounds.  However, explicit bounds
       
  1661      * checking is not guaranteed.
       
  1662      * @param x        The X coordinate of the pixel location
       
  1663      * @param y        The Y coordinate of the pixel location
       
  1664      * @param b        The band to return
       
  1665      * @return the sample in the specified band for the pixel at the
       
  1666      *         specified coordinate.
       
  1667      *
       
  1668      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1669      * the band index are not in bounds.
       
  1670      */
       
  1671     public float getSampleFloat(int x, int y, int b) {
       
  1672         return sampleModel.getSampleFloat(x - sampleModelTranslateX,
       
  1673                                           y - sampleModelTranslateY, b,
       
  1674                                           dataBuffer);
       
  1675     }
       
  1676 
       
  1677     /**
       
  1678      * Returns the sample in a specified band
       
  1679      * for a pixel located at (x,y) as a double.
       
  1680      * An ArrayIndexOutOfBoundsException may be thrown
       
  1681      * if the coordinates are not in bounds.  However, explicit bounds
       
  1682      * checking is not guaranteed.
       
  1683      * @param x        The X coordinate of the pixel location
       
  1684      * @param y        The Y coordinate of the pixel location
       
  1685      * @param b        The band to return
       
  1686      * @return the sample in the specified band for the pixel at the
       
  1687      *         specified coordinate.
       
  1688      *
       
  1689      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1690      * the band index are not in bounds.
       
  1691      */
       
  1692     public double getSampleDouble(int x, int y, int b) {
       
  1693         return sampleModel.getSampleDouble(x - sampleModelTranslateX,
       
  1694                                            y - sampleModelTranslateY,
       
  1695                                            b, dataBuffer);
       
  1696     }
       
  1697 
       
  1698     /**
       
  1699      * Returns the samples for a specified band for the specified rectangle
       
  1700      * of pixels in an int array, one sample per array element.
       
  1701      * An ArrayIndexOutOfBoundsException may be thrown
       
  1702      * if the coordinates are not in bounds.  However, explicit bounds
       
  1703      * checking is not guaranteed.
       
  1704      * @param x        The X coordinate of the upper-left pixel location
       
  1705      * @param y        The Y coordinate of the upper-left pixel location
       
  1706      * @param w        Width of the pixel rectangle
       
  1707      * @param h        Height of the pixel rectangle
       
  1708      * @param b        The band to return
       
  1709      * @param iArray   An optionally pre-allocated int array
       
  1710      * @return the samples for the specified band for the specified
       
  1711      *         rectangle of pixels.
       
  1712      *
       
  1713      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1714      * the band index are not in bounds, or if iArray is too small to
       
  1715      * hold the output.
       
  1716      */
       
  1717     public int[] getSamples(int x, int y, int w, int h, int b,
       
  1718                             int iArray[]) {
       
  1719         return sampleModel.getSamples(x - sampleModelTranslateX,
       
  1720                                       y - sampleModelTranslateY,
       
  1721                                       w, h, b, iArray,
       
  1722                                       dataBuffer);
       
  1723     }
       
  1724 
       
  1725     /**
       
  1726      * Returns the samples for a specified band for the specified rectangle
       
  1727      * of pixels in a float array, one sample per array element.
       
  1728      * An ArrayIndexOutOfBoundsException may be thrown
       
  1729      * if the coordinates are not in bounds.  However, explicit bounds
       
  1730      * checking is not guaranteed.
       
  1731      * @param x        The X coordinate of the upper-left pixel location
       
  1732      * @param y        The Y coordinate of the upper-left pixel location
       
  1733      * @param w        Width of the pixel rectangle
       
  1734      * @param h        Height of the pixel rectangle
       
  1735      * @param b        The band to return
       
  1736      * @param fArray   An optionally pre-allocated float array
       
  1737      * @return the samples for the specified band for the specified
       
  1738      *         rectangle of pixels.
       
  1739      *
       
  1740      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1741      * the band index are not in bounds, or if fArray is too small to
       
  1742      * hold the output.
       
  1743      */
       
  1744     public float[] getSamples(int x, int y, int w, int h, int b,
       
  1745                               float fArray[]) {
       
  1746         return sampleModel.getSamples(x - sampleModelTranslateX,
       
  1747                                       y - sampleModelTranslateY,
       
  1748                                       w, h, b, fArray, dataBuffer);
       
  1749     }
       
  1750 
       
  1751     /**
       
  1752      * Returns the samples for a specified band for a specified rectangle
       
  1753      * of pixels in a double array, one sample per array element.
       
  1754      * An ArrayIndexOutOfBoundsException may be thrown
       
  1755      * if the coordinates are not in bounds.  However, explicit bounds
       
  1756      * checking is not guaranteed.
       
  1757      * @param x        The X coordinate of the upper-left pixel location
       
  1758      * @param y        The Y coordinate of the upper-left pixel location
       
  1759      * @param w        Width of the pixel rectangle
       
  1760      * @param h        Height of the pixel rectangle
       
  1761      * @param b        The band to return
       
  1762      * @param dArray   An optionally pre-allocated double array
       
  1763      * @return the samples for the specified band for the specified
       
  1764      *         rectangle of pixels.
       
  1765      *
       
  1766      * @throws ArrayIndexOutOfBoundsException if the coordinates or
       
  1767      * the band index are not in bounds, or if dArray is too small to
       
  1768      * hold the output.
       
  1769      */
       
  1770     public double[] getSamples(int x, int y, int w, int h, int b,
       
  1771                                double dArray[]) {
       
  1772          return sampleModel.getSamples(x - sampleModelTranslateX,
       
  1773                                        y - sampleModelTranslateY,
       
  1774                                        w, h, b, dArray, dataBuffer);
       
  1775     }
       
  1776 
       
  1777 }