Home » openjdk-7 » java » awt » image » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   /* ****************************************************************
   27    ******************************************************************
   28    ******************************************************************
   29    *** COPYRIGHT (c) Eastman Kodak Company, 1997
   30    *** As  an unpublished  work pursuant to Title 17 of the United
   31    *** States Code.  All rights reserved.
   32    ******************************************************************
   33    ******************************************************************
   34    ******************************************************************/
   35   
   36   package java.awt.image;
   37   
   38   import java.util.Arrays;
   39   
   40   /**
   41    *  This class represents image data which is stored such that each sample
   42    *  of a pixel occupies one data element of the DataBuffer.  It stores the
   43    *  N samples which make up a pixel in N separate data array elements.
   44    *  Different bands may be in different banks of the DataBuffer.
   45    *  Accessor methods are provided so that image data can be manipulated
   46    *  directly. This class can support different kinds of interleaving, e.g.
   47    *  band interleaving, scanline interleaving, and pixel interleaving.
   48    *  Pixel stride is the number of data array elements between two samples
   49    *  for the same band on the same scanline. Scanline stride is the number
   50    *  of data array elements between a given sample and the corresponding sample
   51    *  in the same column of the next scanline.  Band offsets denote the number
   52    *  of data array elements from the first data array element of the bank
   53    *  of the DataBuffer holding each band to the first sample of the band.
   54    *  The bands are numbered from 0 to N-1.  This class can represent image
   55    *  data for which each sample is an unsigned integral number which can be
   56    *  stored in 8, 16, or 32 bits (using <code>DataBuffer.TYPE_BYTE</code>,
   57    *  <code>DataBuffer.TYPE_USHORT</code>, or <code>DataBuffer.TYPE_INT</code>,
   58    *  respectively), data for which each sample is a signed integral number
   59    *  which can be stored in 16 bits (using <code>DataBuffer.TYPE_SHORT</code>),
   60    *  or data for which each sample is a signed float or double quantity
   61    *  (using <code>DataBuffer.TYPE_FLOAT</code> or
   62    *  <code>DataBuffer.TYPE_DOUBLE</code>, respectively).
   63    *  All samples of a given ComponentSampleModel
   64    *  are stored with the same precision.  All strides and offsets must be
   65    *  non-negative.  This class supports
   66    *  {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
   67    *  {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
   68    *  {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
   69    *  {@link DataBuffer#TYPE_INT TYPE_INT},
   70    *  {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT},
   71    *  {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE},
   72    *  @see java.awt.image.PixelInterleavedSampleModel
   73    *  @see java.awt.image.BandedSampleModel
   74    */
   75   
   76   public class ComponentSampleModel extends SampleModel
   77   {
   78       /** Offsets for all bands in data array elements. */
   79       protected int bandOffsets[];
   80   
   81       /** Index for each bank storing a band of image data. */
   82       protected int[] bankIndices;
   83   
   84       /**
   85        * The number of bands in this
   86        * <code>ComponentSampleModel</code>.
   87        */
   88       protected int numBands = 1;
   89   
   90       /**
   91        * The number of banks in this
   92        * <code>ComponentSampleModel</code>.
   93        */
   94       protected int numBanks = 1;
   95   
   96       /**
   97        *  Line stride (in data array elements) of the region of image
   98        *  data described by this ComponentSampleModel.
   99        */
  100       protected int scanlineStride;
  101   
  102       /** Pixel stride (in data array elements) of the region of image
  103        *  data described by this ComponentSampleModel.
  104        */
  105       protected int pixelStride;
  106   
  107       static private native void initIDs();
  108       static {
  109           ColorModel.loadLibraries();
  110           initIDs();
  111       }
  112   
  113       /**
  114        * Constructs a ComponentSampleModel with the specified parameters.
  115        * The number of bands will be given by the length of the bandOffsets array.
  116        * All bands will be stored in the first bank of the DataBuffer.
  117        * @param dataType  the data type for storing samples
  118        * @param w         the width (in pixels) of the region of
  119        *     image data described
  120        * @param h         the height (in pixels) of the region of
  121        *     image data described
  122        * @param pixelStride the pixel stride of the region of image
  123        *     data described
  124        * @param scanlineStride the line stride of the region of image
  125        *     data described
  126        * @param bandOffsets the offsets of all bands
  127        * @throws IllegalArgumentException if <code>w</code> or
  128        *         <code>h</code> is not greater than 0
  129        * @throws IllegalArgumentException if <code>pixelStride</code>
  130        *         is less than 0
  131        * @throws IllegalArgumentException if <code>scanlineStride</code>
  132        *         is less than 0
  133        * @throws IllegalArgumentException if <code>numBands</code>
  134        *         is less than 1
  135        * @throws IllegalArgumentException if the product of <code>w</code>
  136        *         and <code>h</code> is greater than
  137        *         <code>Integer.MAX_VALUE</code>
  138        * @throws IllegalArgumentException if <code>dataType</code> is not
  139        *         one of the supported data types
  140        */
  141       public ComponentSampleModel(int dataType,
  142                                   int w, int h,
  143                                   int pixelStride,
  144                                   int scanlineStride,
  145                                   int bandOffsets[]) {
  146           super(dataType, w, h, bandOffsets.length);
  147           this.dataType = dataType;
  148           this.pixelStride = pixelStride;
  149           this.scanlineStride  = scanlineStride;
  150           this.bandOffsets = (int[])bandOffsets.clone();
  151           numBands = bandOffsets.length;
  152           if (pixelStride < 0) {
  153               throw new IllegalArgumentException("Pixel stride must be >= 0");
  154           }
  155           // TODO - bug 4296691 - remove this check
  156           if (scanlineStride < 0) {
  157               throw new IllegalArgumentException("Scanline stride must be >= 0");
  158           }
  159           if (numBands < 1) {
  160               throw new IllegalArgumentException("Must have at least one band.");
  161           }
  162           if ((dataType < DataBuffer.TYPE_BYTE) ||
  163               (dataType > DataBuffer.TYPE_DOUBLE)) {
  164               throw new IllegalArgumentException("Unsupported dataType.");
  165           }
  166           bankIndices = new int[numBands];
  167           for (int i=0; i<numBands; i++) {
  168               bankIndices[i] = 0;
  169           }
  170       }
  171   
  172   
  173       /**
  174        * Constructs a ComponentSampleModel with the specified parameters.
  175        * The number of bands will be given by the length of the bandOffsets array.
  176        * Different bands may be stored in different banks of the DataBuffer.
  177        *
  178        * @param dataType  the data type for storing samples
  179        * @param w         the width (in pixels) of the region of
  180        *     image data described
  181        * @param h         the height (in pixels) of the region of
  182        *     image data described
  183        * @param pixelStride the pixel stride of the region of image
  184        *     data described
  185        * @param scanlineStride The line stride of the region of image
  186        *     data described
  187        * @param bankIndices the bank indices of all bands
  188        * @param bandOffsets the band offsets of all bands
  189        * @throws IllegalArgumentException if <code>w</code> or
  190        *         <code>h</code> is not greater than 0
  191        * @throws IllegalArgumentException if <code>pixelStride</code>
  192        *         is less than 0
  193        * @throws IllegalArgumentException if <code>scanlineStride</code>
  194        *         is less than 0
  195        * @throws IllegalArgumentException if the length of
  196        *         <code>bankIndices</code> does not equal the length of
  197        *         <code>bankOffsets</code>
  198        * @throws IllegalArgumentException if any of the bank indices
  199        *         of <code>bandIndices</code> is less than 0
  200        * @throws IllegalArgumentException if <code>dataType</code> is not
  201        *         one of the supported data types
  202        */
  203       public ComponentSampleModel(int dataType,
  204                                   int w, int h,
  205                                   int pixelStride,
  206                                   int scanlineStride,
  207                                   int bankIndices[],
  208                                   int bandOffsets[]) {
  209           super(dataType, w, h, bandOffsets.length);
  210           this.dataType = dataType;
  211           this.pixelStride = pixelStride;
  212           this.scanlineStride  = scanlineStride;
  213           this.bandOffsets = (int[])bandOffsets.clone();
  214           this.bankIndices = (int[]) bankIndices.clone();
  215           if (pixelStride < 0) {
  216               throw new IllegalArgumentException("Pixel stride must be >= 0");
  217           }
  218           // TODO - bug 4296691 - remove this check
  219           if (scanlineStride < 0) {
  220               throw new IllegalArgumentException("Scanline stride must be >= 0");
  221           }
  222           if ((dataType < DataBuffer.TYPE_BYTE) ||
  223               (dataType > DataBuffer.TYPE_DOUBLE)) {
  224               throw new IllegalArgumentException("Unsupported dataType.");
  225           }
  226           int maxBank = bankIndices[0];
  227           if (maxBank < 0) {
  228               throw new IllegalArgumentException("Index of bank 0 is less than "+
  229                                                  "0 ("+maxBank+")");
  230           }
  231           for (int i=1; i < bankIndices.length; i++) {
  232               if (bankIndices[i] > maxBank) {
  233                   maxBank = bankIndices[i];
  234               }
  235               else if (bankIndices[i] < 0) {
  236                   throw new IllegalArgumentException("Index of bank "+i+
  237                                                      " is less than 0 ("+
  238                                                      maxBank+")");
  239               }
  240           }
  241           numBanks         = maxBank+1;
  242           numBands         = bandOffsets.length;
  243           if (bandOffsets.length != bankIndices.length) {
  244               throw new IllegalArgumentException("Length of bandOffsets must "+
  245                                                  "equal length of bankIndices.");
  246           }
  247       }
  248   
  249       /**
  250        * Returns the size of the data buffer (in data elements) needed
  251        * for a data buffer that matches this ComponentSampleModel.
  252        */
  253        private long getBufferSize() {
  254            int maxBandOff=bandOffsets[0];
  255            for (int i=1; i<bandOffsets.length; i++)
  256                maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  257   
  258            long size = 0;
  259            if (maxBandOff >= 0)
  260                size += maxBandOff+1;
  261            if (pixelStride > 0)
  262                size += pixelStride * (width-1);
  263            if (scanlineStride > 0)
  264                size += scanlineStride*(height-1);
  265            return size;
  266        }
  267   
  268        /**
  269         * Preserves band ordering with new step factor...
  270         */
  271       int []orderBands(int orig[], int step) {
  272           int map[] = new int[orig.length];
  273           int ret[] = new int[orig.length];
  274   
  275           for (int i=0; i<map.length; i++) map[i] = i;
  276   
  277           for (int i = 0; i < ret.length; i++) {
  278               int index = i;
  279               for (int j = i+1; j < ret.length; j++) {
  280                   if (orig[map[index]] > orig[map[j]]) {
  281                       index = j;
  282                   }
  283               }
  284               ret[map[index]] = i*step;
  285               map[index]  = map[i];
  286           }
  287           return ret;
  288       }
  289   
  290       /**
  291        * Creates a new <code>ComponentSampleModel</code> with the specified
  292        * width and height.  The new <code>SampleModel</code> will have the same
  293        * number of bands, storage data type, interleaving scheme, and
  294        * pixel stride as this <code>SampleModel</code>.
  295        * @param w the width of the resulting <code>SampleModel</code>
  296        * @param h the height of the resulting <code>SampleModel</code>
  297        * @return a new <code>ComponentSampleModel</code> with the specified size
  298        * @throws IllegalArgumentException if <code>w</code> or
  299        *         <code>h</code> is not greater than 0
  300        */
  301       public SampleModel createCompatibleSampleModel(int w, int h) {
  302           SampleModel ret=null;
  303           long size;
  304           int minBandOff=bandOffsets[0];
  305           int maxBandOff=bandOffsets[0];
  306           for (int i=1; i<bandOffsets.length; i++) {
  307               minBandOff = Math.min(minBandOff,bandOffsets[i]);
  308               maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  309           }
  310           maxBandOff -= minBandOff;
  311   
  312           int bands   = bandOffsets.length;
  313           int bandOff[];
  314           int pStride = Math.abs(pixelStride);
  315           int lStride = Math.abs(scanlineStride);
  316           int bStride = Math.abs(maxBandOff);
  317   
  318           if (pStride > lStride) {
  319               if (pStride > bStride) {
  320                   if (lStride > bStride) { // pix > line > band
  321                       bandOff = new int[bandOffsets.length];
  322                       for (int i=0; i<bands; i++)
  323                           bandOff[i] = bandOffsets[i]-minBandOff;
  324                       lStride = bStride+1;
  325                       pStride = lStride*h;
  326                   } else { // pix > band > line
  327                       bandOff = orderBands(bandOffsets,lStride*h);
  328                       pStride = bands*lStride*h;
  329                   }
  330               } else { // band > pix > line
  331                   pStride = lStride*h;
  332                   bandOff = orderBands(bandOffsets,pStride*w);
  333               }
  334           } else {
  335               if (pStride > bStride) { // line > pix > band
  336                   bandOff = new int[bandOffsets.length];
  337                   for (int i=0; i<bands; i++)
  338                       bandOff[i] = bandOffsets[i]-minBandOff;
  339                   pStride = bStride+1;
  340                   lStride = pStride*w;
  341               } else {
  342                   if (lStride > bStride) { // line > band > pix
  343                       bandOff = orderBands(bandOffsets,pStride*w);
  344                       lStride = bands*pStride*w;
  345                   } else { // band > line > pix
  346                       lStride = pStride*w;
  347                       bandOff = orderBands(bandOffsets,lStride*h);
  348                   }
  349               }
  350           }
  351   
  352           // make sure we make room for negative offsets...
  353           int base = 0;
  354           if (scanlineStride < 0) {
  355               base += lStride*h;
  356               lStride *= -1;
  357           }
  358           if (pixelStride    < 0) {
  359               base += pStride*w;
  360               pStride *= -1;
  361           }
  362   
  363           for (int i=0; i<bands; i++)
  364               bandOff[i] += base;
  365           return new ComponentSampleModel(dataType, w, h, pStride,
  366                                           lStride, bankIndices, bandOff);
  367       }
  368   
  369       /**
  370        * Creates a new ComponentSampleModel with a subset of the bands
  371        * of this ComponentSampleModel.  The new ComponentSampleModel can be
  372        * used with any DataBuffer that the existing ComponentSampleModel
  373        * can be used with.  The new ComponentSampleModel/DataBuffer
  374        * combination will represent an image with a subset of the bands
  375        * of the original ComponentSampleModel/DataBuffer combination.
  376        * @param bands a subset of bands from this
  377        *              <code>ComponentSampleModel</code>
  378        * @return a <code>ComponentSampleModel</code> created with a subset
  379        *          of bands from this <code>ComponentSampleModel</code>.
  380        */
  381       public SampleModel createSubsetSampleModel(int bands[]) {
  382          if (bands.length > bankIndices.length)
  383               throw new RasterFormatException("There are only " +
  384                                               bankIndices.length +
  385                                               " bands");
  386           int newBankIndices[] = new int[bands.length];
  387           int newBandOffsets[] = new int[bands.length];
  388   
  389           for (int i=0; i<bands.length; i++) {
  390               newBankIndices[i] = bankIndices[bands[i]];
  391               newBandOffsets[i] = bandOffsets[bands[i]];
  392           }
  393   
  394           return new ComponentSampleModel(this.dataType, width, height,
  395                                           this.pixelStride,
  396                                           this.scanlineStride,
  397                                           newBankIndices, newBandOffsets);
  398       }
  399   
  400       /**
  401        * Creates a <code>DataBuffer</code> that corresponds to this
  402        * <code>ComponentSampleModel</code>.
  403        * The <code>DataBuffer</code> object's data type, number of banks,
  404        * and size are be consistent with this <code>ComponentSampleModel</code>.
  405        * @return a <code>DataBuffer</code> whose data type, number of banks
  406        *         and size are consistent with this
  407        *         <code>ComponentSampleModel</code>.
  408        */
  409       public DataBuffer createDataBuffer() {
  410           DataBuffer dataBuffer = null;
  411   
  412           int size = (int)getBufferSize();
  413           switch (dataType) {
  414           case DataBuffer.TYPE_BYTE:
  415               dataBuffer = new DataBufferByte(size, numBanks);
  416               break;
  417           case DataBuffer.TYPE_USHORT:
  418               dataBuffer = new DataBufferUShort(size, numBanks);
  419               break;
  420           case DataBuffer.TYPE_SHORT:
  421               dataBuffer = new DataBufferShort(size, numBanks);
  422               break;
  423           case DataBuffer.TYPE_INT:
  424               dataBuffer = new DataBufferInt(size, numBanks);
  425               break;
  426           case DataBuffer.TYPE_FLOAT:
  427               dataBuffer = new DataBufferFloat(size, numBanks);
  428               break;
  429           case DataBuffer.TYPE_DOUBLE:
  430               dataBuffer = new DataBufferDouble(size, numBanks);
  431               break;
  432           }
  433   
  434           return dataBuffer;
  435       }
  436   
  437   
  438       /** Gets the offset for the first band of pixel (x,y).
  439        *  A sample of the first band can be retrieved from a
  440        * <code>DataBuffer</code>
  441        *  <code>data</code> with a <code>ComponentSampleModel</code>
  442        * <code>csm</code> as
  443        * <pre>
  444        *        data.getElem(csm.getOffset(x, y));
  445        * </pre>
  446        * @param x the X location of the pixel
  447        * @param y the Y location of the pixel
  448        * @return the offset for the first band of the specified pixel.
  449        */
  450       public int getOffset(int x, int y) {
  451           int offset = y*scanlineStride + x*pixelStride + bandOffsets[0];
  452           return offset;
  453       }
  454   
  455       /** Gets the offset for band b of pixel (x,y).
  456        *  A sample of band <code>b</code> can be retrieved from a
  457        *  <code>DataBuffer</code> <code>data</code>
  458        *  with a <code>ComponentSampleModel</code> <code>csm</code> as
  459        * <pre>
  460        *       data.getElem(csm.getOffset(x, y, b));
  461        * </pre>
  462        * @param x the X location of the specified pixel
  463        * @param y the Y location of the specified pixel
  464        * @param b the specified band
  465        * @return the offset for the specified band of the specified pixel.
  466        */
  467       public int getOffset(int x, int y, int b) {
  468           int offset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  469           return offset;
  470       }
  471   
  472       /** Returns the number of bits per sample for all bands.
  473        *  @return an array containing the number of bits per sample
  474        *          for all bands, where each element in the array
  475        *          represents a band.
  476        */
  477       public final int[] getSampleSize() {
  478           int sampleSize[] = new int [numBands];
  479           int sizeInBits = getSampleSize(0);
  480   
  481           for (int i=0; i<numBands; i++)
  482               sampleSize[i] = sizeInBits;
  483   
  484           return sampleSize;
  485       }
  486   
  487       /** Returns the number of bits per sample for the specified band.
  488        *  @param band the specified band
  489        *  @return the number of bits per sample for the specified band.
  490        */
  491       public final int getSampleSize(int band) {
  492           return DataBuffer.getDataTypeSize(dataType);
  493       }
  494   
  495       /** Returns the bank indices for all bands.
  496        *  @return the bank indices for all bands.
  497        */
  498       public final int [] getBankIndices() {
  499           return (int[]) bankIndices.clone();
  500       }
  501   
  502       /** Returns the band offset for all bands.
  503        *  @return the band offsets for all bands.
  504        */
  505       public final int [] getBandOffsets() {
  506           return (int[])bandOffsets.clone();
  507       }
  508   
  509       /** Returns the scanline stride of this ComponentSampleModel.
  510        *  @return the scanline stride of this <code>ComponentSampleModel</code>.
  511        */
  512       public final int getScanlineStride() {
  513           return scanlineStride;
  514       }
  515   
  516       /** Returns the pixel stride of this ComponentSampleModel.
  517        *  @return the pixel stride of this <code>ComponentSampleModel</code>.
  518        */
  519       public final int getPixelStride() {
  520           return pixelStride;
  521       }
  522   
  523       /**
  524        * Returns the number of data elements needed to transfer a pixel
  525        * with the
  526        * {@link #getDataElements(int, int, Object, DataBuffer) } and
  527        * {@link #setDataElements(int, int, Object, DataBuffer) }
  528        * methods.
  529        * For a <code>ComponentSampleModel</code>, this is identical to the
  530        * number of bands.
  531        * @return the number of data elements needed to transfer a pixel with
  532        *         the <code>getDataElements</code> and
  533        *         <code>setDataElements</code> methods.
  534        * @see java.awt.image.SampleModel#getNumDataElements
  535        * @see #getNumBands
  536        */
  537       public final int getNumDataElements() {
  538           return getNumBands();
  539       }
  540   
  541       /**
  542        * Returns data for a single pixel in a primitive array of type
  543        * <code>TransferType</code>.  For a <code>ComponentSampleModel</code>,
  544        * this is the same as the data type, and samples are returned
  545        * one per array element.  Generally, <code>obj</code> should
  546        * be passed in as <code>null</code>, so that the <code>Object</code>
  547        * is created automatically and is the right primitive data type.
  548        * <p>
  549        * The following code illustrates transferring data for one pixel from
  550        * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
  551        * described by <code>ComponentSampleModel</code> <code>csm1</code>,
  552        * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
  553        * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
  554        * The transfer is usually more efficient than using
  555        * <code>getPixel</code> and <code>setPixel</code>.
  556        * <pre>
  557        *       ComponentSampleModel csm1, csm2;
  558        *       DataBufferInt db1, db2;
  559        *       csm2.setDataElements(x, y,
  560        *                            csm1.getDataElements(x, y, null, db1), db2);
  561        * </pre>
  562        *
  563        * Using <code>getDataElements</code> and <code>setDataElements</code>
  564        * to transfer between two <code>DataBuffer/SampleModel</code>
  565        * pairs is legitimate if the <code>SampleModel</code> objects have
  566        * the same number of bands, corresponding bands have the same number of
  567        * bits per sample, and the <code>TransferType</code>s are the same.
  568        * <p>
  569        * If <code>obj</code> is not <code>null</code>, it should be a
  570        * primitive array of type <code>TransferType</code>.
  571        * Otherwise, a <code>ClassCastException</code> is thrown.  An
  572        * <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
  573        * coordinates are not in bounds, or if <code>obj</code> is not
  574        * <code>null</code> and is not large enough to hold
  575        * the pixel data.
  576        *
  577        * @param x         the X coordinate of the pixel location
  578        * @param y         the Y coordinate of the pixel location
  579        * @param obj       if non-<code>null</code>, a primitive array
  580        *                  in which to return the pixel data
  581        * @param data      the <code>DataBuffer</code> containing the image data
  582        * @return the data of the specified pixel
  583        * @see #setDataElements(int, int, Object, DataBuffer)
  584        *
  585        * @throws NullPointerException if data is null.
  586        * @throws ArrayIndexOutOfBoundsException if the coordinates are
  587        * not in bounds, or if obj is too small to hold the ouput.
  588        */
  589       public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
  590           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  591               throw new ArrayIndexOutOfBoundsException
  592                   ("Coordinate out of bounds!");
  593           }
  594   
  595           int type = getTransferType();
  596           int numDataElems = getNumDataElements();
  597           int pixelOffset = y*scanlineStride + x*pixelStride;
  598   
  599           switch(type) {
  600   
  601           case DataBuffer.TYPE_BYTE:
  602   
  603               byte[] bdata;
  604   
  605               if (obj == null)
  606                   bdata = new byte[numDataElems];
  607               else
  608                   bdata = (byte[])obj;
  609   
  610               for (int i=0; i<numDataElems; i++) {
  611                   bdata[i] = (byte)data.getElem(bankIndices[i],
  612                                                 pixelOffset + bandOffsets[i]);
  613               }
  614   
  615               obj = (Object)bdata;
  616               break;
  617   
  618           case DataBuffer.TYPE_USHORT:
  619           case DataBuffer.TYPE_SHORT:
  620   
  621               short[] sdata;
  622   
  623               if (obj == null)
  624                   sdata = new short[numDataElems];
  625               else
  626                   sdata = (short[])obj;
  627   
  628               for (int i=0; i<numDataElems; i++) {
  629                   sdata[i] = (short)data.getElem(bankIndices[i],
  630                                                  pixelOffset + bandOffsets[i]);
  631               }
  632   
  633               obj = (Object)sdata;
  634               break;
  635   
  636           case DataBuffer.TYPE_INT:
  637   
  638               int[] idata;
  639   
  640               if (obj == null)
  641                   idata = new int[numDataElems];
  642               else
  643                   idata = (int[])obj;
  644   
  645               for (int i=0; i<numDataElems; i++) {
  646                   idata[i] = data.getElem(bankIndices[i],
  647                                           pixelOffset + bandOffsets[i]);
  648               }
  649   
  650               obj = (Object)idata;
  651               break;
  652   
  653           case DataBuffer.TYPE_FLOAT:
  654   
  655               float[] fdata;
  656   
  657               if (obj == null)
  658                   fdata = new float[numDataElems];
  659               else
  660                   fdata = (float[])obj;
  661   
  662               for (int i=0; i<numDataElems; i++) {
  663                   fdata[i] = data.getElemFloat(bankIndices[i],
  664                                                pixelOffset + bandOffsets[i]);
  665               }
  666   
  667               obj = (Object)fdata;
  668               break;
  669   
  670           case DataBuffer.TYPE_DOUBLE:
  671   
  672               double[] ddata;
  673   
  674               if (obj == null)
  675                   ddata = new double[numDataElems];
  676               else
  677                   ddata = (double[])obj;
  678   
  679               for (int i=0; i<numDataElems; i++) {
  680                   ddata[i] = data.getElemDouble(bankIndices[i],
  681                                                 pixelOffset + bandOffsets[i]);
  682               }
  683   
  684               obj = (Object)ddata;
  685               break;
  686           }
  687   
  688           return obj;
  689       }
  690   
  691       /**
  692        * Returns all samples for the specified pixel in an int array,
  693        * one sample per array element.
  694        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  695        * the coordinates are not in bounds.
  696        * @param x         the X coordinate of the pixel location
  697        * @param y         the Y coordinate of the pixel location
  698        * @param iArray    If non-null, returns the samples in this array
  699        * @param data      The DataBuffer containing the image data
  700        * @return the samples of the specified pixel.
  701        * @see #setPixel(int, int, int[], DataBuffer)
  702        *
  703        * @throws NullPointerException if data is null.
  704        * @throws ArrayIndexOutOfBoundsException if the coordinates are
  705        * not in bounds, or if iArray is too small to hold the output.
  706        */
  707       public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  708           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  709               throw new ArrayIndexOutOfBoundsException
  710                   ("Coordinate out of bounds!");
  711           }
  712           int pixels[];
  713           if (iArray != null) {
  714              pixels = iArray;
  715           } else {
  716              pixels = new int [numBands];
  717           }
  718           int pixelOffset = y*scanlineStride + x*pixelStride;
  719           for (int i=0; i<numBands; i++) {
  720               pixels[i] = data.getElem(bankIndices[i],
  721                                        pixelOffset + bandOffsets[i]);
  722           }
  723           return pixels;
  724       }
  725   
  726       /**
  727        * Returns all samples for the specified rectangle of pixels in
  728        * an int array, one sample per array element.
  729        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  730        * the coordinates are not in bounds.
  731        * @param x         The X coordinate of the upper left pixel location
  732        * @param y         The Y coordinate of the upper left pixel location
  733        * @param w         The width of the pixel rectangle
  734        * @param h         The height of the pixel rectangle
  735        * @param iArray    If non-null, returns the samples in this array
  736        * @param data      The DataBuffer containing the image data
  737        * @return the samples of the pixels within the specified region.
  738        * @see #setPixels(int, int, int, int, int[], DataBuffer)
  739        */
  740       public int[] getPixels(int x, int y, int w, int h,
  741                              int iArray[], DataBuffer data) {
  742           int x1 = x + w;
  743           int y1 = y + h;
  744   
  745           if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
  746               y < 0 || y >= height || y > height || y1 < 0 || y1 >  height)
  747           {
  748               throw new ArrayIndexOutOfBoundsException
  749                   ("Coordinate out of bounds!");
  750           }
  751           int pixels[];
  752           if (iArray != null) {
  753              pixels = iArray;
  754           } else {
  755              pixels = new int [w*h*numBands];
  756           }
  757           int lineOffset = y*scanlineStride + x*pixelStride;
  758           int srcOffset = 0;
  759   
  760           for (int i = 0; i < h; i++) {
  761              int pixelOffset = lineOffset;
  762              for (int j = 0; j < w; j++) {
  763                 for (int k=0; k < numBands; k++) {
  764                    pixels[srcOffset++] =
  765                       data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]);
  766                 }
  767                 pixelOffset += pixelStride;
  768              }
  769              lineOffset += scanlineStride;
  770           }
  771           return pixels;
  772       }
  773   
  774       /**
  775        * Returns as int the sample in a specified band for the pixel
  776        * located at (x,y).
  777        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  778        * the coordinates are not in bounds.
  779        * @param x         the X coordinate of the pixel location
  780        * @param y         the Y coordinate of the pixel location
  781        * @param b         the band to return
  782        * @param data      the <code>DataBuffer</code> containing the image data
  783        * @return the sample in a specified band for the specified pixel
  784        * @see #setSample(int, int, int, int, DataBuffer)
  785        */
  786       public int getSample(int x, int y, int b, DataBuffer data) {
  787           // Bounds check for 'b' will be performed automatically
  788           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  789               throw new ArrayIndexOutOfBoundsException
  790                   ("Coordinate out of bounds!");
  791           }
  792           int sample = data.getElem(bankIndices[b],
  793                                     y*scanlineStride + x*pixelStride +
  794                                     bandOffsets[b]);
  795           return sample;
  796       }
  797   
  798       /**
  799        * Returns the sample in a specified band
  800        * for the pixel located at (x,y) as a float.
  801        * An <code>ArrayIndexOutOfBoundsException</code> might be
  802        * thrown if the coordinates are not in bounds.
  803        * @param x         The X coordinate of the pixel location
  804        * @param y         The Y coordinate of the pixel location
  805        * @param b         The band to return
  806        * @param data      The DataBuffer containing the image data
  807        * @return a float value representing the sample in the specified
  808        * band for the specified pixel.
  809        */
  810       public float getSampleFloat(int x, int y, int b, DataBuffer data) {
  811           // Bounds check for 'b' will be performed automatically
  812           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  813               throw new ArrayIndexOutOfBoundsException
  814                   ("Coordinate out of bounds!");
  815           }
  816   
  817           float sample = data.getElemFloat(bankIndices[b],
  818                                            y*scanlineStride + x*pixelStride +
  819                                            bandOffsets[b]);
  820           return sample;
  821       }
  822   
  823       /**
  824        * Returns the sample in a specified band
  825        * for a pixel located at (x,y) as a double.
  826        * An <code>ArrayIndexOutOfBoundsException</code> might be
  827        * thrown if the coordinates are not in bounds.
  828        * @param x         The X coordinate of the pixel location
  829        * @param y         The Y coordinate of the pixel location
  830        * @param b         The band to return
  831        * @param data      The DataBuffer containing the image data
  832        * @return a double value representing the sample in the specified
  833        * band for the specified pixel.
  834        */
  835       public double getSampleDouble(int x, int y, int b, DataBuffer data) {
  836           // Bounds check for 'b' will be performed automatically
  837           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  838               throw new ArrayIndexOutOfBoundsException
  839                   ("Coordinate out of bounds!");
  840           }
  841   
  842           double sample = data.getElemDouble(bankIndices[b],
  843                                              y*scanlineStride + x*pixelStride +
  844                                              bandOffsets[b]);
  845           return sample;
  846       }
  847   
  848       /**
  849        * Returns the samples in a specified band for the specified rectangle
  850        * of pixels in an int array, one sample per data array element.
  851        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  852        * the coordinates are not in bounds.
  853        * @param x         The X coordinate of the upper left pixel location
  854        * @param y         The Y coordinate of the upper left pixel location
  855        * @param w         the width of the pixel rectangle
  856        * @param h         the height of the pixel rectangle
  857        * @param b         the band to return
  858        * @param iArray    if non-<code>null</code>, returns the samples
  859        *                  in this array
  860        * @param data      the <code>DataBuffer</code> containing the image data
  861        * @return the samples in the specified band of the specified pixel
  862        * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
  863        */
  864       public int[] getSamples(int x, int y, int w, int h, int b,
  865                               int iArray[], DataBuffer data) {
  866           // Bounds check for 'b' will be performed automatically
  867           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
  868               throw new ArrayIndexOutOfBoundsException
  869                   ("Coordinate out of bounds!");
  870           }
  871           int samples[];
  872           if (iArray != null) {
  873              samples = iArray;
  874           } else {
  875              samples = new int [w*h];
  876           }
  877           int lineOffset = y*scanlineStride + x*pixelStride +  bandOffsets[b];
  878           int srcOffset = 0;
  879   
  880           for (int i = 0; i < h; i++) {
  881              int sampleOffset = lineOffset;
  882              for (int j = 0; j < w; j++) {
  883                 samples[srcOffset++] = data.getElem(bankIndices[b],
  884                                                     sampleOffset);
  885                 sampleOffset += pixelStride;
  886              }
  887              lineOffset += scanlineStride;
  888           }
  889           return samples;
  890       }
  891   
  892       /**
  893        * Sets the data for a single pixel in the specified
  894        * <code>DataBuffer</code> from a primitive array of type
  895        * <code>TransferType</code>.  For a <code>ComponentSampleModel</code>,
  896        * this is the same as the data type, and samples are transferred
  897        * one per array element.
  898        * <p>
  899        * The following code illustrates transferring data for one pixel from
  900        * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
  901        * described by <code>ComponentSampleModel</code> <code>csm1</code>,
  902        * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
  903        * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
  904        * The transfer is usually more efficient than using
  905        * <code>getPixel</code> and <code>setPixel</code>.
  906        * <pre>
  907        *       ComponentSampleModel csm1, csm2;
  908        *       DataBufferInt db1, db2;
  909        *       csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
  910        *                            db2);
  911        * </pre>
  912        * Using <code>getDataElements</code> and <code>setDataElements</code>
  913        * to transfer between two <code>DataBuffer/SampleModel</code> pairs
  914        * is legitimate if the <code>SampleModel</code> objects have
  915        * the same number of bands, corresponding bands have the same number of
  916        * bits per sample, and the <code>TransferType</code>s are the same.
  917        * <p>
  918        * A <code>ClassCastException</code> is thrown if <code>obj</code> is not
  919        * a primitive array of type <code>TransferType</code>.
  920        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  921        * the coordinates are not in bounds, or if <code>obj</code> is not large
  922        * enough to hold the pixel data.
  923        * @param x         the X coordinate of the pixel location
  924        * @param y         the Y coordinate of the pixel location
  925        * @param obj       a primitive array containing pixel data
  926        * @param data      the DataBuffer containing the image data
  927        * @see #getDataElements(int, int, Object, DataBuffer)
  928        */
  929       public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  930           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  931               throw new ArrayIndexOutOfBoundsException
  932                   ("Coordinate out of bounds!");
  933           }
  934   
  935           int type = getTransferType();
  936           int numDataElems = getNumDataElements();
  937           int pixelOffset = y*scanlineStride + x*pixelStride;
  938   
  939           switch(type) {
  940   
  941           case DataBuffer.TYPE_BYTE:
  942   
  943               byte[] barray = (byte[])obj;
  944   
  945               for (int i=0; i<numDataElems; i++) {
  946                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  947                              ((int)barray[i])&0xff);
  948               }
  949               break;
  950   
  951           case DataBuffer.TYPE_USHORT:
  952           case DataBuffer.TYPE_SHORT:
  953   
  954               short[] sarray = (short[])obj;
  955   
  956               for (int i=0; i<numDataElems; i++) {
  957                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  958                              ((int)sarray[i])&0xffff);
  959               }
  960               break;
  961   
  962           case DataBuffer.TYPE_INT:
  963   
  964               int[] iarray = (int[])obj;
  965   
  966               for (int i=0; i<numDataElems; i++) {
  967                   data.setElem(bankIndices[i],
  968                                pixelOffset + bandOffsets[i], iarray[i]);
  969               }
  970               break;
  971   
  972           case DataBuffer.TYPE_FLOAT:
  973   
  974               float[] farray = (float[])obj;
  975   
  976               for (int i=0; i<numDataElems; i++) {
  977                   data.setElemFloat(bankIndices[i],
  978                                pixelOffset + bandOffsets[i], farray[i]);
  979               }
  980               break;
  981   
  982           case DataBuffer.TYPE_DOUBLE:
  983   
  984               double[] darray = (double[])obj;
  985   
  986               for (int i=0; i<numDataElems; i++) {
  987                   data.setElemDouble(bankIndices[i],
  988                                pixelOffset + bandOffsets[i], darray[i]);
  989               }
  990               break;
  991   
  992           }
  993       }
  994   
  995       /**
  996        * Sets a pixel in the <code>DataBuffer</code> using an int array of
  997        * samples for input.  An <code>ArrayIndexOutOfBoundsException</code>
  998        * might be thrown if the coordinates are
  999        * not in bounds.
 1000        * @param x         The X coordinate of the pixel location
 1001        * @param y         The Y coordinate of the pixel location
 1002        * @param iArray    The input samples in an int array
 1003        * @param data      The DataBuffer containing the image data
 1004        * @see #getPixel(int, int, int[], DataBuffer)
 1005        */
 1006       public void setPixel(int x, int y, int iArray[], DataBuffer data) {
 1007           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1008               throw new ArrayIndexOutOfBoundsException
 1009                   ("Coordinate out of bounds!");
 1010           }
 1011          int pixelOffset = y*scanlineStride + x*pixelStride;
 1012          for (int i=0; i<numBands; i++) {
 1013              data.setElem(bankIndices[i],
 1014                           pixelOffset + bandOffsets[i],iArray[i]);
 1015          }
 1016       }
 1017   
 1018       /**
 1019        * Sets all samples for a rectangle of pixels from an int array containing
 1020        * one sample per array element.
 1021        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1022        * coordinates are not in bounds.
 1023        * @param x         The X coordinate of the upper left pixel location
 1024        * @param y         The Y coordinate of the upper left pixel location
 1025        * @param w         The width of the pixel rectangle
 1026        * @param h         The height of the pixel rectangle
 1027        * @param iArray    The input samples in an int array
 1028        * @param data      The DataBuffer containing the image data
 1029        * @see #getPixels(int, int, int, int, int[], DataBuffer)
 1030        */
 1031       public void setPixels(int x, int y, int w, int h,
 1032                             int iArray[], DataBuffer data) {
 1033           int x1 = x + w;
 1034           int y1 = y + h;
 1035   
 1036           if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
 1037               y < 0 || y >= height || h > height || y1 < 0 || y1 >  height)
 1038           {
 1039               throw new ArrayIndexOutOfBoundsException
 1040                   ("Coordinate out of bounds!");
 1041           }
 1042   
 1043           int lineOffset = y*scanlineStride + x*pixelStride;
 1044           int srcOffset = 0;
 1045   
 1046           for (int i = 0; i < h; i++) {
 1047              int pixelOffset = lineOffset;
 1048              for (int j = 0; j < w; j++) {
 1049                 for (int k=0; k < numBands; k++) {
 1050                    data.setElem(bankIndices[k], pixelOffset + bandOffsets[k],
 1051                                 iArray[srcOffset++]);
 1052                 }
 1053                 pixelOffset += pixelStride;
 1054              }
 1055              lineOffset += scanlineStride;
 1056           }
 1057       }
 1058   
 1059       /**
 1060        * Sets a sample in the specified band for the pixel located at (x,y)
 1061        * in the <code>DataBuffer</code> using an int for input.
 1062        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1063        * coordinates are not in bounds.
 1064        * @param x         The X coordinate of the pixel location
 1065        * @param y         The Y coordinate of the pixel location
 1066        * @param b         the band to set
 1067        * @param s         the input sample as an int
 1068        * @param data      the DataBuffer containing the image data
 1069        * @see #getSample(int, int, int, DataBuffer)
 1070        */
 1071       public void setSample(int x, int y, int b, int s,
 1072                             DataBuffer data) {
 1073           // Bounds check for 'b' will be performed automatically
 1074           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1075               throw new ArrayIndexOutOfBoundsException
 1076                   ("Coordinate out of bounds!");
 1077           }
 1078           data.setElem(bankIndices[b],
 1079                        y*scanlineStride + x*pixelStride + bandOffsets[b], s);
 1080       }
 1081   
 1082       /**
 1083        * Sets a sample in the specified band for the pixel located at (x,y)
 1084        * in the <code>DataBuffer</code> using a float for input.
 1085        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
 1086        * the coordinates are not in bounds.
 1087        * @param x         The X coordinate of the pixel location
 1088        * @param y         The Y coordinate of the pixel location
 1089        * @param b         The band to set
 1090        * @param s         The input sample as a float
 1091        * @param data      The DataBuffer containing the image data
 1092        * @see #getSample(int, int, int, DataBuffer)
 1093        */
 1094       public void setSample(int x, int y, int b,
 1095                             float s ,
 1096                             DataBuffer data) {
 1097           // Bounds check for 'b' will be performed automatically
 1098           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1099               throw new ArrayIndexOutOfBoundsException
 1100                   ("Coordinate out of bounds!");
 1101           }
 1102           data.setElemFloat(bankIndices[b],
 1103                             y*scanlineStride + x*pixelStride + bandOffsets[b],
 1104                             s);
 1105       }
 1106   
 1107       /**
 1108        * Sets a sample in the specified band for the pixel located at (x,y)
 1109        * in the <code>DataBuffer</code> using a double for input.
 1110        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
 1111        * the coordinates are not in bounds.
 1112        * @param x         The X coordinate of the pixel location
 1113        * @param y         The Y coordinate of the pixel location
 1114        * @param b         The band to set
 1115        * @param s         The input sample as a double
 1116        * @param data      The DataBuffer containing the image data
 1117        * @see #getSample(int, int, int, DataBuffer)
 1118        */
 1119       public void setSample(int x, int y, int b,
 1120                             double s,
 1121                             DataBuffer data) {
 1122           // Bounds check for 'b' will be performed automatically
 1123           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1124               throw new ArrayIndexOutOfBoundsException
 1125                   ("Coordinate out of bounds!");
 1126           }
 1127           data.setElemDouble(bankIndices[b],
 1128                             y*scanlineStride + x*pixelStride + bandOffsets[b],
 1129                             s);
 1130       }
 1131   
 1132       /**
 1133        * Sets the samples in the specified band for the specified rectangle
 1134        * of pixels from an int array containing one sample per data array element.
 1135        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1136        * coordinates are not in bounds.
 1137        * @param x         The X coordinate of the upper left pixel location
 1138        * @param y         The Y coordinate of the upper left pixel location
 1139        * @param w         The width of the pixel rectangle
 1140        * @param h         The height of the pixel rectangle
 1141        * @param b         The band to set
 1142        * @param iArray    The input samples in an int array
 1143        * @param data      The DataBuffer containing the image data
 1144        * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
 1145        */
 1146       public void setSamples(int x, int y, int w, int h, int b,
 1147                              int iArray[], DataBuffer data) {
 1148           // Bounds check for 'b' will be performed automatically
 1149           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
 1150               throw new ArrayIndexOutOfBoundsException
 1151                   ("Coordinate out of bounds!");
 1152           }
 1153           int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
 1154           int srcOffset = 0;
 1155   
 1156           for (int i = 0; i < h; i++) {
 1157              int sampleOffset = lineOffset;
 1158              for (int j = 0; j < w; j++) {
 1159                 data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]);
 1160                 sampleOffset += pixelStride;
 1161              }
 1162              lineOffset += scanlineStride;
 1163           }
 1164       }
 1165   
 1166       public boolean equals(Object o) {
 1167           if ((o == null) || !(o instanceof ComponentSampleModel)) {
 1168               return false;
 1169           }
 1170   
 1171           ComponentSampleModel that = (ComponentSampleModel)o;
 1172           return this.width == that.width &&
 1173               this.height == that.height &&
 1174               this.numBands == that.numBands &&
 1175               this.dataType == that.dataType &&
 1176               Arrays.equals(this.bandOffsets, that.bandOffsets) &&
 1177               Arrays.equals(this.bankIndices, that.bankIndices) &&
 1178               this.numBands == that.numBands &&
 1179               this.numBanks == that.numBanks &&
 1180               this.scanlineStride == that.scanlineStride &&
 1181               this.pixelStride == that.pixelStride;
 1182       }
 1183   
 1184       // If we implement equals() we must also implement hashCode
 1185       public int hashCode() {
 1186           int hash = 0;
 1187           hash = width;
 1188           hash <<= 8;
 1189           hash ^= height;
 1190           hash <<= 8;
 1191           hash ^= numBands;
 1192           hash <<= 8;
 1193           hash ^= dataType;
 1194           hash <<= 8;
 1195           for (int i = 0; i < bandOffsets.length; i++) {
 1196               hash ^= bandOffsets[i];
 1197               hash <<= 8;
 1198           }
 1199           for (int i = 0; i < bankIndices.length; i++) {
 1200               hash ^= bankIndices[i];
 1201               hash <<= 8;
 1202           }
 1203           hash ^= numBands;
 1204           hash <<= 8;
 1205           hash ^= numBanks;
 1206           hash <<= 8;
 1207           hash ^= scanlineStride;
 1208           hash <<= 8;
 1209           hash ^= pixelStride;
 1210           return hash;
 1211       }
 1212   }

Home » openjdk-7 » java » awt » image » [javadoc | source]