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    * The <code>MultiPixelPackedSampleModel</code> class represents
   40    * one-banded images and can pack multiple one-sample
   41    * pixels into one data element.  Pixels are not allowed to span data elements.
   42    * The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
   43    * or DataBuffer.TYPE_INT.  Each pixel must be a power of 2 number of bits
   44    * and a power of 2 number of pixels must fit exactly in one data element.
   45    * Pixel bit stride is equal to the number of bits per pixel.  Scanline
   46    * stride is in data elements and the last several data elements might be
   47    * padded with unused pixels.  Data bit offset is the offset in bits from
   48    * the beginning of the {@link DataBuffer} to the first pixel and must be
   49    * a multiple of pixel bit stride.
   50    * <p>
   51    * The following code illustrates extracting the bits for pixel
   52    * <code>x,&nbsp;y</code> from <code>DataBuffer</code> <code>data</code>
   53    * and storing the pixel data in data elements of type
   54    * <code>dataType</code>:
   55    * <pre>
   56    *      int dataElementSize = DataBuffer.getDataTypeSize(dataType);
   57    *      int bitnum = dataBitOffset + x*pixelBitStride;
   58    *      int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
   59    *      int shift = dataElementSize - (bitnum & (dataElementSize-1))
   60    *                  - pixelBitStride;
   61    *      int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
   62    * </pre>
   63    */
   64   
   65   public class MultiPixelPackedSampleModel extends SampleModel
   66   {
   67       /** The number of bits from one pixel to the next. */
   68       int pixelBitStride;
   69   
   70       /** Bitmask that extracts the rightmost pixel of a data element. */
   71       int bitMask;
   72   
   73       /**
   74         * The number of pixels that fit in a data element.  Also used
   75         * as the number of bits per pixel.
   76         */
   77       int pixelsPerDataElement;
   78   
   79       /** The size of a data element in bits. */
   80       int dataElementSize;
   81   
   82       /** The bit offset into the data array where the first pixel begins.
   83        */
   84       int dataBitOffset;
   85   
   86       /** ScanlineStride of the data buffer described in data array elements. */
   87       int scanlineStride;
   88   
   89       /**
   90        * Constructs a <code>MultiPixelPackedSampleModel</code> with the
   91        * specified data type, width, height and number of bits per pixel.
   92        * @param dataType  the data type for storing samples
   93        * @param w         the width, in pixels, of the region of
   94        *                  image data described
   95        * @param h         the height, in pixels, of the region of
   96        *                  image data described
   97        * @param numberOfBits the number of bits per pixel
   98        * @throws IllegalArgumentException if <code>dataType</code> is not
   99        *         either <code>DataBuffer.TYPE_BYTE</code>,
  100        *         <code>DataBuffer.TYPE_USHORT</code>, or
  101        *         <code>DataBuffer.TYPE_INT</code>
  102        */
  103       public MultiPixelPackedSampleModel(int dataType,
  104                                          int w,
  105                                          int h,
  106                                          int numberOfBits) {
  107           this(dataType,w,h,
  108                numberOfBits,
  109               (w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
  110                   DataBuffer.getDataTypeSize(dataType),
  111                0);
  112           if (dataType != DataBuffer.TYPE_BYTE &&
  113               dataType != DataBuffer.TYPE_USHORT &&
  114               dataType != DataBuffer.TYPE_INT) {
  115               throw new IllegalArgumentException("Unsupported data type "+
  116                                                  dataType);
  117           }
  118       }
  119   
  120       /**
  121        * Constructs a <code>MultiPixelPackedSampleModel</code> with
  122        * specified data type, width, height, number of bits per pixel,
  123        * scanline stride and data bit offset.
  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 numberOfBits the number of bits per pixel
  130        * @param scanlineStride the line stride of the image data
  131        * @param dataBitOffset the data bit offset for the region of image
  132        *                  data described
  133        * @exception RasterFormatException if the number of bits per pixel
  134        *                  is not a power of 2 or if a power of 2 number of
  135        *                  pixels do not fit in one data element.
  136        * @throws IllegalArgumentException if <code>w</code> or
  137        *         <code>h</code> is not greater than 0
  138        * @throws IllegalArgumentException if <code>dataType</code> is not
  139        *         either <code>DataBuffer.TYPE_BYTE</code>,
  140        *         <code>DataBuffer.TYPE_USHORT</code>, or
  141        *         <code>DataBuffer.TYPE_INT</code>
  142        */
  143       public MultiPixelPackedSampleModel(int dataType, int w, int h,
  144                                          int numberOfBits,
  145                                          int scanlineStride,
  146                                          int dataBitOffset) {
  147           super(dataType, w, h, 1);
  148           if (dataType != DataBuffer.TYPE_BYTE &&
  149               dataType != DataBuffer.TYPE_USHORT &&
  150               dataType != DataBuffer.TYPE_INT) {
  151               throw new IllegalArgumentException("Unsupported data type "+
  152                                                  dataType);
  153           }
  154           this.dataType = dataType;
  155           this.pixelBitStride = numberOfBits;
  156           this.scanlineStride = scanlineStride;
  157           this.dataBitOffset = dataBitOffset;
  158           this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
  159           this.pixelsPerDataElement = dataElementSize/numberOfBits;
  160           if (pixelsPerDataElement*numberOfBits != dataElementSize) {
  161              throw new RasterFormatException("MultiPixelPackedSampleModel " +
  162                                                "does not allow pixels to " +
  163                                                "span data element boundaries");
  164           }
  165           this.bitMask = (1 << numberOfBits) - 1;
  166       }
  167   
  168   
  169       /**
  170        * Creates a new <code>MultiPixelPackedSampleModel</code> with the
  171        * specified width and height.  The new
  172        * <code>MultiPixelPackedSampleModel</code> has the
  173        * same storage data type and number of bits per pixel as this
  174        * <code>MultiPixelPackedSampleModel</code>.
  175        * @param w the specified width
  176        * @param h the specified height
  177        * @return a {@link SampleModel} with the specified width and height
  178        * and with the same storage data type and number of bits per pixel
  179        * as this <code>MultiPixelPackedSampleModel</code>.
  180        * @throws IllegalArgumentException if <code>w</code> or
  181        *         <code>h</code> is not greater than 0
  182        */
  183       public SampleModel createCompatibleSampleModel(int w, int h) {
  184         SampleModel sampleModel =
  185               new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
  186         return sampleModel;
  187       }
  188   
  189       /**
  190        * Creates a <code>DataBuffer</code> that corresponds to this
  191        * <code>MultiPixelPackedSampleModel</code>.  The
  192        * <code>DataBuffer</code> object's data type and size
  193        * is consistent with this <code>MultiPixelPackedSampleModel</code>.
  194        * The <code>DataBuffer</code> has a single bank.
  195        * @return a <code>DataBuffer</code> with the same data type and
  196        * size as this <code>MultiPixelPackedSampleModel</code>.
  197        */
  198       public DataBuffer createDataBuffer() {
  199           DataBuffer dataBuffer = null;
  200   
  201           int size = (int)scanlineStride*height;
  202           switch (dataType) {
  203           case DataBuffer.TYPE_BYTE:
  204               dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
  205               break;
  206           case DataBuffer.TYPE_USHORT:
  207               dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
  208               break;
  209           case DataBuffer.TYPE_INT:
  210               dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
  211               break;
  212           }
  213           return dataBuffer;
  214       }
  215   
  216       /**
  217        * Returns the number of data elements needed to transfer one pixel
  218        * via the {@link #getDataElements} and {@link #setDataElements}
  219        * methods.  For a <code>MultiPixelPackedSampleModel</code>, this is
  220        * one.
  221        * @return the number of data elements.
  222        */
  223       public int getNumDataElements() {
  224           return 1;
  225       }
  226   
  227       /**
  228        * Returns the number of bits per sample for all bands.
  229        * @return the number of bits per sample.
  230        */
  231       public int[] getSampleSize() {
  232           int sampleSize[] = {pixelBitStride};
  233           return sampleSize;
  234       }
  235   
  236       /**
  237        * Returns the number of bits per sample for the specified band.
  238        * @param band the specified band
  239        * @return the number of bits per sample for the specified band.
  240        */
  241       public int getSampleSize(int band) {
  242           return pixelBitStride;
  243       }
  244   
  245       /**
  246        * Returns the offset of pixel (x,&nbsp;y) in data array elements.
  247        * @param x the X coordinate of the specified pixel
  248        * @param y the Y coordinate of the specified pixel
  249        * @return the offset of the specified pixel.
  250        */
  251       public int getOffset(int x, int y) {
  252           int offset = y * scanlineStride;
  253           offset +=  (x*pixelBitStride+dataBitOffset)/dataElementSize;
  254           return offset;
  255       }
  256   
  257       /**
  258        *  Returns the offset, in bits, into the data element in which it is
  259        *  stored for the <code>x</code>th pixel of a scanline.
  260        *  This offset is the same for all scanlines.
  261        *  @param x the specified pixel
  262        *  @return the bit offset of the specified pixel.
  263        */
  264       public int getBitOffset(int x){
  265          return  (x*pixelBitStride+dataBitOffset)%dataElementSize;
  266       }
  267   
  268       /**
  269        * Returns the scanline stride.
  270        * @return the scanline stride of this
  271        * <code>MultiPixelPackedSampleModel</code>.
  272        */
  273       public int getScanlineStride() {
  274           return scanlineStride;
  275       }
  276   
  277       /**
  278        * Returns the pixel bit stride in bits.  This value is the same as
  279        * the number of bits per pixel.
  280        * @return the <code>pixelBitStride</code> of this
  281        * <code>MultiPixelPackedSampleModel</code>.
  282        */
  283       public int getPixelBitStride() {
  284           return pixelBitStride;
  285       }
  286   
  287       /**
  288        * Returns the data bit offset in bits.
  289        * @return the <code>dataBitOffset</code> of this
  290        * <code>MultiPixelPackedSampleModel</code>.
  291        */
  292       public int getDataBitOffset() {
  293           return dataBitOffset;
  294       }
  295   
  296       /**
  297        *  Returns the TransferType used to transfer pixels by way of the
  298        *  <code>getDataElements</code> and <code>setDataElements</code>
  299        *  methods. The TransferType might or might not be the same as the
  300        *  storage DataType.  The TransferType is one of
  301        *  DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
  302        *  or DataBuffer.TYPE_INT.
  303        *  @return the transfertype.
  304        */
  305       public int getTransferType() {
  306           if (pixelBitStride > 16)
  307               return DataBuffer.TYPE_INT;
  308           else if (pixelBitStride > 8)
  309               return DataBuffer.TYPE_USHORT;
  310           else
  311               return DataBuffer.TYPE_BYTE;
  312       }
  313   
  314       /**
  315        * Creates a new <code>MultiPixelPackedSampleModel</code> with a
  316        * subset of the bands of this
  317        * <code>MultiPixelPackedSampleModel</code>.  Since a
  318        * <code>MultiPixelPackedSampleModel</code> only has one band, the
  319        * bands argument must have a length of one and indicate the zeroth
  320        * band.
  321        * @param bands the specified bands
  322        * @return a new <code>SampleModel</code> with a subset of bands of
  323        * this <code>MultiPixelPackedSampleModel</code>.
  324        * @exception RasterFormatException if the number of bands requested
  325        * is not one.
  326        * @throws IllegalArgumentException if <code>w</code> or
  327        *         <code>h</code> is not greater than 0
  328        */
  329       public SampleModel createSubsetSampleModel(int bands[]) {
  330           if (bands != null) {
  331              if (bands.length != 1)
  332               throw new RasterFormatException("MultiPixelPackedSampleModel has "
  333                                               + "only one band.");
  334           }
  335           SampleModel sm = createCompatibleSampleModel(width, height);
  336           return sm;
  337       }
  338   
  339       /**
  340        * Returns as <code>int</code> the sample in a specified band for the
  341        * pixel located at (x,&nbsp;y).  An
  342        * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
  343        * coordinates are not in bounds.
  344        * @param x         the X coordinate of the specified pixel
  345        * @param y         the Y coordinate of the specified pixel
  346        * @param b         the band to return, which is assumed to be 0
  347        * @param data      the <code>DataBuffer</code> containing the image
  348        *                  data
  349        * @return the specified band containing the sample of the specified
  350        * pixel.
  351        * @exception ArrayIndexOutOfBoundException if the specified
  352        *          coordinates are not in bounds.
  353        * @see #setSample(int, int, int, int, DataBuffer)
  354        */
  355       public int getSample(int x, int y, int b, DataBuffer data) {
  356           // 'b' must be 0
  357           if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
  358               (b != 0)) {
  359               throw new ArrayIndexOutOfBoundsException
  360                   ("Coordinate out of bounds!");
  361           }
  362           int bitnum = dataBitOffset + x*pixelBitStride;
  363           int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
  364           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  365                       - pixelBitStride;
  366           return (element >> shift) & bitMask;
  367       }
  368   
  369       /**
  370        * Sets a sample in the specified band for the pixel located at
  371        * (x,&nbsp;y) in the <code>DataBuffer</code> using an
  372        * <code>int</code> for input.
  373        * An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
  374        * coordinates are not in bounds.
  375        * @param x the X coordinate of the specified pixel
  376        * @param y the Y coordinate of the specified pixel
  377        * @param b the band to return, which is assumed to be 0
  378        * @param s the input sample as an <code>int</code>
  379        * @param data the <code>DataBuffer</code> where image data is stored
  380        * @exception ArrayIndexOutOfBoundsException if the coordinates are
  381        * not in bounds.
  382        * @see #getSample(int, int, int, DataBuffer)
  383        */
  384       public void setSample(int x, int y, int b, int s,
  385                             DataBuffer data) {
  386           // 'b' must be 0
  387           if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
  388               (b != 0)) {
  389               throw new ArrayIndexOutOfBoundsException
  390                   ("Coordinate out of bounds!");
  391           }
  392           int bitnum = dataBitOffset + x * pixelBitStride;
  393           int index = y * scanlineStride + (bitnum / dataElementSize);
  394           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  395                       - pixelBitStride;
  396           int element = data.getElem(index);
  397           element &= ~(bitMask << shift);
  398           element |= (s & bitMask) << shift;
  399           data.setElem(index,element);
  400       }
  401   
  402       /**
  403        * Returns data for a single pixel in a primitive array of type
  404        * TransferType.  For a <code>MultiPixelPackedSampleModel</code>,
  405        * the array has one element, and the type is the smallest of
  406        * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
  407        * that can hold a single pixel.  Generally, <code>obj</code>
  408        * should be passed in as <code>null</code>, so that the
  409        * <code>Object</code> is created automatically and is the
  410        * correct primitive data type.
  411        * <p>
  412        * The following code illustrates transferring data for one pixel from
  413        * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
  414        * described by <code>MultiPixelPackedSampleModel</code>
  415        * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
  416        * whose storage layout is described by
  417        * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
  418        * The transfer is generally more efficient than using
  419        * <code>getPixel</code> or <code>setPixel</code>.
  420        * <pre>
  421        *       MultiPixelPackedSampleModel mppsm1, mppsm2;
  422        *       DataBufferInt db1, db2;
  423        *       mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
  424        *                              db1), db2);
  425        * </pre>
  426        * Using <code>getDataElements</code> or <code>setDataElements</code>
  427        * to transfer between two <code>DataBuffer/SampleModel</code> pairs
  428        * is legitimate if the <code>SampleModels</code> have the same number
  429        * of bands, corresponding bands have the same number of
  430        * bits per sample, and the TransferTypes are the same.
  431        * <p>
  432        * If <code>obj</code> is not <code>null</code>, it should be a
  433        * primitive array of type TransferType.  Otherwise, a
  434        * <code>ClassCastException</code> is thrown.  An
  435        * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
  436        * coordinates are not in bounds, or if <code>obj</code> is not
  437        * <code>null</code> and is not large enough to hold the pixel data.
  438        * @param x the X coordinate of the specified pixel
  439        * @param y the Y coordinate of the specified pixel
  440        * @param obj a primitive array in which to return the pixel data or
  441        *          <code>null</code>.
  442        * @param data the <code>DataBuffer</code> containing the image data.
  443        * @return an <code>Object</code> containing data for the specified
  444        *  pixel.
  445        * @exception ClassCastException if <code>obj</code> is not a
  446        *  primitive array of type TransferType or is not <code>null</code>
  447        * @exception ArrayIndexOutOfBoundsException if the coordinates are
  448        * not in bounds, or if <code>obj</code> is not <code>null</code> or
  449        * not large enough to hold the pixel data
  450        * @see #setDataElements(int, int, Object, DataBuffer)
  451        */
  452       public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
  453           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  454               throw new ArrayIndexOutOfBoundsException
  455                   ("Coordinate out of bounds!");
  456           }
  457   
  458           int type = getTransferType();
  459           int bitnum = dataBitOffset + x*pixelBitStride;
  460           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  461                       - pixelBitStride;
  462           int element = 0;
  463   
  464           switch(type) {
  465   
  466           case DataBuffer.TYPE_BYTE:
  467   
  468               byte[] bdata;
  469   
  470               if (obj == null)
  471                   bdata = new byte[1];
  472               else
  473                   bdata = (byte[])obj;
  474   
  475               element = data.getElem(y*scanlineStride +
  476                                       bitnum/dataElementSize);
  477               bdata[0] = (byte)((element >> shift) & bitMask);
  478   
  479               obj = (Object)bdata;
  480               break;
  481   
  482           case DataBuffer.TYPE_USHORT:
  483   
  484               short[] sdata;
  485   
  486               if (obj == null)
  487                   sdata = new short[1];
  488               else
  489                   sdata = (short[])obj;
  490   
  491               element = data.getElem(y*scanlineStride +
  492                                      bitnum/dataElementSize);
  493               sdata[0] = (short)((element >> shift) & bitMask);
  494   
  495               obj = (Object)sdata;
  496               break;
  497   
  498           case DataBuffer.TYPE_INT:
  499   
  500               int[] idata;
  501   
  502               if (obj == null)
  503                   idata = new int[1];
  504               else
  505                   idata = (int[])obj;
  506   
  507               element = data.getElem(y*scanlineStride +
  508                                      bitnum/dataElementSize);
  509               idata[0] = (element >> shift) & bitMask;
  510   
  511               obj = (Object)idata;
  512               break;
  513           }
  514   
  515           return obj;
  516       }
  517   
  518       /**
  519        * Returns the specified single band pixel in the first element
  520        * of an <code>int</code> array.
  521        * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
  522        * coordinates are not in bounds.
  523        * @param x the X coordinate of the specified pixel
  524        * @param y the Y coordinate of the specified pixel
  525        * @param iArray the array containing the pixel to be returned or
  526        *  <code>null</code>
  527        * @param data the <code>DataBuffer</code> where image data is stored
  528        * @return an array containing the specified pixel.
  529        * @exception ArrayIndexOutOfBoundsException if the coordinates
  530        *  are not in bounds
  531        * @see #setPixel(int, int, int[], DataBuffer)
  532        */
  533       public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  534           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  535               throw new ArrayIndexOutOfBoundsException
  536                   ("Coordinate out of bounds!");
  537           }
  538           int pixels[];
  539           if (iArray != null) {
  540              pixels = iArray;
  541           } else {
  542              pixels = new int [numBands];
  543           }
  544           int bitnum = dataBitOffset + x*pixelBitStride;
  545           int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
  546           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  547                       - pixelBitStride;
  548           pixels[0] = (element >> shift) & bitMask;
  549           return pixels;
  550       }
  551   
  552       /**
  553        * Sets the data for a single pixel in the specified
  554        * <code>DataBuffer</code> from a primitive array of type
  555        * TransferType.  For a <code>MultiPixelPackedSampleModel</code>,
  556        * only the first element of the array holds valid data,
  557        * and the type must be the smallest of
  558        * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
  559        * that can hold a single pixel.
  560        * <p>
  561        * The following code illustrates transferring data for one pixel from
  562        * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
  563        * described by <code>MultiPixelPackedSampleModel</code>
  564        * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
  565        * whose storage layout is described by
  566        * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
  567        * The transfer is generally more efficient than using
  568        * <code>getPixel</code> or <code>setPixel</code>.
  569        * <pre>
  570        *       MultiPixelPackedSampleModel mppsm1, mppsm2;
  571        *       DataBufferInt db1, db2;
  572        *       mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
  573        *                              db1), db2);
  574        * </pre>
  575        * Using <code>getDataElements</code> or <code>setDataElements</code> to
  576        * transfer between two <code>DataBuffer/SampleModel</code> pairs is
  577        * legitimate if the <code>SampleModel</code> objects have
  578        * the same number of bands, corresponding bands have the same number of
  579        * bits per sample, and the TransferTypes are the same.
  580        * <p>
  581        * <code>obj</code> must be a primitive array of type TransferType.
  582        * Otherwise, a <code>ClassCastException</code> is thrown.  An
  583        * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
  584        * coordinates are not in bounds, or if <code>obj</code> is not large
  585        * enough to hold the pixel data.
  586        * @param x the X coordinate of the pixel location
  587        * @param y the Y coordinate of the pixel location
  588        * @param obj a primitive array containing pixel data
  589        * @param data the <code>DataBuffer</code> containing the image data
  590        * @see #getDataElements(int, int, Object, DataBuffer)
  591        */
  592       public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  593           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  594               throw new ArrayIndexOutOfBoundsException
  595                   ("Coordinate out of bounds!");
  596           }
  597   
  598           int type = getTransferType();
  599           int bitnum = dataBitOffset + x * pixelBitStride;
  600           int index = y * scanlineStride + (bitnum / dataElementSize);
  601           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  602                       - pixelBitStride;
  603           int element = data.getElem(index);
  604           element &= ~(bitMask << shift);
  605   
  606           switch(type) {
  607   
  608           case DataBuffer.TYPE_BYTE:
  609   
  610               byte[] barray = (byte[])obj;
  611               element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
  612               data.setElem(index, element);
  613               break;
  614   
  615           case DataBuffer.TYPE_USHORT:
  616   
  617               short[] sarray = (short[])obj;
  618               element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
  619               data.setElem(index, element);
  620               break;
  621   
  622           case DataBuffer.TYPE_INT:
  623   
  624               int[] iarray = (int[])obj;
  625               element |= (iarray[0] & bitMask) << shift;
  626               data.setElem(index, element);
  627               break;
  628           }
  629       }
  630   
  631       /**
  632        * Sets a pixel in the <code>DataBuffer</code> using an
  633        * <code>int</code> array for input.
  634        * <code>ArrayIndexOutOfBoundsException</code> is thrown if
  635        * the coordinates are not in bounds.
  636        * @param x the X coordinate of the pixel location
  637        * @param y the Y coordinate of the pixel location
  638        * @param iArray the input pixel in an <code>int</code> array
  639        * @param data the <code>DataBuffer</code> containing the image data
  640        * @see #getPixel(int, int, int[], DataBuffer)
  641        */
  642       public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
  643           if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
  644               throw new ArrayIndexOutOfBoundsException
  645                   ("Coordinate out of bounds!");
  646           }
  647           int bitnum = dataBitOffset + x * pixelBitStride;
  648           int index = y * scanlineStride + (bitnum / dataElementSize);
  649           int shift = dataElementSize - (bitnum & (dataElementSize-1))
  650                       - pixelBitStride;
  651           int element = data.getElem(index);
  652           element &= ~(bitMask << shift);
  653           element |= (iArray[0] & bitMask) << shift;
  654           data.setElem(index,element);
  655       }
  656   
  657       public boolean equals(Object o) {
  658           if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
  659               return false;
  660           }
  661   
  662           MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
  663           return this.width == that.width &&
  664               this.height == that.height &&
  665               this.numBands == that.numBands &&
  666               this.dataType == that.dataType &&
  667               this.pixelBitStride == that.pixelBitStride &&
  668               this.bitMask == that.bitMask &&
  669               this.pixelsPerDataElement == that.pixelsPerDataElement &&
  670               this.dataElementSize == that.dataElementSize &&
  671               this.dataBitOffset == that.dataBitOffset &&
  672               this.scanlineStride == that.scanlineStride;
  673       }
  674   
  675       // If we implement equals() we must also implement hashCode
  676       public int hashCode() {
  677           int hash = 0;
  678           hash = width;
  679           hash <<= 8;
  680           hash ^= height;
  681           hash <<= 8;
  682           hash ^= numBands;
  683           hash <<= 8;
  684           hash ^= dataType;
  685           hash <<= 8;
  686           hash ^= pixelBitStride;
  687           hash <<= 8;
  688           hash ^= bitMask;
  689           hash <<= 8;
  690           hash ^= pixelsPerDataElement;
  691           hash <<= 8;
  692           hash ^= dataElementSize;
  693           hash <<= 8;
  694           hash ^= dataBitOffset;
  695           hash <<= 8;
  696           hash ^= scanlineStride;
  697           return hash;
  698       }
  699   }

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