001    /* Copyright (C) 2000, 2002, 2005  Free Software Foundation
002    
003    This file is part of GNU Classpath.
004    
005    GNU Classpath is free software; you can redistribute it and/or modify
006    it under the terms of the GNU General Public License as published by
007    the Free Software Foundation; either version 2, or (at your option)
008    any later version.
009    
010    GNU Classpath is distributed in the hope that it will be useful, but
011    WITHOUT ANY WARRANTY; without even the implied warranty of
012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013    General Public License for more details.
014    
015    You should have received a copy of the GNU General Public License
016    along with GNU Classpath; see the file COPYING.  If not, write to the
017    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
018    02110-1301 USA.
019    
020    Linking this library statically or dynamically with other modules is
021    making a combined work based on this library.  Thus, the terms and
022    conditions of the GNU General Public License cover the whole
023    combination.
024    
025    As a special exception, the copyright holders of this library give you
026    permission to link this library with independent modules to produce an
027    executable, regardless of the license terms of these independent
028    modules, and to copy and distribute the resulting executable under
029    terms of your choice, provided that you also meet, for each linked
030    independent module, the terms and conditions of the license of that
031    module.  An independent module is a module which is not derived from
032    or based on this library.  If you modify this library, you may extend
033    this exception to your version of the library, but you are not
034    obligated to do so.  If you do not wish to do so, delete this
035    exception statement from your version. */
036    
037    package java.awt.image;
038    
039    /**
040     * Class that manages arrays of data elements. A data buffer consists
041     * of one or more banks.  A bank is a continuous region of data
042     * elements.
043     *
044     * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
045     */
046    public abstract class DataBuffer
047    {
048      /**
049       * A constant representing a data type that uses <code>byte</code> primitives
050       * as the storage unit.
051       */
052      public static final int TYPE_BYTE      =  0;
053    
054      /**
055       * A constant representing a data type that uses <code>short</code>
056       * primitives as the storage unit.
057       */
058      public static final int TYPE_USHORT    =  1;
059    
060      /**
061       * A constant representing a data type that uses <code>short</code>
062       * primitives as the storage unit.
063       */
064      public static final int TYPE_SHORT     =  2;
065    
066      /**
067       * A constant representing a data type that uses <code>int</code>
068       * primitives as the storage unit.
069       */
070      public static final int TYPE_INT       =  3;
071    
072      /**
073       * A constant representing a data type that uses <code>float</code>
074       * primitives as the storage unit.
075       */
076      public static final int TYPE_FLOAT     =  4;
077    
078      /**
079       * A constant representing a data type that uses <code>double</code>
080       * primitives as the storage unit.
081       */
082      public static final int TYPE_DOUBLE    =  5;
083    
084      /**
085       * A constant representing an undefined data type.
086       */
087      public static final int TYPE_UNDEFINED = 32;
088    
089      /** The type of the data elements stored in the data buffer.  */
090      protected int dataType;
091    
092      /** The number of banks in this buffer.  */
093      protected int banks = 1;
094    
095      /** Offset into the default (0'th) bank). */
096      protected int offset; // FIXME: Is offsets[0] always mirrored in offset?
097    
098      /** The size of the banks.  */
099      protected int size;
100    
101      /** Offset into each bank.  */
102      protected int[] offsets;
103    
104      /**
105       * Creates a new <code>DataBuffer</code> with the specified data type and
106       * size.  The <code>dataType</code> should be one of the constants
107       * {@link #TYPE_BYTE}, {@link #TYPE_SHORT}, {@link #TYPE_USHORT},
108       * {@link #TYPE_INT}, {@link #TYPE_FLOAT} and {@link #TYPE_DOUBLE}.
109       * <p>
110       * The physical (array-based) storage is allocated by a subclass.
111       *
112       * @param dataType the data type.
113       * @param size the number of elements in the buffer.
114       */
115      protected DataBuffer(int dataType, int size)
116      {
117        this(dataType, size, 1);
118      }
119    
120      /**
121       * Creates a new <code>DataBuffer</code> with the specified data type,
122       * size and number of banks.  The <code>dataType</code> should be one of
123       * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
124       * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
125       * {@link #TYPE_DOUBLE}.
126       * <p>
127       * The physical (array-based) storage is allocated by a subclass.
128       *
129       * @param dataType the data type.
130       * @param size the number of elements in the buffer.
131       * @param numBanks the number of data banks.
132       */
133      protected DataBuffer(int dataType, int size, int numBanks) {
134        this(dataType, size, numBanks, 0);
135      }
136    
137      /**
138       * Creates a new <code>DataBuffer</code> with the specified data type,
139       * size and number of banks.  An offset (which applies to all banks) is
140       * also specified.  The <code>dataType</code> should be one of
141       * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
142       * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
143       * {@link #TYPE_DOUBLE}.
144       * <p>
145       * The physical (array-based) storage is allocated by a subclass.
146       *
147       * @param dataType the data type.
148       * @param size the number of elements in the buffer.
149       * @param numBanks the number of data banks.
150       * @param offset the offset to the first element for all banks.
151       */
152      protected DataBuffer(int dataType, int size, int numBanks, int offset) {
153        banks = numBanks;
154        this.dataType = dataType;
155        this.size = size;
156        this.offset = offset;
157    
158        offsets = new int[ numBanks ];
159        for(int i = 0; i < numBanks; i++ )
160          offsets[i] = offset;
161      }
162    
163      /**
164       * Creates a new <code>DataBuffer</code> with the specified data type,
165       * size and number of banks.  An offset (which applies to all banks) is
166       * also specified.  The <code>dataType</code> should be one of
167       * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
168       * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
169       * {@link #TYPE_DOUBLE}.
170       * <p>
171       * The physical (array-based) storage is allocated by a subclass.
172       *
173       * @param dataType the data type.
174       * @param size the number of elements in the buffer.
175       * @param numBanks the number of data banks.
176       * @param offsets the offsets to the first element for all banks.
177       *
178       * @throws ArrayIndexOutOfBoundsException if
179       *         <code>numBanks != offsets.length</code>.
180       */
181      protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
182        if (numBanks != offsets.length)
183          throw new ArrayIndexOutOfBoundsException();
184    
185        this.dataType = dataType;
186        this.size = size;
187        banks = numBanks;
188        this.offsets = offsets;
189    
190        offset = offsets[0];
191      }
192    
193      /**
194       * Returns the size (number of bits) of the specified data type. Valid types
195       * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
196       * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
197       * {@link #TYPE_DOUBLE}.
198       *
199       * @param dataType the data type.
200       * @return The number of bits for the specified data type.
201       * @throws IllegalArgumentException if <code>dataType < 0</code> or
202       *         <code>dataType > TYPE_DOUBLE</code>.
203       */
204      public static int getDataTypeSize(int dataType) {
205        // Maybe this should be a lookup table instead.
206        switch (dataType)
207          {
208          case TYPE_BYTE:
209            return 8;
210          case TYPE_USHORT:
211          case TYPE_SHORT:
212            return 16;
213          case TYPE_INT:
214          case TYPE_FLOAT:
215            return 32;
216          case TYPE_DOUBLE:
217            return 64;
218          default:
219            throw new IllegalArgumentException();
220          }
221      }
222    
223      /**
224       * Returns the type of the data elements in the data buffer.  Valid types
225       * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
226       * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
227       * {@link #TYPE_DOUBLE}.
228       *
229       * @return The type.
230       */
231      public int getDataType()
232      {
233        return dataType;
234      }
235    
236      /**
237       * Returns the size of the data buffer.
238       *
239       * @return The size.
240       */
241      public int getSize()
242      {
243        return size;
244      }
245    
246      /**
247       * Returns the element offset for the first data bank.
248       *
249       * @return The element offset.
250       */
251      public int getOffset()
252      {
253        return offset;
254      }
255    
256      /**
257       * Returns the offsets for all the data banks used by this
258       * <code>DataBuffer</code>.
259       *
260       * @return The offsets.
261       */
262      public int[] getOffsets()
263      {
264        if (offsets == null)
265        {
266          // is this necessary?
267          offsets = new int[1];
268          offsets[0] = offset;
269        }
270        return offsets;
271      }
272    
273      /**
274       * Returns the number of data banks for this <code>DataBuffer</code>.
275       * @return The number of data banks.
276       */
277      public int getNumBanks()
278      {
279        return banks;
280      }
281    
282      /**
283       * Returns an element from the first data bank.  The offset (specified in
284       * the constructor) is added to <code>i</code> before accessing the
285       * underlying data array.
286       *
287       * @param i the element index.
288       * @return The element.
289       */
290      public int getElem(int i)
291      {
292        return getElem(0, i);
293      }
294    
295      /**
296       * Returns an element from a particular data bank.  The offset (specified in
297       * the constructor) is added to <code>i</code> before accessing the
298       * underlying data array.
299       *
300       * @param bank the bank index.
301       * @param i the element index.
302       * @return The element.
303       */
304      public abstract int getElem(int bank, int i);
305    
306      /**
307       * Sets an element in the first data bank.  The offset (specified in the
308       * constructor) is added to <code>i</code> before updating the underlying
309       * data array.
310       *
311       * @param i the element index.
312       * @param val the new element value.
313       */
314      public void setElem(int i, int val)
315      {
316        setElem(0, i, val);
317      }
318    
319      /**
320       * Sets an element in a particular data bank.  The offset (specified in the
321       * constructor) is added to <code>i</code> before updating the underlying
322       * data array.
323       *
324       * @param bank the data bank index.
325       * @param i the element index.
326       * @param val the new element value.
327       */
328      public abstract void setElem(int bank, int i, int val);
329    
330      /**
331       * Returns an element from the first data bank, converted to a
332       * <code>float</code>.  The offset (specified in the constructor) is added
333       * to <code>i</code> before accessing the underlying data array.
334       *
335       * @param i the element index.
336       * @return The element.
337       */
338      public float getElemFloat(int i)
339      {
340        return getElem(i);
341      }
342    
343      /**
344       * Returns an element from a particular data bank, converted to a
345       * <code>float</code>.  The offset (specified in the constructor) is
346       * added to <code>i</code> before accessing the underlying data array.
347       *
348       * @param bank the bank index.
349       * @param i the element index.
350       * @return The element.
351       */
352      public float getElemFloat(int bank, int i)
353      {
354        return getElem(bank, i);
355      }
356    
357      /**
358       * Sets an element in the first data bank.  The offset (specified in the
359       * constructor) is added to <code>i</code> before updating the underlying
360       * data array.
361       *
362       * @param i the element index.
363       * @param val the new element value.
364       */
365      public void setElemFloat(int i, float val)
366      {
367        setElem(i, (int) val);
368      }
369    
370      /**
371       * Sets an element in a particular data bank.  The offset (specified in the
372       * constructor) is added to <code>i</code> before updating the underlying
373       * data array.
374       *
375       * @param bank the data bank index.
376       * @param i the element index.
377       * @param val the new element value.
378       */
379      public void setElemFloat(int bank, int i, float val)
380      {
381        setElem(bank, i, (int) val);
382      }
383    
384      /**
385       * Returns an element from the first data bank, converted to a
386       * <code>double</code>.  The offset (specified in the constructor) is added
387       * to <code>i</code> before accessing the underlying data array.
388       *
389       * @param i the element index.
390       * @return The element.
391       */
392      public double getElemDouble(int i)
393      {
394        return getElem(i);
395      }
396    
397      /**
398       * Returns an element from a particular data bank, converted to a
399       * <code>double</code>.  The offset (specified in the constructor) is
400       * added to <code>i</code> before accessing the underlying data array.
401       *
402       * @param bank the bank index.
403       * @param i the element index.
404       * @return The element.
405       */
406      public double getElemDouble(int bank, int i)
407      {
408        return getElem(bank, i);
409      }
410    
411      /**
412       * Sets an element in the first data bank.  The offset (specified in the
413       * constructor) is added to <code>i</code> before updating the underlying
414       * data array.
415       *
416       * @param i the element index.
417       * @param val the new element value.
418       */
419      public void setElemDouble(int i, double val)
420      {
421        setElem(i, (int) val);
422      }
423    
424      /**
425       * Sets an element in a particular data bank.  The offset (specified in the
426       * constructor) is added to <code>i</code> before updating the underlying
427       * data array.
428       *
429       * @param bank the data bank index.
430       * @param i the element index.
431       * @param val the new element value.
432       */
433      public void setElemDouble(int bank, int i, double val)
434      {
435        setElem(bank, i, (int) val);
436      }
437    }