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

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