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   /**
   39    *  This class represents image data which is stored in a band interleaved
   40    *  fashion and for
   41    *  which each sample of a pixel occupies one data element of the DataBuffer.
   42    *  It subclasses ComponentSampleModel but provides a more efficent
   43    *  implementation for accessing band interleaved image data than is provided
   44    *  by ComponentSampleModel.  This class should typically be used when working
   45    *  with images which store sample data for each band in a different bank of the
   46    *  DataBuffer. Accessor methods are provided so that image data can be
   47    *  manipulated directly. Pixel stride is the number of
   48    *  data array elements between two samples for the same band on the same
   49    *  scanline. The pixel stride for a BandedSampleModel is one.
   50    *  Scanline stride is the number of data array elements between
   51    *  a given sample and the corresponding sample in the same column of the next
   52    *  scanline.  Band offsets denote the number
   53    *  of data array elements from the first data array element of the bank
   54    *  of the DataBuffer holding each band to the first sample of the band.
   55    *  The bands are numbered from 0 to N-1.
   56    *  Bank indices denote the correspondence between a bank of the data buffer
   57    *  and a band of image data.  This class supports
   58    *  {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
   59    *  {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
   60    *  {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
   61    *  {@link DataBuffer#TYPE_INT TYPE_INT},
   62    *  {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
   63    *  {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
   64    */
   65   
   66   
   67   public final class BandedSampleModel extends ComponentSampleModel
   68   {
   69   
   70       /**
   71        * Constructs a BandedSampleModel with the specified parameters.
   72        * The pixel stride will be one data element.  The scanline stride
   73        * will be the same as the width.  Each band will be stored in
   74        * a separate bank and all band offsets will be zero.
   75        * @param dataType  The data type for storing samples.
   76        * @param w         The width (in pixels) of the region of
   77        *                  image data described.
   78        * @param h         The height (in pixels) of the region of image
   79        *                  data described.
   80        * @param numBands  The number of bands for the image data.
   81        * @throws IllegalArgumentException if <code>dataType</code> is not
   82        *         one of the supported data types
   83        */
   84       public BandedSampleModel(int dataType, int w, int h, int numBands) {
   85           super(dataType, w, h, 1, w,
   86                 BandedSampleModel.createIndicesArray(numBands),
   87                 BandedSampleModel.createOffsetArray(numBands));
   88       }
   89   
   90       /**
   91        * Constructs a BandedSampleModel with the specified parameters.
   92        * The number of bands will be inferred from the lengths of the
   93        * bandOffsets bankIndices arrays, which must be equal.  The pixel
   94        * stride will be one data element.
   95        * @param dataType  The data type for storing samples.
   96        * @param w         The width (in pixels) of the region of
   97        *                  image data described.
   98        * @param h         The height (in pixels) of the region of
   99        *                  image data described.
  100        * @param scanlineStride The line stride of the of the image data.
  101        * @param bankIndices The bank index for each band.
  102        * @param bandOffsets The band offset for each band.
  103        * @throws IllegalArgumentException if <code>dataType</code> is not
  104        *         one of the supported data types
  105        */
  106       public BandedSampleModel(int dataType,
  107                                int w, int h,
  108                                int scanlineStride,
  109                                int bankIndices[],
  110                                int bandOffsets[]) {
  111   
  112           super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
  113       }
  114   
  115       /**
  116        * Creates a new BandedSampleModel with the specified
  117        * width and height.  The new BandedSampleModel will have the same
  118        * number of bands, storage data type, and bank indices
  119        * as this BandedSampleModel.  The band offsets will be compressed
  120        * such that the offset between bands will be w*pixelStride and
  121        * the minimum of all of the band offsets is zero.
  122        * @param w the width of the resulting <code>BandedSampleModel</code>
  123        * @param h the height of the resulting <code>BandedSampleModel</code>
  124        * @return a new <code>BandedSampleModel</code> with the specified
  125        *         width and height.
  126        * @throws IllegalArgumentException if <code>w</code> or
  127        *         <code>h</code> equals either
  128        *         <code>Integer.MAX_VALUE</code> or
  129        *         <code>Integer.MIN_VALUE</code>
  130        * @throws IllegalArgumentException if <code>dataType</code> is not
  131        *         one of the supported data types
  132        */
  133       public SampleModel createCompatibleSampleModel(int w, int h) {
  134           int[] bandOffs;
  135   
  136           if (numBanks == 1) {
  137               bandOffs = orderBands(bandOffsets, w*h);
  138           }
  139           else {
  140               bandOffs = new int[bandOffsets.length];
  141           }
  142   
  143           SampleModel sampleModel =
  144               new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
  145           return sampleModel;
  146       }
  147   
  148       /**
  149        * Creates a new BandedSampleModel with a subset of the bands of this
  150        * BandedSampleModel.  The new BandedSampleModel can be
  151        * used with any DataBuffer that the existing BandedSampleModel
  152        * can be used with.  The new BandedSampleModel/DataBuffer
  153        * combination will represent an image with a subset of the bands
  154        * of the original BandedSampleModel/DataBuffer combination.
  155        * @throws RasterFormatException if the number of bands is greater than
  156        *                               the number of banks in this sample model.
  157        * @throws IllegalArgumentException if <code>dataType</code> is not
  158        *         one of the supported data types
  159        */
  160       public SampleModel createSubsetSampleModel(int bands[]) {
  161           if (bands.length > bankIndices.length)
  162               throw new RasterFormatException("There are only " +
  163                                               bankIndices.length +
  164                                               " bands");
  165           int newBankIndices[] = new int[bands.length];
  166           int newBandOffsets[] = new int[bands.length];
  167   
  168           for (int i=0; i<bands.length; i++) {
  169               newBankIndices[i] = bankIndices[bands[i]];
  170               newBandOffsets[i] = bandOffsets[bands[i]];
  171           }
  172   
  173           return new BandedSampleModel(this.dataType, width, height,
  174                                        this.scanlineStride,
  175                                        newBankIndices, newBandOffsets);
  176       }
  177   
  178       /**
  179        * Creates a DataBuffer that corresponds to this BandedSampleModel,
  180        * The DataBuffer's data type, number of banks, and size
  181        * will be consistent with this BandedSampleModel.
  182        * @throws IllegalArgumentException if <code>dataType</code> is not
  183        *         one of the supported types.
  184        */
  185       public DataBuffer createDataBuffer() {
  186           DataBuffer dataBuffer = null;
  187   
  188           int size = scanlineStride * height;
  189           switch (dataType) {
  190           case DataBuffer.TYPE_BYTE:
  191               dataBuffer = new DataBufferByte(size, numBanks);
  192               break;
  193           case DataBuffer.TYPE_USHORT:
  194               dataBuffer = new DataBufferUShort(size, numBanks);
  195               break;
  196           case DataBuffer.TYPE_SHORT:
  197               dataBuffer = new DataBufferShort(size, numBanks);
  198               break;
  199           case DataBuffer.TYPE_INT:
  200               dataBuffer = new DataBufferInt(size, numBanks);
  201               break;
  202           case DataBuffer.TYPE_FLOAT:
  203               dataBuffer = new DataBufferFloat(size, numBanks);
  204               break;
  205           case DataBuffer.TYPE_DOUBLE:
  206               dataBuffer = new DataBufferDouble(size, numBanks);
  207               break;
  208           default:
  209               throw new IllegalArgumentException("dataType is not one " +
  210                   "of the supported types.");
  211           }
  212   
  213           return dataBuffer;
  214       }
  215   
  216   
  217       /**
  218        * Returns data for a single pixel in a primitive array of type
  219        * TransferType.  For a BandedSampleModel, this will be the same
  220        * as the data type, and samples will be returned one per array
  221        * element.  Generally, obj
  222        * should be passed in as null, so that the Object will be created
  223        * automatically and will be of the right primitive data type.
  224        * <p>
  225        * The following code illustrates transferring data for one pixel from
  226        * DataBuffer <code>db1</code>, whose storage layout is described by
  227        * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
  228        * whose storage layout is described by
  229        * BandedSampleModel <code>bsm2</code>.
  230        * The transfer will generally be more efficient than using
  231        * getPixel/setPixel.
  232        * <pre>
  233        *       BandedSampleModel bsm1, bsm2;
  234        *       DataBufferInt db1, db2;
  235        *       bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
  236        *                            db2);
  237        * </pre>
  238        * Using getDataElements/setDataElements to transfer between two
  239        * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
  240        * the same number of bands, corresponding bands have the same number of
  241        * bits per sample, and the TransferTypes are the same.
  242        * <p>
  243        * If obj is non-null, it should be a primitive array of type TransferType.
  244        * Otherwise, a ClassCastException is thrown.  An
  245        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  246        * not in bounds, or if obj is non-null and is not large enough to hold
  247        * the pixel data.
  248        * @param x         The X coordinate of the pixel location
  249        * @param y         The Y coordinate of the pixel location
  250        * @param obj       If non-null, a primitive array in which to return
  251        *                  the pixel data.
  252        * @param data      The DataBuffer containing the image data.
  253        * @return the data for the specified pixel.
  254        * @see #setDataElements(int, int, Object, DataBuffer)
  255        */
  256       public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
  257           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  258               throw new ArrayIndexOutOfBoundsException
  259                   ("Coordinate out of bounds!");
  260           }
  261           int type = getTransferType();
  262           int numDataElems = getNumDataElements();
  263           int pixelOffset = y*scanlineStride + x;
  264   
  265           switch(type) {
  266   
  267           case DataBuffer.TYPE_BYTE:
  268   
  269               byte[] bdata;
  270   
  271               if (obj == null) {
  272                   bdata = new byte[numDataElems];
  273               } else {
  274                   bdata = (byte[])obj;
  275               }
  276   
  277               for (int i=0; i<numDataElems; i++) {
  278                   bdata[i] = (byte)data.getElem(bankIndices[i],
  279                                                 pixelOffset + bandOffsets[i]);
  280               }
  281   
  282               obj = (Object)bdata;
  283               break;
  284   
  285           case DataBuffer.TYPE_USHORT:
  286           case DataBuffer.TYPE_SHORT:
  287   
  288               short[] sdata;
  289   
  290               if (obj == null) {
  291                   sdata = new short[numDataElems];
  292               } else {
  293                   sdata = (short[])obj;
  294               }
  295   
  296               for (int i=0; i<numDataElems; i++) {
  297                   sdata[i] = (short)data.getElem(bankIndices[i],
  298                                                  pixelOffset + bandOffsets[i]);
  299               }
  300   
  301               obj = (Object)sdata;
  302               break;
  303   
  304           case DataBuffer.TYPE_INT:
  305   
  306               int[] idata;
  307   
  308               if (obj == null) {
  309                   idata = new int[numDataElems];
  310               } else {
  311                   idata = (int[])obj;
  312               }
  313   
  314               for (int i=0; i<numDataElems; i++) {
  315                   idata[i] = data.getElem(bankIndices[i],
  316                                           pixelOffset + bandOffsets[i]);
  317               }
  318   
  319               obj = (Object)idata;
  320               break;
  321   
  322           case DataBuffer.TYPE_FLOAT:
  323   
  324               float[] fdata;
  325   
  326               if (obj == null) {
  327                   fdata = new float[numDataElems];
  328               } else {
  329                   fdata = (float[])obj;
  330               }
  331   
  332               for (int i=0; i<numDataElems; i++) {
  333                   fdata[i] = data.getElemFloat(bankIndices[i],
  334                                                pixelOffset + bandOffsets[i]);
  335               }
  336   
  337               obj = (Object)fdata;
  338               break;
  339   
  340           case DataBuffer.TYPE_DOUBLE:
  341   
  342               double[] ddata;
  343   
  344               if (obj == null) {
  345                   ddata = new double[numDataElems];
  346               } else {
  347                   ddata = (double[])obj;
  348               }
  349   
  350               for (int i=0; i<numDataElems; i++) {
  351                   ddata[i] = data.getElemDouble(bankIndices[i],
  352                                                 pixelOffset + bandOffsets[i]);
  353               }
  354   
  355               obj = (Object)ddata;
  356               break;
  357           }
  358   
  359           return obj;
  360       }
  361   
  362       /**
  363        * Returns all samples for the specified pixel in an int array.
  364        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  365        * not in bounds.
  366        * @param x         The X coordinate of the pixel location
  367        * @param y         The Y coordinate of the pixel location
  368        * @param iArray    If non-null, returns the samples in this array
  369        * @param data      The DataBuffer containing the image data
  370        * @return the samples for the specified pixel.
  371        * @see #setPixel(int, int, int[], DataBuffer)
  372        */
  373       public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  374           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  375               throw new ArrayIndexOutOfBoundsException
  376                   ("Coordinate out of bounds!");
  377           }
  378   
  379           int[] pixels;
  380   
  381           if (iArray != null) {
  382              pixels = iArray;
  383           } else {
  384              pixels = new int [numBands];
  385           }
  386   
  387           int pixelOffset = y*scanlineStride + x;
  388           for (int i=0; i<numBands; i++) {
  389               pixels[i] = data.getElem(bankIndices[i],
  390                                        pixelOffset + bandOffsets[i]);
  391           }
  392           return pixels;
  393       }
  394   
  395       /**
  396        * Returns all samples for the specified rectangle of pixels in
  397        * an int array, one sample per data array element.
  398        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  399        * not in bounds.
  400        * @param x         The X coordinate of the upper left pixel location
  401        * @param y         The Y coordinate of the upper left pixel location
  402        * @param w         The width of the pixel rectangle
  403        * @param h         The height of the pixel rectangle
  404        * @param iArray    If non-null, returns the samples in this array
  405        * @param data      The DataBuffer containing the image data
  406        * @return the samples for the pixels within the specified region.
  407        * @see #setPixels(int, int, int, int, int[], DataBuffer)
  408        */
  409       public int[] getPixels(int x, int y, int w, int h,
  410                              int iArray[], DataBuffer data) {
  411           int x1 = x + w;
  412           int y1 = y + h;
  413   
  414           if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
  415               y < 0 || y >= height || h > height || y1 < 0 || y1 >  height)
  416           {
  417               throw new ArrayIndexOutOfBoundsException
  418                   ("Coordinate out of bounds!");
  419           }
  420           int[] pixels;
  421   
  422           if (iArray != null) {
  423              pixels = iArray;
  424           } else {
  425              pixels = new int[w*h*numBands];
  426           }
  427   
  428           for (int k = 0; k < numBands; k++) {
  429               int lineOffset = y*scanlineStride + x + bandOffsets[k];
  430               int srcOffset = k;
  431               int bank = bankIndices[k];
  432   
  433               for (int i = 0; i < h; i++) {
  434                   int pixelOffset = lineOffset;
  435                   for (int j = 0; j < w; j++) {
  436                       pixels[srcOffset] = data.getElem(bank, pixelOffset++);
  437                       srcOffset += numBands;
  438                   }
  439                   lineOffset += scanlineStride;
  440               }
  441           }
  442           return pixels;
  443       }
  444   
  445       /**
  446        * Returns as int the sample in a specified band for the pixel
  447        * located at (x,y).
  448        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  449        * not in bounds.
  450        * @param x         The X coordinate of the pixel location
  451        * @param y         The Y coordinate of the pixel location
  452        * @param b         The band to return
  453        * @param data      The DataBuffer containing the image data
  454        * @return the sample in the specified band for the specified pixel.
  455        * @see #setSample(int, int, int, int, DataBuffer)
  456        */
  457       public int getSample(int x, int y, int b, DataBuffer data) {
  458           // Bounds check for 'b' will be performed automatically
  459           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  460               throw new ArrayIndexOutOfBoundsException
  461                   ("Coordinate out of bounds!");
  462           }
  463           int sample =
  464               data.getElem(bankIndices[b],
  465                            y*scanlineStride + x + bandOffsets[b]);
  466           return sample;
  467       }
  468   
  469       /**
  470        * Returns the sample in a specified band
  471        * for the pixel located at (x,y) as a float.
  472        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  473        * not in bounds.
  474        * @param x         The X coordinate of the pixel location
  475        * @param y         The Y coordinate of the pixel location
  476        * @param b         The band to return
  477        * @param data      The DataBuffer containing the image data
  478        * @return a float value that represents the sample in the specified
  479        * band for the specified pixel.
  480        */
  481       public float getSampleFloat(int x, int y, int b, DataBuffer data) {
  482           // Bounds check for 'b' will be performed automatically
  483           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  484               throw new ArrayIndexOutOfBoundsException
  485                   ("Coordinate out of bounds!");
  486           }
  487   
  488           float sample = data.getElemFloat(bankIndices[b],
  489                                       y*scanlineStride + x + bandOffsets[b]);
  490           return sample;
  491       }
  492   
  493       /**
  494        * Returns the sample in a specified band
  495        * for a pixel located at (x,y) as a double.
  496        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  497        * not in bounds.
  498        * @param x         The X coordinate of the pixel location
  499        * @param y         The Y coordinate of the pixel location
  500        * @param b         The band to return
  501        * @param data      The DataBuffer containing the image data
  502        * @return a double value that represents the sample in the specified
  503        * band for the specified pixel.
  504        */
  505       public double getSampleDouble(int x, int y, int b, DataBuffer data) {
  506           // Bounds check for 'b' will be performed automatically
  507           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  508               throw new ArrayIndexOutOfBoundsException
  509                   ("Coordinate out of bounds!");
  510           }
  511   
  512           double sample = data.getElemDouble(bankIndices[b],
  513                                          y*scanlineStride + x + bandOffsets[b]);
  514           return sample;
  515       }
  516   
  517       /**
  518        * Returns the samples in a specified band for the specified rectangle
  519        * of pixels in an int array, one sample per data array element.
  520        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  521        * not in bounds.
  522        * @param x         The X coordinate of the upper left pixel location
  523        * @param y         The Y coordinate of the upper left pixel location
  524        * @param w         The width of the pixel rectangle
  525        * @param h         The height of the pixel rectangle
  526        * @param b         The band to return
  527        * @param iArray    If non-null, returns the samples in this array
  528        * @param data      The DataBuffer containing the image data
  529        * @return the samples in the specified band for the pixels within
  530        * the specified region.
  531        * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
  532        */
  533       public int[] getSamples(int x, int y, int w, int h, int b,
  534                               int iArray[], DataBuffer data) {
  535           // Bounds check for 'b' will be performed automatically
  536           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
  537               throw new ArrayIndexOutOfBoundsException
  538                   ("Coordinate out of bounds!");
  539           }
  540           int samples[];
  541           if (iArray != null) {
  542              samples = iArray;
  543           } else {
  544              samples = new int [w*h];
  545           }
  546   
  547           int lineOffset = y*scanlineStride + x + bandOffsets[b];
  548           int srcOffset = 0;
  549           int bank = bankIndices[b];
  550   
  551           for (int i = 0; i < h; i++) {
  552              int sampleOffset = lineOffset;
  553              for (int j = 0; j < w; j++) {
  554                  samples[srcOffset++] = data.getElem(bank, sampleOffset++);
  555              }
  556              lineOffset += scanlineStride;
  557           }
  558           return samples;
  559       }
  560   
  561       /**
  562        * Sets the data for a single pixel in the specified DataBuffer from a
  563        * primitive array of type TransferType.  For a BandedSampleModel,
  564        * this will be the same as the data type, and samples are transferred
  565        * one per array element.
  566        * <p>
  567        * The following code illustrates transferring data for one pixel from
  568        * DataBuffer <code>db1</code>, whose storage layout is described by
  569        * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
  570        * whose storage layout is described by
  571        * BandedSampleModel <code>bsm2</code>.
  572        * The transfer will generally be more efficient than using
  573        * getPixel/setPixel.
  574        * <pre>
  575        *       BandedSampleModel bsm1, bsm2;
  576        *       DataBufferInt db1, db2;
  577        *       bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
  578        *                            db2);
  579        * </pre>
  580        * Using getDataElements/setDataElements to transfer between two
  581        * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
  582        * the same number of bands, corresponding bands have the same number of
  583        * bits per sample, and the TransferTypes are the same.
  584        * <p>
  585        * obj must be a primitive array of type TransferType.  Otherwise,
  586        * a ClassCastException is thrown.  An
  587        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  588        * not in bounds, or if obj is not large enough to hold the pixel data.
  589        * @param x         The X coordinate of the pixel location
  590        * @param y         The Y coordinate of the pixel location
  591        * @param obj       If non-null, returns the primitive array in this
  592        *                  object
  593        * @param data      The DataBuffer containing the image data
  594        * @see #getDataElements(int, int, Object, DataBuffer)
  595        */
  596       public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  597           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  598               throw new ArrayIndexOutOfBoundsException
  599                   ("Coordinate out of bounds!");
  600           }
  601           int type = getTransferType();
  602           int numDataElems = getNumDataElements();
  603           int pixelOffset = y*scanlineStride + x;
  604   
  605           switch(type) {
  606   
  607           case DataBuffer.TYPE_BYTE:
  608   
  609               byte[] barray = (byte[])obj;
  610   
  611               for (int i=0; i<numDataElems; i++) {
  612                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  613                                barray[i] & 0xff);
  614               }
  615               break;
  616   
  617           case DataBuffer.TYPE_USHORT:
  618           case DataBuffer.TYPE_SHORT:
  619   
  620               short[] sarray = (short[])obj;
  621   
  622               for (int i=0; i<numDataElems; i++) {
  623                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  624                                sarray[i] & 0xffff);
  625               }
  626               break;
  627   
  628           case DataBuffer.TYPE_INT:
  629   
  630               int[] iarray = (int[])obj;
  631   
  632               for (int i=0; i<numDataElems; i++) {
  633                   data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  634                                iarray[i]);
  635               }
  636               break;
  637   
  638           case DataBuffer.TYPE_FLOAT:
  639   
  640               float[] farray = (float[])obj;
  641   
  642               for (int i=0; i<numDataElems; i++) {
  643                   data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
  644                                     farray[i]);
  645               }
  646               break;
  647   
  648           case DataBuffer.TYPE_DOUBLE:
  649   
  650               double[] darray = (double[])obj;
  651   
  652               for (int i=0; i<numDataElems; i++) {
  653                   data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
  654                                      darray[i]);
  655               }
  656               break;
  657   
  658           }
  659       }
  660   
  661       /**
  662        * Sets a pixel in the DataBuffer using an int array of samples for input.
  663        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  664        * not in bounds.
  665        * @param x         The X coordinate of the pixel location
  666        * @param y         The Y coordinate of the pixel location
  667        * @param iArray    The input samples in an int array
  668        * @param data      The DataBuffer containing the image data
  669        * @see #getPixel(int, int, int[], DataBuffer)
  670        */
  671       public void setPixel(int x, int y, int iArray[], DataBuffer data) {
  672           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  673               throw new ArrayIndexOutOfBoundsException
  674                   ("Coordinate out of bounds!");
  675           }
  676          int pixelOffset = y*scanlineStride + x;
  677          for (int i=0; i<numBands; i++) {
  678              data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  679                           iArray[i]);
  680          }
  681       }
  682   
  683       /**
  684        * Sets all samples for a rectangle of pixels from an int array containing
  685        * one sample per array element.
  686        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  687        * not in bounds.
  688        * @param x         The X coordinate of the upper left pixel location
  689        * @param y         The Y coordinate of the upper left pixel location
  690        * @param w         The width of the pixel rectangle
  691        * @param h         The height of the pixel rectangle
  692        * @param iArray    The input samples in an int array
  693        * @param data      The DataBuffer containing the image data
  694        * @see #getPixels(int, int, int, int, int[], DataBuffer)
  695        */
  696       public void setPixels(int x, int y, int w, int h,
  697                             int iArray[], DataBuffer data) {
  698           int x1 = x + w;
  699           int y1 = y + h;
  700   
  701           if (x < 0 || x >= width || w > width || x1 < 0 || x1 > width ||
  702               y < 0 || y >= height || h > height || y1 < 0 || y1 >  height)
  703           {
  704               throw new ArrayIndexOutOfBoundsException
  705                   ("Coordinate out of bounds!");
  706           }
  707   
  708           for (int k = 0; k < numBands; k++) {
  709               int lineOffset = y*scanlineStride + x + bandOffsets[k];
  710               int srcOffset = k;
  711               int bank = bankIndices[k];
  712   
  713               for (int i = 0; i < h; i++) {
  714                   int pixelOffset = lineOffset;
  715                   for (int j = 0; j < w; j++) {
  716                       data.setElem(bank, pixelOffset++, iArray[srcOffset]);
  717                       srcOffset += numBands;
  718                   }
  719                   lineOffset += scanlineStride;
  720              }
  721           }
  722       }
  723   
  724       /**
  725        * Sets a sample in the specified band for the pixel located at (x,y)
  726        * in the DataBuffer using an int for input.
  727        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  728        * not in bounds.
  729        * @param x         The X coordinate of the pixel location
  730        * @param y         The Y coordinate of the pixel location
  731        * @param b         The band to set
  732        * @param s         The input sample as an int
  733        * @param data      The DataBuffer containing the image data
  734        * @see #getSample(int, int, int, DataBuffer)
  735        */
  736       public void setSample(int x, int y, int b, int s,
  737                             DataBuffer data) {
  738           // Bounds check for 'b' will be performed automatically
  739           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  740               throw new ArrayIndexOutOfBoundsException
  741                   ("Coordinate out of bounds!");
  742           }
  743           data.setElem(bankIndices[b],
  744                        y*scanlineStride + x + bandOffsets[b], s);
  745       }
  746   
  747       /**
  748        * Sets a sample in the specified band for the pixel located at (x,y)
  749        * in the DataBuffer using a float for input.
  750        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  751        * not in bounds.
  752        * @param x         The X coordinate of the pixel location
  753        * @param y         The Y coordinate of the pixel location
  754        * @param b         The band to set
  755        * @param s         The input sample as a float
  756        * @param data      The DataBuffer containing the image data
  757        * @see #getSample(int, int, int, DataBuffer)
  758        */
  759       public void setSample(int x, int y, int b,
  760                             float s ,
  761                             DataBuffer data) {
  762           // Bounds check for 'b' will be performed automatically
  763           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  764               throw new ArrayIndexOutOfBoundsException
  765                   ("Coordinate out of bounds!");
  766           }
  767           data.setElemFloat(bankIndices[b],
  768                             y*scanlineStride + x + bandOffsets[b], s);
  769       }
  770   
  771       /**
  772        * Sets a sample in the specified band for the pixel located at (x,y)
  773        * in the DataBuffer using a double for input.
  774        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  775        * not in bounds.
  776        * @param x         The X coordinate of the pixel location
  777        * @param y         The Y coordinate of the pixel location
  778        * @param b         The band to set
  779        * @param s         The input sample as a double
  780        * @param data      The DataBuffer containing the image data
  781        * @see #getSample(int, int, int, DataBuffer)
  782        */
  783       public void setSample(int x, int y, int b,
  784                             double s,
  785                             DataBuffer data) {
  786           // Bounds check for 'b' will be performed automatically
  787           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  788               throw new ArrayIndexOutOfBoundsException
  789                   ("Coordinate out of bounds!");
  790           }
  791           data.setElemDouble(bankIndices[b],
  792                             y*scanlineStride + x + bandOffsets[b], s);
  793       }
  794   
  795       /**
  796        * Sets the samples in the specified band for the specified rectangle
  797        * of pixels from an int array containing one sample per data array element.
  798        * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  799        * not in bounds.
  800        * @param x         The X coordinate of the upper left pixel location
  801        * @param y         The Y coordinate of the upper left pixel location
  802        * @param w         The width of the pixel rectangle
  803        * @param h         The height of the pixel rectangle
  804        * @param b         The band to set
  805        * @param iArray    The input sample array
  806        * @param data      The DataBuffer containing the image data
  807        * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
  808        */
  809       public void setSamples(int x, int y, int w, int h, int b,
  810                              int iArray[], DataBuffer data) {
  811           // Bounds check for 'b' will be performed automatically
  812           if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
  813               throw new ArrayIndexOutOfBoundsException
  814                   ("Coordinate out of bounds!");
  815           }
  816           int lineOffset = y*scanlineStride + x + bandOffsets[b];
  817           int srcOffset = 0;
  818           int bank = bankIndices[b];
  819   
  820           for (int i = 0; i < h; i++) {
  821              int sampleOffset = lineOffset;
  822              for (int j = 0; j < w; j++) {
  823                 data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
  824              }
  825              lineOffset += scanlineStride;
  826           }
  827       }
  828   
  829       private static int[] createOffsetArray(int numBands) {
  830           int[] bandOffsets = new int[numBands];
  831           for (int i=0; i < numBands; i++) {
  832               bandOffsets[i] = 0;
  833           }
  834           return bandOffsets;
  835       }
  836   
  837       private static int[] createIndicesArray(int numBands) {
  838           int[] bankIndices = new int[numBands];
  839           for (int i=0; i < numBands; i++) {
  840               bankIndices[i] = i;
  841           }
  842           return bankIndices;
  843       }
  844   
  845       // Differentiate hash code from other ComponentSampleModel subclasses
  846       public int hashCode() {
  847           return super.hashCode() ^ 0x2;
  848       }
  849   }

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