Save This Page
Home » openjdk-7 » java » awt » image » [javadoc | source]
    1   /*
    2    * Portions Copyright 1997-2006 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   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           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
  743               throw new ArrayIndexOutOfBoundsException
  744                   ("Coordinate out of bounds!");
  745           }
  746           int pixels[];
  747           if (iArray != null) {
  748              pixels = iArray;
  749           } else {
  750              pixels = new int [w*h*numBands];
  751           }
  752           int lineOffset = y*scanlineStride + x*pixelStride;
  753           int srcOffset = 0;
  754   
  755           for (int i = 0; i < h; i++) {
  756              int pixelOffset = lineOffset;
  757              for (int j = 0; j < w; j++) {
  758                 for (int k=0; k < numBands; k++) {
  759                    pixels[srcOffset++] =
  760                       data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]);
  761                 }
  762                 pixelOffset += pixelStride;
  763              }
  764              lineOffset += scanlineStride;
  765           }
  766           return pixels;
  767       }
  768   
  769       /**
  770        * Returns as int the sample in a specified band for the pixel
  771        * located at (x,y).
  772        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  773        * the coordinates are not in bounds.
  774        * @param x         the X coordinate of the pixel location
  775        * @param y         the Y coordinate of the pixel location
  776        * @param b         the band to return
  777        * @param data      the <code>DataBuffer</code> containing the image data
  778        * @return the sample in a specified band for the specified pixel
  779        * @see #setSample(int, int, int, int, DataBuffer)
  780        */
  781       public int getSample(int x, int y, int b, DataBuffer data) {
  782           // Bounds check for 'b' will be performed automatically
  783           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  784               throw new ArrayIndexOutOfBoundsException
  785                   ("Coordinate out of bounds!");
  786           }
  787           int sample = data.getElem(bankIndices[b],
  788                                     y*scanlineStride + x*pixelStride +
  789                                     bandOffsets[b]);
  790           return sample;
  791       }
  792   
  793       /**
  794        * Returns the sample in a specified band
  795        * for the pixel located at (x,y) as a float.
  796        * An <code>ArrayIndexOutOfBoundsException</code> might be
  797        * thrown if the coordinates are not in bounds.
  798        * @param x         The X coordinate of the pixel location
  799        * @param y         The Y coordinate of the pixel location
  800        * @param b         The band to return
  801        * @param data      The DataBuffer containing the image data
  802        * @return a float value representing the sample in the specified
  803        * band for the specified pixel.
  804        */
  805       public float getSampleFloat(int x, int y, int b, DataBuffer data) {
  806           // Bounds check for 'b' will be performed automatically
  807           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  808               throw new ArrayIndexOutOfBoundsException
  809                   ("Coordinate out of bounds!");
  810           }
  811   
  812           float sample = data.getElemFloat(bankIndices[b],
  813                                            y*scanlineStride + x*pixelStride +
  814                                            bandOffsets[b]);
  815           return sample;
  816       }
  817   
  818       /**
  819        * Returns the sample in a specified band
  820        * for a pixel located at (x,y) as a double.
  821        * An <code>ArrayIndexOutOfBoundsException</code> might be
  822        * thrown if the coordinates are not in bounds.
  823        * @param x         The X coordinate of the pixel location
  824        * @param y         The Y coordinate of the pixel location
  825        * @param b         The band to return
  826        * @param data      The DataBuffer containing the image data
  827        * @return a double value representing the sample in the specified
  828        * band for the specified pixel.
  829        */
  830       public double getSampleDouble(int x, int y, int b, DataBuffer data) {
  831           // Bounds check for 'b' will be performed automatically
  832           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  833               throw new ArrayIndexOutOfBoundsException
  834                   ("Coordinate out of bounds!");
  835           }
  836   
  837           double sample = data.getElemDouble(bankIndices[b],
  838                                              y*scanlineStride + x*pixelStride +
  839                                              bandOffsets[b]);
  840           return sample;
  841       }
  842   
  843       /**
  844        * Returns the samples in a specified band for the specified rectangle
  845        * of pixels in an int array, one sample per data array element.
  846        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  847        * the coordinates are not in bounds.
  848        * @param x         The X coordinate of the upper left pixel location
  849        * @param y         The Y coordinate of the upper left pixel location
  850        * @param w         the width of the pixel rectangle
  851        * @param h         the height of the pixel rectangle
  852        * @param b         the band to return
  853        * @param iArray    if non-<code>null</code>, returns the samples
  854        *                  in this array
  855        * @param data      the <code>DataBuffer</code> containing the image data
  856        * @return the samples in the specified band of the specified pixel
  857        * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
  858        */
  859       public int[] getSamples(int x, int y, int w, int h, int b,
  860                               int iArray[], DataBuffer data) {
  861           // Bounds check for 'b' will be performed automatically
  862           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
  863               throw new ArrayIndexOutOfBoundsException
  864                   ("Coordinate out of bounds!");
  865           }
  866           int samples[];
  867           if (iArray != null) {
  868              samples = iArray;
  869           } else {
  870              samples = new int [w*h];
  871           }
  872           int lineOffset = y*scanlineStride + x*pixelStride +  bandOffsets[b];
  873           int srcOffset = 0;
  874   
  875           for (int i = 0; i < h; i++) {
  876              int sampleOffset = lineOffset;
  877              for (int j = 0; j < w; j++) {
  878                 samples[srcOffset++] = data.getElem(bankIndices[b],
  879                                                     sampleOffset);
  880                 sampleOffset += pixelStride;
  881              }
  882              lineOffset += scanlineStride;
  883           }
  884           return samples;
  885       }
  886   
  887       /**
  888        * Sets the data for a single pixel in the specified
  889        * <code>DataBuffer</code> from a primitive array of type
  890        * <code>TransferType</code>.  For a <code>ComponentSampleModel</code>,
  891        * this is the same as the data type, and samples are transferred
  892        * one per array element.
  893        * <p>
  894        * The following code illustrates transferring data for one pixel from
  895        * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
  896        * described by <code>ComponentSampleModel</code> <code>csm1</code>,
  897        * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
  898        * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
  899        * The transfer is usually more efficient than using
  900        * <code>getPixel</code> and <code>setPixel</code>.
  901        * <pre>
  902        *       ComponentSampleModel csm1, csm2;
  903        *       DataBufferInt db1, db2;
  904        *       csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
  905        *                            db2);
  906        * </pre>
  907        * Using <code>getDataElements</code> and <code>setDataElements</code>
  908        * to transfer between two <code>DataBuffer/SampleModel</code> pairs
  909        * is legitimate if the <code>SampleModel</code> objects have
  910        * the same number of bands, corresponding bands have the same number of
  911        * bits per sample, and the <code>TransferType</code>s are the same.
  912        * <p>
  913        * A <code>ClassCastException</code> is thrown if <code>obj</code> is not
  914        * a primitive array of type <code>TransferType</code>.
  915        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
  916        * the coordinates are not in bounds, or if <code>obj</code> is not large
  917        * enough to hold the pixel data.
  918        * @param x         the X coordinate of the pixel location
  919        * @param y         the Y coordinate of the pixel location
  920        * @param obj       a primitive array containing pixel data
  921        * @param data      the DataBuffer containing the image data
  922        * @see #getDataElements(int, int, Object, DataBuffer)
  923        */
  924       public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  925           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  926               throw new ArrayIndexOutOfBoundsException
  927                   ("Coordinate out of bounds!");
  928           }
  929   
  930           int type = getTransferType();
  931           int numDataElems = getNumDataElements();
  932           int pixelOffset = y*scanlineStride + x*pixelStride;
  933   
  934           switch(type) {
  935   
  936           case DataBuffer.TYPE_BYTE:
  937   
  938               byte[] barray = (byte[])obj;
  939   
  940               for (int i=0; i<numDataElems; i++) {
  941                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  942                              ((int)barray[i])&0xff);
  943               }
  944               break;
  945   
  946           case DataBuffer.TYPE_USHORT:
  947           case DataBuffer.TYPE_SHORT:
  948   
  949               short[] sarray = (short[])obj;
  950   
  951               for (int i=0; i<numDataElems; i++) {
  952                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  953                              ((int)sarray[i])&0xffff);
  954               }
  955               break;
  956   
  957           case DataBuffer.TYPE_INT:
  958   
  959               int[] iarray = (int[])obj;
  960   
  961               for (int i=0; i<numDataElems; i++) {
  962                   data.setElem(bankIndices[i],
  963                                pixelOffset + bandOffsets[i], iarray[i]);
  964               }
  965               break;
  966   
  967           case DataBuffer.TYPE_FLOAT:
  968   
  969               float[] farray = (float[])obj;
  970   
  971               for (int i=0; i<numDataElems; i++) {
  972                   data.setElemFloat(bankIndices[i],
  973                                pixelOffset + bandOffsets[i], farray[i]);
  974               }
  975               break;
  976   
  977           case DataBuffer.TYPE_DOUBLE:
  978   
  979               double[] darray = (double[])obj;
  980   
  981               for (int i=0; i<numDataElems; i++) {
  982                   data.setElemDouble(bankIndices[i],
  983                                pixelOffset + bandOffsets[i], darray[i]);
  984               }
  985               break;
  986   
  987           }
  988       }
  989   
  990       /**
  991        * Sets a pixel in the <code>DataBuffer</code> using an int array of
  992        * samples for input.  An <code>ArrayIndexOutOfBoundsException</code>
  993        * might be thrown if the coordinates are
  994        * not in bounds.
  995        * @param x         The X coordinate of the pixel location
  996        * @param y         The Y coordinate of the pixel location
  997        * @param iArray    The input samples in an int array
  998        * @param data      The DataBuffer containing the image data
  999        * @see #getPixel(int, int, int[], DataBuffer)
 1000        */
 1001       public void setPixel(int x, int y, int iArray[], DataBuffer data) {
 1002           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1003               throw new ArrayIndexOutOfBoundsException
 1004                   ("Coordinate out of bounds!");
 1005           }
 1006          int pixelOffset = y*scanlineStride + x*pixelStride;
 1007          for (int i=0; i<numBands; i++) {
 1008              data.setElem(bankIndices[i],
 1009                           pixelOffset + bandOffsets[i],iArray[i]);
 1010          }
 1011       }
 1012   
 1013       /**
 1014        * Sets all samples for a rectangle of pixels from an int array containing
 1015        * one sample per array element.
 1016        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1017        * coordinates are not in bounds.
 1018        * @param x         The X coordinate of the upper left pixel location
 1019        * @param y         The Y coordinate of the upper left pixel location
 1020        * @param w         The width of the pixel rectangle
 1021        * @param h         The height of the pixel rectangle
 1022        * @param iArray    The input samples in an int array
 1023        * @param data      The DataBuffer containing the image data
 1024        * @see #getPixels(int, int, int, int, int[], DataBuffer)
 1025        */
 1026       public void setPixels(int x, int y, int w, int h,
 1027                             int iArray[], DataBuffer data) {
 1028           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
 1029               throw new ArrayIndexOutOfBoundsException
 1030                   ("Coordinate out of bounds!");
 1031           }
 1032   
 1033           int lineOffset = y*scanlineStride + x*pixelStride;
 1034           int srcOffset = 0;
 1035   
 1036           for (int i = 0; i < h; i++) {
 1037              int pixelOffset = lineOffset;
 1038              for (int j = 0; j < w; j++) {
 1039                 for (int k=0; k < numBands; k++) {
 1040                    data.setElem(bankIndices[k], pixelOffset + bandOffsets[k],
 1041                                 iArray[srcOffset++]);
 1042                 }
 1043                 pixelOffset += pixelStride;
 1044              }
 1045              lineOffset += scanlineStride;
 1046           }
 1047       }
 1048   
 1049       /**
 1050        * Sets a sample in the specified band for the pixel located at (x,y)
 1051        * in the <code>DataBuffer</code> using an int for input.
 1052        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1053        * coordinates are not in bounds.
 1054        * @param x         The X coordinate of the pixel location
 1055        * @param y         The Y coordinate of the pixel location
 1056        * @param b         the band to set
 1057        * @param s         the input sample as an int
 1058        * @param data      the DataBuffer containing the image data
 1059        * @see #getSample(int, int, int, DataBuffer)
 1060        */
 1061       public void setSample(int x, int y, int b, int s,
 1062                             DataBuffer data) {
 1063           // Bounds check for 'b' will be performed automatically
 1064           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1065               throw new ArrayIndexOutOfBoundsException
 1066                   ("Coordinate out of bounds!");
 1067           }
 1068           data.setElem(bankIndices[b],
 1069                        y*scanlineStride + x*pixelStride + bandOffsets[b], s);
 1070       }
 1071   
 1072       /**
 1073        * Sets a sample in the specified band for the pixel located at (x,y)
 1074        * in the <code>DataBuffer</code> using a float for input.
 1075        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
 1076        * the coordinates are not in bounds.
 1077        * @param x         The X coordinate of the pixel location
 1078        * @param y         The Y coordinate of the pixel location
 1079        * @param b         The band to set
 1080        * @param s         The input sample as a float
 1081        * @param data      The DataBuffer containing the image data
 1082        * @see #getSample(int, int, int, DataBuffer)
 1083        */
 1084       public void setSample(int x, int y, int b,
 1085                             float s ,
 1086                             DataBuffer data) {
 1087           // Bounds check for 'b' will be performed automatically
 1088           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1089               throw new ArrayIndexOutOfBoundsException
 1090                   ("Coordinate out of bounds!");
 1091           }
 1092           data.setElemFloat(bankIndices[b],
 1093                             y*scanlineStride + x*pixelStride + bandOffsets[b],
 1094                             s);
 1095       }
 1096   
 1097       /**
 1098        * Sets a sample in the specified band for the pixel located at (x,y)
 1099        * in the <code>DataBuffer</code> using a double for input.
 1100        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
 1101        * the coordinates are not in bounds.
 1102        * @param x         The X coordinate of the pixel location
 1103        * @param y         The Y coordinate of the pixel location
 1104        * @param b         The band to set
 1105        * @param s         The input sample as a double
 1106        * @param data      The DataBuffer containing the image data
 1107        * @see #getSample(int, int, int, DataBuffer)
 1108        */
 1109       public void setSample(int x, int y, int b,
 1110                             double s,
 1111                             DataBuffer data) {
 1112           // Bounds check for 'b' will be performed automatically
 1113           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
 1114               throw new ArrayIndexOutOfBoundsException
 1115                   ("Coordinate out of bounds!");
 1116           }
 1117           data.setElemDouble(bankIndices[b],
 1118                             y*scanlineStride + x*pixelStride + bandOffsets[b],
 1119                             s);
 1120       }
 1121   
 1122       /**
 1123        * Sets the samples in the specified band for the specified rectangle
 1124        * of pixels from an int array containing one sample per data array element.
 1125        * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
 1126        * coordinates are not in bounds.
 1127        * @param x         The X coordinate of the upper left pixel location
 1128        * @param y         The Y coordinate of the upper left pixel location
 1129        * @param w         The width of the pixel rectangle
 1130        * @param h         The height of the pixel rectangle
 1131        * @param b         The band to set
 1132        * @param iArray    The input samples in an int array
 1133        * @param data      The DataBuffer containing the image data
 1134        * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
 1135        */
 1136       public void setSamples(int x, int y, int w, int h, int b,
 1137                              int iArray[], DataBuffer data) {
 1138           // Bounds check for 'b' will be performed automatically
 1139           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
 1140               throw new ArrayIndexOutOfBoundsException
 1141                   ("Coordinate out of bounds!");
 1142           }
 1143           int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
 1144           int srcOffset = 0;
 1145   
 1146           for (int i = 0; i < h; i++) {
 1147              int sampleOffset = lineOffset;
 1148              for (int j = 0; j < w; j++) {
 1149                 data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]);
 1150                 sampleOffset += pixelStride;
 1151              }
 1152              lineOffset += scanlineStride;
 1153           }
 1154       }
 1155   
 1156       public boolean equals(Object o) {
 1157           if ((o == null) || !(o instanceof ComponentSampleModel)) {
 1158               return false;
 1159           }
 1160   
 1161           ComponentSampleModel that = (ComponentSampleModel)o;
 1162           return this.width == that.width &&
 1163               this.height == that.height &&
 1164               this.numBands == that.numBands &&
 1165               this.dataType == that.dataType &&
 1166               Arrays.equals(this.bandOffsets, that.bandOffsets) &&
 1167               Arrays.equals(this.bankIndices, that.bankIndices) &&
 1168               this.numBands == that.numBands &&
 1169               this.numBanks == that.numBanks &&
 1170               this.scanlineStride == that.scanlineStride &&
 1171               this.pixelStride == that.pixelStride;
 1172       }
 1173   
 1174       // If we implement equals() we must also implement hashCode
 1175       public int hashCode() {
 1176           int hash = 0;
 1177           hash = width;
 1178           hash <<= 8;
 1179           hash ^= height;
 1180           hash <<= 8;
 1181           hash ^= numBands;
 1182           hash <<= 8;
 1183           hash ^= dataType;
 1184           hash <<= 8;
 1185           for (int i = 0; i < bandOffsets.length; i++) {
 1186               hash ^= bandOffsets[i];
 1187               hash <<= 8;
 1188           }
 1189           for (int i = 0; i < bankIndices.length; i++) {
 1190               hash ^= bankIndices[i];
 1191               hash <<= 8;
 1192           }
 1193           hash ^= numBands;
 1194           hash <<= 8;
 1195           hash ^= numBanks;
 1196           hash <<= 8;
 1197           hash ^= scanlineStride;
 1198           hash <<= 8;
 1199           hash ^= pixelStride;
 1200           return hash;
 1201       }
 1202   }

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