001/* Copyright (C) 2000, 2002, 2005  Free Software Foundation
002
003This file is part of GNU Classpath.
004
005GNU Classpath is free software; you can redistribute it and/or modify
006it under the terms of the GNU General Public License as published by
007the Free Software Foundation; either version 2, or (at your option)
008any later version.
009
010GNU Classpath is distributed in the hope that it will be useful, but
011WITHOUT ANY WARRANTY; without even the implied warranty of
012MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013General Public License for more details.
014
015You should have received a copy of the GNU General Public License
016along with GNU Classpath; see the file COPYING.  If not, write to the
017Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01802110-1301 USA.
019
020Linking this library statically or dynamically with other modules is
021making a combined work based on this library.  Thus, the terms and
022conditions of the GNU General Public License cover the whole
023combination.
024
025As a special exception, the copyright holders of this library give you
026permission to link this library with independent modules to produce an
027executable, regardless of the license terms of these independent
028modules, and to copy and distribute the resulting executable under
029terms of your choice, provided that you also meet, for each linked
030independent module, the terms and conditions of the license of that
031module.  An independent module is a module which is not derived from
032or based on this library.  If you modify this library, you may extend
033this exception to your version of the library, but you are not
034obligated to do so.  If you do not wish to do so, delete this
035exception statement from your version. */
036
037package 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 */
046public 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}