1 /* Copyright (C) 2000, 2002, 2005  Free Software Foundation
2 
3 This file is part of GNU Classpath.
4 
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9 
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING.  If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 USA.
19 
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library.  Thus, the terms and
22 conditions of the GNU General Public License cover the whole
23 combination.
24 
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module.  An independent module is a module which is not derived from
32 or based on this library.  If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so.  If you do not wish to do so, delete this
35 exception statement from your version. */
36 
37 package java.awt.image;
38 
39 /**
40  * Class that manages arrays of data elements. A data buffer consists
41  * of one or more banks.  A bank is a continuous region of data
42  * elements.
43  *
44  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
45  */
46 public abstract class DataBuffer
47 {
48   /**
49    * A constant representing a data type that uses <code>byte</code> primitives
50    * as the storage unit.
51    */
52   public static final int TYPE_BYTE      =  0;
53 
54   /**
55    * A constant representing a data type that uses <code>short</code>
56    * primitives as the storage unit.
57    */
58   public static final int TYPE_USHORT    =  1;
59 
60   /**
61    * A constant representing a data type that uses <code>short</code>
62    * primitives as the storage unit.
63    */
64   public static final int TYPE_SHORT     =  2;
65 
66   /**
67    * A constant representing a data type that uses <code>int</code>
68    * primitives as the storage unit.
69    */
70   public static final int TYPE_INT       =  3;
71 
72   /**
73    * A constant representing a data type that uses <code>float</code>
74    * primitives as the storage unit.
75    */
76   public static final int TYPE_FLOAT     =  4;
77 
78   /**
79    * A constant representing a data type that uses <code>double</code>
80    * primitives as the storage unit.
81    */
82   public static final int TYPE_DOUBLE    =  5;
83 
84   /**
85    * A constant representing an undefined data type.
86    */
87   public static final int TYPE_UNDEFINED = 32;
88 
89   /** The type of the data elements stored in the data buffer.  */
90   protected int dataType;
91 
92   /** The number of banks in this buffer.  */
93   protected int banks = 1;
94 
95   /** Offset into the default (0'th) bank). */
96   protected int offset; // FIXME: Is offsets[0] always mirrored in offset?
97 
98   /** The size of the banks.  */
99   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    */
DataBuffer(int dataType, int size)115   protected DataBuffer(int dataType, int size)
116   {
117     this.dataType = dataType;
118     this.size = size;
119   }
120 
121   /**
122    * Creates a new <code>DataBuffer</code> with the specified data type,
123    * size and number of banks.  The <code>dataType</code> should be one of
124    * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
125    * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
126    * {@link #TYPE_DOUBLE}.
127    * <p>
128    * The physical (array-based) storage is allocated by a subclass.
129    *
130    * @param dataType the data type.
131    * @param size the number of elements in the buffer.
132    * @param numBanks the number of data banks.
133    */
DataBuffer(int dataType, int size, int numBanks)134   protected DataBuffer(int dataType, int size, int numBanks) {
135     this(dataType, size);
136     banks = numBanks;
137     offsets = new int[numBanks];
138   }
139 
140   /**
141    * Creates a new <code>DataBuffer</code> with the specified data type,
142    * size and number of banks.  An offset (which applies to all banks) is
143    * also specified.  The <code>dataType</code> should be one of
144    * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
145    * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
146    * {@link #TYPE_DOUBLE}.
147    * <p>
148    * The physical (array-based) storage is allocated by a subclass.
149    *
150    * @param dataType the data type.
151    * @param size the number of elements in the buffer.
152    * @param numBanks the number of data banks.
153    * @param offset the offset to the first element for all banks.
154    */
DataBuffer(int dataType, int size, int numBanks, int offset)155   protected DataBuffer(int dataType, int size, int numBanks, int offset) {
156     this(dataType, size, numBanks);
157 
158     java.util.Arrays.fill(offsets, offset);
159 
160     this.offset = 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    */
DataBuffer(int dataType, int size, int numBanks, int[] offsets)181   protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
182     this(dataType, size);
183     if (numBanks != offsets.length)
184       throw new ArrayIndexOutOfBoundsException();
185 
186     banks = numBanks;
187     this.offsets = offsets;
188 
189     offset = offsets[0];
190   }
191 
192   /**
193    * Returns the size (number of bits) of the specified data type. Valid types
194    * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
195    * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
196    * {@link #TYPE_DOUBLE}.
197    *
198    * @param dataType the data type.
199    * @return The number of bits for the specified data type.
200    * @throws IllegalArgumentException if <code>dataType < 0</code> or
201    *         <code>dataType > TYPE_DOUBLE</code>.
202    */
getDataTypeSize(int dataType)203   public static int getDataTypeSize(int dataType) {
204     // Maybe this should be a lookup table instead.
205     switch (dataType)
206       {
207       case TYPE_BYTE:
208 	return 8;
209       case TYPE_USHORT:
210       case TYPE_SHORT:
211 	return 16;
212       case TYPE_INT:
213       case TYPE_FLOAT:
214 	return 32;
215       case TYPE_DOUBLE:
216 	return 64;
217       default:
218 	throw new IllegalArgumentException();
219       }
220   }
221 
222   /**
223    * Returns the type of the data elements in the data buffer.  Valid types
224    * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
225    * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
226    * {@link #TYPE_DOUBLE}.
227    *
228    * @return The type.
229    */
getDataType()230   public int getDataType()
231   {
232     return dataType;
233   }
234 
235   /**
236    * Returns the size of the data buffer.
237    *
238    * @return The size.
239    */
getSize()240   public int getSize()
241   {
242     return size;
243   }
244 
245   /**
246    * Returns the element offset for the first data bank.
247    *
248    * @return The element offset.
249    */
getOffset()250   public int getOffset()
251   {
252     return offset;
253   }
254 
255   /**
256    * Returns the offsets for all the data banks used by this
257    * <code>DataBuffer</code>.
258    *
259    * @return The offsets.
260    */
getOffsets()261   public int[] getOffsets()
262   {
263     if (offsets == null)
264     {
265       // is this necessary?
266       offsets = new int[1];
267       offsets[0] = offset;
268     }
269     return offsets;
270   }
271 
272   /**
273    * Returns the number of data banks for this <code>DataBuffer</code>.
274    * @return The number of data banks.
275    */
getNumBanks()276   public int getNumBanks()
277   {
278     return banks;
279   }
280 
281   /**
282    * Returns an element from the first data bank.  The offset (specified in
283    * the constructor) is added to <code>i</code> before accessing the
284    * underlying data array.
285    *
286    * @param i the element index.
287    * @return The element.
288    */
getElem(int i)289   public int getElem(int i)
290   {
291     return getElem(0, i);
292   }
293 
294   /**
295    * Returns an element from a particular data bank.  The offset (specified in
296    * the constructor) is added to <code>i</code> before accessing the
297    * underlying data array.
298    *
299    * @param bank the bank index.
300    * @param i the element index.
301    * @return The element.
302    */
getElem(int bank, int i)303   public abstract int getElem(int bank, int i);
304 
305   /**
306    * Sets an element in the first data bank.  The offset (specified in the
307    * constructor) is added to <code>i</code> before updating the underlying
308    * data array.
309    *
310    * @param i the element index.
311    * @param val the new element value.
312    */
setElem(int i, int val)313   public void setElem(int i, int val)
314   {
315     setElem(0, i, val);
316   }
317 
318   /**
319    * Sets an element in a particular data bank.  The offset (specified in the
320    * constructor) is added to <code>i</code> before updating the underlying
321    * data array.
322    *
323    * @param bank the data bank index.
324    * @param i the element index.
325    * @param val the new element value.
326    */
setElem(int bank, int i, int val)327   public abstract void setElem(int bank, int i, int val);
328 
329   /**
330    * Returns an element from the first data bank, converted to a
331    * <code>float</code>.  The offset (specified in the constructor) is added
332    * to <code>i</code> before accessing the underlying data array.
333    *
334    * @param i the element index.
335    * @return The element.
336    */
getElemFloat(int i)337   public float getElemFloat(int i)
338   {
339     return getElem(i);
340   }
341 
342   /**
343    * Returns an element from a particular data bank, converted to a
344    * <code>float</code>.  The offset (specified in the constructor) is
345    * added to <code>i</code> before accessing the underlying data array.
346    *
347    * @param bank the bank index.
348    * @param i the element index.
349    * @return The element.
350    */
getElemFloat(int bank, int i)351   public float getElemFloat(int bank, int i)
352   {
353     return getElem(bank, i);
354   }
355 
356   /**
357    * Sets an element in the first data bank.  The offset (specified in the
358    * constructor) is added to <code>i</code> before updating the underlying
359    * data array.
360    *
361    * @param i the element index.
362    * @param val the new element value.
363    */
setElemFloat(int i, float val)364   public void setElemFloat(int i, float val)
365   {
366     setElem(i, (int) val);
367   }
368 
369   /**
370    * Sets an element in a particular data bank.  The offset (specified in the
371    * constructor) is added to <code>i</code> before updating the underlying
372    * data array.
373    *
374    * @param bank the data bank index.
375    * @param i the element index.
376    * @param val the new element value.
377    */
setElemFloat(int bank, int i, float val)378   public void setElemFloat(int bank, int i, float val)
379   {
380     setElem(bank, i, (int) val);
381   }
382 
383   /**
384    * Returns an element from the first data bank, converted to a
385    * <code>double</code>.  The offset (specified in the constructor) is added
386    * to <code>i</code> before accessing the underlying data array.
387    *
388    * @param i the element index.
389    * @return The element.
390    */
getElemDouble(int i)391   public double getElemDouble(int i)
392   {
393     return getElem(i);
394   }
395 
396   /**
397    * Returns an element from a particular data bank, converted to a
398    * <code>double</code>.  The offset (specified in the constructor) is
399    * added to <code>i</code> before accessing the underlying data array.
400    *
401    * @param bank the bank index.
402    * @param i the element index.
403    * @return The element.
404    */
getElemDouble(int bank, int i)405   public double getElemDouble(int bank, int i)
406   {
407     return getElem(bank, i);
408   }
409 
410   /**
411    * Sets an element in the first data bank.  The offset (specified in the
412    * constructor) is added to <code>i</code> before updating the underlying
413    * data array.
414    *
415    * @param i the element index.
416    * @param val the new element value.
417    */
setElemDouble(int i, double val)418   public void setElemDouble(int i, double val)
419   {
420     setElem(i, (int) val);
421   }
422 
423   /**
424    * Sets an element in a particular data bank.  The offset (specified in the
425    * constructor) is added to <code>i</code> before updating the underlying
426    * data array.
427    *
428    * @param bank the data bank index.
429    * @param i the element index.
430    * @param val the new element value.
431    */
setElemDouble(int bank, int i, double val)432   public void setElemDouble(int bank, int i, double val)
433   {
434     setElem(bank, i, (int) val);
435   }
436 }
437