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

    1   /*
    2    * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   /* ****************************************************************
   27    ******************************************************************
   28    ******************************************************************
   29    *** COPYRIGHT (c) Eastman Kodak Company, 1997
   30    *** As  an unpublished  work pursuant to Title 17 of the United
   31    *** States Code.  All rights reserved.
   32    ******************************************************************
   33    ******************************************************************
   34    ******************************************************************/
   35   
   36   package java.awt.image;
   37   
   38   import sun.java2d.StateTrackable.State;
   39   import static sun.java2d.StateTrackable.State.*;
   40   import sun.java2d.StateTrackableDelegate;
   41   
   42   import sun.awt.image.SunWritableRaster;
   43   
   44   /**
   45    * This class exists to wrap one or more data arrays.  Each data array in
   46    * the DataBuffer is referred to as a bank.  Accessor methods for getting
   47    * and setting elements of the DataBuffer's banks exist with and without
   48    * a bank specifier.  The methods without a bank specifier use the default 0th
   49    * bank.  The DataBuffer can optionally take an offset per bank, so that
   50    * data in an existing array can be used even if the interesting data
   51    * doesn't start at array location zero.  Getting or setting the 0th
   52    * element of a bank, uses the (0+offset)th element of the array.  The
   53    * size field specifies how much of the data array is available for
   54    * use.  Size + offset for a given bank should never be greater
   55    * than the length of the associated data array.  The data type of
   56    * a data buffer indicates the type of the data array(s) and may also
   57    * indicate additional semantics, e.g. storing unsigned 8-bit data
   58    * in elements of a byte array.  The data type may be TYPE_UNDEFINED
   59    * or one of the types defined below.  Other types may be added in
   60    * the future.  Generally, an object of class DataBuffer will be cast down
   61    * to one of its data type specific subclasses to access data type specific
   62    * methods for improved performance.  Currently, the Java 2D(tm) API
   63    * image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
   64    * TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
   65    * @see java.awt.image.Raster
   66    * @see java.awt.image.SampleModel
   67    */
   68   public abstract class DataBuffer {
   69   
   70       /** Tag for unsigned byte data. */
   71       public static final int TYPE_BYTE  = 0;
   72   
   73       /** Tag for unsigned short data. */
   74       public static final int TYPE_USHORT = 1;
   75   
   76       /** Tag for signed short data.  Placeholder for future use. */
   77       public static final int TYPE_SHORT = 2;
   78   
   79       /** Tag for int data. */
   80       public static final int TYPE_INT   = 3;
   81   
   82       /** Tag for float data.  Placeholder for future use. */
   83       public static final int TYPE_FLOAT  = 4;
   84   
   85       /** Tag for double data.  Placeholder for future use. */
   86       public static final int TYPE_DOUBLE  = 5;
   87   
   88       /** Tag for undefined data. */
   89       public static final int TYPE_UNDEFINED = 32;
   90   
   91       /** The data type of this DataBuffer. */
   92       protected int dataType;
   93   
   94       /** The number of banks in this DataBuffer. */
   95       protected int banks;
   96   
   97       /** Offset into default (first) bank from which to get the first element. */
   98       protected int offset;
   99   
  100       /** Usable size of all banks. */
  101       protected int size;
  102   
  103       /** Offsets into all banks. */
  104       protected int offsets[];
  105   
  106       /* The current StateTrackable state. */
  107       StateTrackableDelegate theTrackable;
  108   
  109       /** Size of the data types indexed by DataType tags defined above. */
  110       private static final int dataTypeSize[] = {8,16,16,32,32,64};
  111   
  112       /** Returns the size (in bits) of the data type, given a datatype tag.
  113         * @param type the value of one of the defined datatype tags
  114         * @return the size of the data type
  115         * @throws IllegalArgumentException if <code>type</code> is less than
  116         *         zero or greater than {@link #TYPE_DOUBLE}
  117         */
  118       public static int getDataTypeSize(int type) {
  119           if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
  120               throw new IllegalArgumentException("Unknown data type "+type);
  121           }
  122           return dataTypeSize[type];
  123       }
  124   
  125       /**
  126        *  Constructs a DataBuffer containing one bank of the specified
  127        *  data type and size.
  128        *
  129        *  @param dataType the data type of this <code>DataBuffer</code>
  130        *  @param size the size of the banks
  131        */
  132       protected DataBuffer(int dataType, int size) {
  133           this(UNTRACKABLE, dataType, size);
  134       }
  135   
  136       /**
  137        *  Constructs a DataBuffer containing one bank of the specified
  138        *  data type and size with the indicated initial {@link State State}.
  139        *
  140        *  @param initialState the initial {@link State State} state of the data
  141        *  @param dataType the data type of this <code>DataBuffer</code>
  142        *  @param size the size of the banks
  143        *  @since 1.7
  144        */
  145       DataBuffer(State initialState,
  146                  int dataType, int size)
  147       {
  148           this.theTrackable = StateTrackableDelegate.createInstance(initialState);
  149           this.dataType = dataType;
  150           this.banks = 1;
  151           this.size = size;
  152           this.offset = 0;
  153           this.offsets = new int[1];  // init to 0 by new
  154       }
  155   
  156       /**
  157        *  Constructs a DataBuffer containing the specified number of
  158        *  banks.  Each bank has the specified size and an offset of 0.
  159        *
  160        *  @param dataType the data type of this <code>DataBuffer</code>
  161        *  @param size the size of the banks
  162        *  @param numBanks the number of banks in this
  163        *         <code>DataBuffer</code>
  164        */
  165       protected DataBuffer(int dataType, int size, int numBanks) {
  166           this(UNTRACKABLE, dataType, size, numBanks);
  167       }
  168   
  169       /**
  170        *  Constructs a DataBuffer containing the specified number of
  171        *  banks with the indicated initial {@link State State}.
  172        *  Each bank has the specified size and an offset of 0.
  173        *
  174        *  @param initialState the initial {@link State State} state of the data
  175        *  @param dataType the data type of this <code>DataBuffer</code>
  176        *  @param size the size of the banks
  177        *  @param numBanks the number of banks in this
  178        *         <code>DataBuffer</code>
  179        *  @since 1.7
  180        */
  181       DataBuffer(State initialState,
  182                  int dataType, int size, int numBanks)
  183       {
  184           this.theTrackable = StateTrackableDelegate.createInstance(initialState);
  185           this.dataType = dataType;
  186           this.banks = numBanks;
  187           this.size = size;
  188           this.offset = 0;
  189           this.offsets = new int[banks]; // init to 0 by new
  190       }
  191   
  192       /**
  193        *  Constructs a DataBuffer that contains the specified number
  194        *  of banks.  Each bank has the specified datatype, size and offset.
  195        *
  196        *  @param dataType the data type of this <code>DataBuffer</code>
  197        *  @param size the size of the banks
  198        *  @param numBanks the number of banks in this
  199        *         <code>DataBuffer</code>
  200        *  @param offset the offset for each bank
  201        */
  202       protected DataBuffer(int dataType, int size, int numBanks, int offset) {
  203           this(UNTRACKABLE, dataType, size, numBanks, offset);
  204       }
  205   
  206       /**
  207        *  Constructs a DataBuffer that contains the specified number
  208        *  of banks with the indicated initial {@link State State}.
  209        *  Each bank has the specified datatype, size and offset.
  210        *
  211        *  @param initialState the initial {@link State State} state of the data
  212        *  @param dataType the data type of this <code>DataBuffer</code>
  213        *  @param size the size of the banks
  214        *  @param numBanks the number of banks in this
  215        *         <code>DataBuffer</code>
  216        *  @param offset the offset for each bank
  217        *  @since 1.7
  218        */
  219       DataBuffer(State initialState,
  220                  int dataType, int size, int numBanks, int offset)
  221       {
  222           this.theTrackable = StateTrackableDelegate.createInstance(initialState);
  223           this.dataType = dataType;
  224           this.banks = numBanks;
  225           this.size = size;
  226           this.offset = offset;
  227           this.offsets = new int[numBanks];
  228           for (int i = 0; i < numBanks; i++) {
  229               this.offsets[i] = offset;
  230           }
  231       }
  232   
  233       /**
  234        *  Constructs a DataBuffer which contains the specified number
  235        *  of banks.  Each bank has the specified datatype and size.  The
  236        *  offset for each bank is specified by its respective entry in
  237        *  the offsets array.
  238        *
  239        *  @param dataType the data type of this <code>DataBuffer</code>
  240        *  @param size the size of the banks
  241        *  @param numBanks the number of banks in this
  242        *         <code>DataBuffer</code>
  243        *  @param offsets an array containing an offset for each bank.
  244        *  @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
  245        *          does not equal the length of <code>offsets</code>
  246        */
  247       protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
  248           this(UNTRACKABLE, dataType, size, numBanks, offsets);
  249       }
  250   
  251       /**
  252        *  Constructs a DataBuffer which contains the specified number
  253        *  of banks with the indicated initial {@link State State}.
  254        *  Each bank has the specified datatype and size.  The
  255        *  offset for each bank is specified by its respective entry in
  256        *  the offsets array.
  257        *
  258        *  @param initialState the initial {@link State State} state of the data
  259        *  @param dataType the data type of this <code>DataBuffer</code>
  260        *  @param size the size of the banks
  261        *  @param numBanks the number of banks in this
  262        *         <code>DataBuffer</code>
  263        *  @param offsets an array containing an offset for each bank.
  264        *  @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
  265        *          does not equal the length of <code>offsets</code>
  266        *  @since 1.7
  267        */
  268       DataBuffer(State initialState,
  269                  int dataType, int size, int numBanks, int offsets[])
  270       {
  271           if (numBanks != offsets.length) {
  272               throw new ArrayIndexOutOfBoundsException("Number of banks" +
  273                    " does not match number of bank offsets");
  274           }
  275           this.theTrackable = StateTrackableDelegate.createInstance(initialState);
  276           this.dataType = dataType;
  277           this.banks = numBanks;
  278           this.size = size;
  279           this.offset = offsets[0];
  280           this.offsets = (int[])offsets.clone();
  281       }
  282   
  283       /**  Returns the data type of this DataBuffer.
  284        *   @return the data type of this <code>DataBuffer</code>.
  285        */
  286       public int getDataType() {
  287           return dataType;
  288       }
  289   
  290       /**  Returns the size (in array elements) of all banks.
  291        *   @return the size of all banks.
  292        */
  293       public int getSize() {
  294           return size;
  295       }
  296   
  297       /** Returns the offset of the default bank in array elements.
  298        *  @return the offset of the default bank.
  299        */
  300       public int getOffset() {
  301           return offset;
  302       }
  303   
  304       /** Returns the offsets (in array elements) of all the banks.
  305        *  @return the offsets of all banks.
  306        */
  307       public int[] getOffsets() {
  308           return (int[])offsets.clone();
  309       }
  310   
  311       /** Returns the number of banks in this DataBuffer.
  312        *  @return the number of banks.
  313        */
  314       public int getNumBanks() {
  315           return banks;
  316       }
  317   
  318       /**
  319        * Returns the requested data array element from the first (default) bank
  320        * as an integer.
  321        * @param i the index of the requested data array element
  322        * @return the data array element at the specified index.
  323        * @see #setElem(int, int)
  324        * @see #setElem(int, int, int)
  325        */
  326       public int getElem(int i) {
  327           return getElem(0,i);
  328       }
  329   
  330       /**
  331        * Returns the requested data array element from the specified bank
  332        * as an integer.
  333        * @param bank the specified bank
  334        * @param i the index of the requested data array element
  335        * @return the data array element at the specified index from the
  336        *         specified bank at the specified index.
  337        * @see #setElem(int, int)
  338        * @see #setElem(int, int, int)
  339        */
  340       public abstract int getElem(int bank, int i);
  341   
  342       /**
  343        * Sets the requested data array element in the first (default) bank
  344        * from the given integer.
  345        * @param i the specified index into the data array
  346        * @param val the data to set the element at the specified index in
  347        * the data array
  348        * @see #getElem(int)
  349        * @see #getElem(int, int)
  350        */
  351       public void  setElem(int i, int val) {
  352           setElem(0,i,val);
  353       }
  354   
  355       /**
  356        * Sets the requested data array element in the specified bank
  357        * from the given integer.
  358        * @param bank the specified bank
  359        * @param i the specified index into the data array
  360        * @param val  the data to set the element in the specified bank
  361        * at the specified index in the data array
  362        * @see #getElem(int)
  363        * @see #getElem(int, int)
  364        */
  365       public abstract void setElem(int bank, int i, int val);
  366   
  367       /**
  368        * Returns the requested data array element from the first (default) bank
  369        * as a float.  The implementation in this class is to cast getElem(i)
  370        * to a float.  Subclasses may override this method if another
  371        * implementation is needed.
  372        * @param i the index of the requested data array element
  373        * @return a float value representing the data array element at the
  374        *  specified index.
  375        * @see #setElemFloat(int, float)
  376        * @see #setElemFloat(int, int, float)
  377        */
  378       public float getElemFloat(int i) {
  379           return (float)getElem(i);
  380       }
  381   
  382       /**
  383        * Returns the requested data array element from the specified bank
  384        * as a float.  The implementation in this class is to cast
  385        * {@link #getElem(int, int)}
  386        * to a float.  Subclasses can override this method if another
  387        * implementation is needed.
  388        * @param bank the specified bank
  389        * @param i the index of the requested data array element
  390        * @return a float value representing the data array element from the
  391        * specified bank at the specified index.
  392        * @see #setElemFloat(int, float)
  393        * @see #setElemFloat(int, int, float)
  394        */
  395       public float getElemFloat(int bank, int i) {
  396           return (float)getElem(bank,i);
  397       }
  398   
  399       /**
  400        * Sets the requested data array element in the first (default) bank
  401        * from the given float.  The implementation in this class is to cast
  402        * val to an int and call {@link #setElem(int, int)}.  Subclasses
  403        * can override this method if another implementation is needed.
  404        * @param i the specified index
  405        * @param val the value to set the element at the specified index in
  406        * the data array
  407        * @see #getElemFloat(int)
  408        * @see #getElemFloat(int, int)
  409        */
  410       public void setElemFloat(int i, float val) {
  411           setElem(i,(int)val);
  412       }
  413   
  414       /**
  415        * Sets the requested data array element in the specified bank
  416        * from the given float.  The implementation in this class is to cast
  417        * val to an int and call {@link #setElem(int, int)}.  Subclasses can
  418        * override this method if another implementation is needed.
  419        * @param bank the specified bank
  420        * @param i the specified index
  421        * @param val the value to set the element in the specified bank at
  422        * the specified index in the data array
  423        * @see #getElemFloat(int)
  424        * @see #getElemFloat(int, int)
  425        */
  426       public void setElemFloat(int bank, int i, float val) {
  427           setElem(bank,i,(int)val);
  428       }
  429   
  430       /**
  431        * Returns the requested data array element from the first (default) bank
  432        * as a double.  The implementation in this class is to cast
  433        * {@link #getElem(int)}
  434        * to a double.  Subclasses can override this method if another
  435        * implementation is needed.
  436        * @param i the specified index
  437        * @return a double value representing the element at the specified
  438        * index in the data array.
  439        * @see #setElemDouble(int, double)
  440        * @see #setElemDouble(int, int, double)
  441        */
  442       public double getElemDouble(int i) {
  443           return (double)getElem(i);
  444       }
  445   
  446       /**
  447        * Returns the requested data array element from the specified bank as
  448        * a double.  The implementation in this class is to cast getElem(bank, i)
  449        * to a double.  Subclasses may override this method if another
  450        * implementation is needed.
  451        * @param bank the specified bank
  452        * @param i the specified index
  453        * @return a double value representing the element from the specified
  454        * bank at the specified index in the data array.
  455        * @see #setElemDouble(int, double)
  456        * @see #setElemDouble(int, int, double)
  457        */
  458       public double getElemDouble(int bank, int i) {
  459           return (double)getElem(bank,i);
  460       }
  461   
  462       /**
  463        * Sets the requested data array element in the first (default) bank
  464        * from the given double.  The implementation in this class is to cast
  465        * val to an int and call {@link #setElem(int, int)}.  Subclasses can
  466        * override this method if another implementation is needed.
  467        * @param i the specified index
  468        * @param val the value to set the element at the specified index
  469        * in the data array
  470        * @see #getElemDouble(int)
  471        * @see #getElemDouble(int, int)
  472        */
  473       public void setElemDouble(int i, double val) {
  474           setElem(i,(int)val);
  475       }
  476   
  477       /**
  478        * Sets the requested data array element in the specified bank
  479        * from the given double.  The implementation in this class is to cast
  480        * val to an int and call {@link #setElem(int, int)}.  Subclasses can
  481        * override this method if another implementation is needed.
  482        * @param bank the specified bank
  483        * @param i the specified index
  484        * @param val the value to set the element in the specified bank
  485        * at the specified index of the data array
  486        * @see #getElemDouble(int)
  487        * @see #getElemDouble(int, int)
  488        */
  489       public void setElemDouble(int bank, int i, double val) {
  490           setElem(bank,i,(int)val);
  491       }
  492   
  493       static int[] toIntArray(Object obj) {
  494           if (obj instanceof int[]) {
  495               return (int[])obj;
  496           } else if (obj == null) {
  497               return null;
  498           } else if (obj instanceof short[]) {
  499               short sdata[] = (short[])obj;
  500               int idata[] = new int[sdata.length];
  501               for (int i = 0; i < sdata.length; i++) {
  502                   idata[i] = (int)sdata[i] & 0xffff;
  503               }
  504               return idata;
  505           } else if (obj instanceof byte[]) {
  506               byte bdata[] = (byte[])obj;
  507               int idata[] = new int[bdata.length];
  508               for (int i = 0; i < bdata.length; i++) {
  509                   idata[i] = 0xff & (int)bdata[i];
  510               }
  511               return idata;
  512           }
  513           return null;
  514       }
  515   
  516       static {
  517           SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
  518               public byte[] getData(DataBufferByte dbb, int bank) {
  519                   return dbb.bankdata[bank];
  520               }
  521   
  522               public short[] getData(DataBufferUShort dbus, int bank) {
  523                   return dbus.bankdata[bank];
  524               }
  525   
  526               public int[] getData(DataBufferInt dbi, int bank) {
  527                   return dbi.bankdata[bank];
  528               }
  529   
  530               public StateTrackableDelegate getTrackable(DataBuffer db) {
  531                   return db.theTrackable;
  532               }
  533   
  534               public void setTrackable(DataBuffer db,
  535                                        StateTrackableDelegate trackable)
  536               {
  537                   db.theTrackable = trackable;
  538               }
  539           });
  540       }
  541   }

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