1. /*
  2. * @(#)DataBuffer.java 1.29 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /* ****************************************************************
  8. ******************************************************************
  9. ******************************************************************
  10. *** COPYRIGHT (c) Eastman Kodak Company, 1997
  11. *** As an unpublished work pursuant to Title 17 of the United
  12. *** States Code. All rights reserved.
  13. ******************************************************************
  14. ******************************************************************
  15. ******************************************************************/
  16. package java.awt.image;
  17. /**
  18. * This class exists to wrap one or more data arrays. Each data array in
  19. * the DataBuffer is referred to as a bank. Accessor methods for getting
  20. * and setting elements of the DataBuffer's banks exist with and without
  21. * a bank specifier. The methods without a bank specifier use the default 0th
  22. * bank. The DataBuffer can optionally take an offset per bank, so that
  23. * data in an existing array can be used even if the interesting data
  24. * doesn't start at array location zero. Getting or setting the 0th
  25. * element of a bank, uses the (0+offset)th element of the array. The
  26. * size field specifies how much of the data array is available for
  27. * use. Size + offset for a given bank should never be greater
  28. * than the length of the associated data array. The data type of
  29. * a data buffer indicates the type of the data array(s) and may also
  30. * indicate additional semantics, e.g. storing unsigned 8-bit data
  31. * in elements of a byte array. The data type may be TYPE_UNDEFINED
  32. * or one of the types defined below. Other types may be added in
  33. * the future. Generally, an object of class DataBuffer will be cast down
  34. * to one of its data type specific subclasses to access data type specific
  35. * methods for improved performance. Currently, the Java 2D(tm) API
  36. * image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
  37. * TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
  38. * @see java.awt.image.Raster
  39. * @see java.awt.image.SampleModel
  40. */
  41. public abstract class DataBuffer
  42. {
  43. /** Tag for unsigned byte data. */
  44. public static final int TYPE_BYTE = 0;
  45. /** Tag for unsigned short data. */
  46. public static final int TYPE_USHORT = 1;
  47. /** Tag for signed short data. Placeholder for future use. */
  48. public static final int TYPE_SHORT = 2;
  49. /** Tag for int data. */
  50. public static final int TYPE_INT = 3;
  51. /** Tag for float data. Placeholder for future use. */
  52. public static final int TYPE_FLOAT = 4;
  53. /** Tag for double data. Placeholder for future use. */
  54. public static final int TYPE_DOUBLE = 5;
  55. /** Tag for undefined data. */
  56. public static final int TYPE_UNDEFINED = 32;
  57. /** The data type of this DataBuffer. */
  58. protected int dataType;
  59. /** The number of banks in this DataBuffer. */
  60. protected int banks;
  61. /** Offset into default (first) bank from which to get the first element. */
  62. protected int offset;
  63. /** Usable size of all banks. */
  64. protected int size;
  65. /** Offsets into all banks. */
  66. protected int offsets[];
  67. /** Size of the data types indexed by DataType tags defined above. */
  68. private static final int dataTypeSize[] = {8,16,16,32,32,64};
  69. /** Returns the size (in bits) of the data type, given a datatype tag.
  70. * @param type the value of one of the defined datatype tags
  71. * @return the size of the data type
  72. * @throws IllegalArgumentException if <code>type</code> is less than
  73. * zero or greater than {@link #TYPE_DOUBLE}
  74. */
  75. public static int getDataTypeSize(int type) {
  76. if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
  77. throw new IllegalArgumentException("Unknown data type "+type);
  78. }
  79. return dataTypeSize[type];
  80. }
  81. /**
  82. * Constructs a DataBuffer containing one bank of the specified
  83. * data type and size.
  84. * @param dataType the data type of this <code>DataBuffer</code>
  85. * @param size the size of the banks
  86. */
  87. protected DataBuffer(int dataType, int size) {
  88. this.dataType = dataType;
  89. this.banks = 1;
  90. this.size = size;
  91. this.offset = 0;
  92. this.offsets = new int[1]; // init to 0 by new
  93. }
  94. /**
  95. * Constructs a DataBuffer containing the specified number of
  96. * banks. Each bank has the specified size and an offset of 0.
  97. * @param dataType the data type of this <code>DataBuffer</code>
  98. * @param size the size of the banks
  99. * @param numBanks the number of banks in this
  100. * <code>DataBuffer</code>
  101. */
  102. protected DataBuffer(int dataType, int size, int numBanks) {
  103. this.dataType = dataType;
  104. this.banks = numBanks;
  105. this.size = size;
  106. this.offset = 0;
  107. this.offsets = new int[banks]; // init to 0 by new
  108. }
  109. /**
  110. * Constructs a DataBuffer that contains the specified number
  111. * of banks. Each bank has the specified datatype, size and offset.
  112. * @param dataType the data type of this <code>DataBuffer</code>
  113. * @param size the size of the banks
  114. * @param numBanks the number of banks in this
  115. * <code>DataBuffer</code>
  116. * @param offset the offset for each bank
  117. */
  118. protected DataBuffer(int dataType, int size, int numBanks, int offset) {
  119. this.dataType = dataType;
  120. this.banks = numBanks;
  121. this.size = size;
  122. this.offset = offset;
  123. this.offsets = new int[numBanks];
  124. for (int i = 0; i < numBanks; i++) {
  125. this.offsets[i] = offset;
  126. }
  127. }
  128. /**
  129. * Constructs a DataBuffer which contains the specified number
  130. * of banks. Each bank has the specified datatype and size. The
  131. * offset for each bank is specified by its respective entry in
  132. * the offsets array.
  133. * @param dataType the data type of this <code>DataBuffer</code>
  134. * @param size the size of the banks
  135. * @param numBanks the number of banks in this
  136. * <code>DataBuffer</code>
  137. * @param offsets an array containing an offset for each bank.
  138. * @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
  139. * does not equal the length of <code>offsets</code>
  140. */
  141. protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
  142. if (numBanks != offsets.length) {
  143. throw new ArrayIndexOutOfBoundsException("Number of banks" +
  144. " does not match number of bank offsets");
  145. }
  146. this.dataType = dataType;
  147. this.banks = numBanks;
  148. this.size = size;
  149. this.offset = offsets[0];
  150. this.offsets = (int[])offsets.clone();
  151. }
  152. /** Returns the data type of this DataBuffer.
  153. * @return the data type of this <code>DataBuffer</code>.
  154. */
  155. public int getDataType() {
  156. return dataType;
  157. }
  158. /** Returns the size (in array elements) of all banks.
  159. * @return the size of all banks.
  160. */
  161. public int getSize() {
  162. return size;
  163. }
  164. /** Returns the offset of the default bank in array elements.
  165. * @return the offset of the default bank.
  166. */
  167. public int getOffset() {
  168. return offset;
  169. }
  170. /** Returns the offsets (in array elements) of all the banks.
  171. * @return the offsets of all banks.
  172. */
  173. public int[] getOffsets() {
  174. return (int[])offsets.clone();
  175. }
  176. /** Returns the number of banks in this DataBuffer.
  177. * @return the number of banks.
  178. */
  179. public int getNumBanks() {
  180. return banks;
  181. }
  182. /**
  183. * Returns the requested data array element from the first (default) bank
  184. * as an integer.
  185. * @param i the index of the requested data array element
  186. * @return the data array element at the specified index.
  187. * @see #setElem(int, int)
  188. * @see #setElem(int, int, int)
  189. */
  190. public int getElem(int i) {
  191. return getElem(0,i);
  192. }
  193. /**
  194. * Returns the requested data array element from the specified bank
  195. * as an integer.
  196. * @param bank the specified bank
  197. * @param i the index of the requested data array element
  198. * @return the data array element at the specified index from the
  199. * specified bank at the specified index.
  200. * @see #setElem(int, int)
  201. * @see #setElem(int, int, int)
  202. */
  203. public abstract int getElem(int bank, int i);
  204. /**
  205. * Sets the requested data array element in the first (default) bank
  206. * from the given integer.
  207. * @param i the specified index into the data array
  208. * @param val the data to set the element at the specified index in
  209. * the data array
  210. * @see #getElem(int)
  211. * @see #getElem(int, int)
  212. */
  213. public void setElem(int i, int val) {
  214. setElem(0,i,val);
  215. }
  216. /**
  217. * Sets the requested data array element in the specified bank
  218. * from the given integer.
  219. * @param bank the specified bank
  220. * @param i the specified index into the data array
  221. * @param val the data to set the element in the specified bank
  222. * at the specified index in the data array
  223. * @see #getElem(int)
  224. * @see #getElem(int, int)
  225. */
  226. public abstract void setElem(int bank, int i, int val);
  227. /**
  228. * Returns the requested data array element from the first (default) bank
  229. * as a float. The implementation in this class is to cast getElem(i)
  230. * to a float. Subclasses may override this method if another
  231. * implementation is needed.
  232. * @param i the index of the requested data array element
  233. * @return a float value representing the data array element at the
  234. * specified index.
  235. * @see #setElemFloat(int, float)
  236. * @see #setElemFloat(int, int, float)
  237. */
  238. public float getElemFloat(int i) {
  239. return (float)getElem(i);
  240. }
  241. /**
  242. * Returns the requested data array element from the specified bank
  243. * as a float. The implementation in this class is to cast
  244. * {@link #getElem(int, int)}
  245. * to a float. Subclasses can override this method if another
  246. * implementation is needed.
  247. * @param bank the specified bank
  248. * @param i the index of the requested data array element
  249. * @return a float value representing the data array element from the
  250. * specified bank at the specified index.
  251. * @see #setElemFloat(int, float)
  252. * @see #setElemFloat(int, int, float)
  253. */
  254. public float getElemFloat(int bank, int i) {
  255. return (float)getElem(bank,i);
  256. }
  257. /**
  258. * Sets the requested data array element in the first (default) bank
  259. * from the given float. The implementation in this class is to cast
  260. * val to an int and call {@link #setElem(int, int)}. Subclasses
  261. * can override this method if another implementation is needed.
  262. * @param i the specified index
  263. * @param val the value to set the element at the specified index in
  264. * the data array
  265. * @see #getElemFloat(int)
  266. * @see #getElemFloat(int, int)
  267. */
  268. public void setElemFloat(int i, float val) {
  269. setElem(i,(int)val);
  270. }
  271. /**
  272. * Sets the requested data array element in the specified bank
  273. * from the given float. The implementation in this class is to cast
  274. * val to an int and call {@link #setElem(int, int)}. Subclasses can
  275. * override this method if another implementation is needed.
  276. * @param bank the specified bank
  277. * @param i the specified index
  278. * @param val the value to set the element in the specified bank at
  279. * the specified index in the data array
  280. * @see #getElemFloat(int)
  281. * @see #getElemFloat(int, int)
  282. */
  283. public void setElemFloat(int bank, int i, float val) {
  284. setElem(bank,i,(int)val);
  285. }
  286. /**
  287. * Returns the requested data array element from the first (default) bank
  288. * as a double. The implementation in this class is to cast
  289. * {@link #getElem(int)}
  290. * to a double. Subclasses can override this method if another
  291. * implementation is needed.
  292. * @param i the specified index
  293. * @return a double value representing the element at the specified
  294. * index in the data array.
  295. * @see #setElemDouble(int, double)
  296. * @see #setElemDouble(int, int, double)
  297. */
  298. public double getElemDouble(int i) {
  299. return (double)getElem(i);
  300. }
  301. /**
  302. * Returns the requested data array element from the specified bank as
  303. * a double. The implementation in this class is to cast getElem(bank, i)
  304. * to a double. Subclasses may override this method if another
  305. * implementation is needed.
  306. * @param bank the specified bank
  307. * @param i the specified index
  308. * @return a double value representing the element from the specified
  309. * bank at the specified index in the data array.
  310. * @see #setElemDouble(int, double)
  311. * @see #setElemDouble(int, int, double)
  312. */
  313. public double getElemDouble(int bank, int i) {
  314. return (double)getElem(bank,i);
  315. }
  316. /**
  317. * Sets the requested data array element in the first (default) bank
  318. * from the given double. The implementation in this class is to cast
  319. * val to an int and call {@link #setElem(int, int)}. Subclasses can
  320. * override this method if another implementation is needed.
  321. * @param i the specified index
  322. * @param val the value to set the element at the specified index
  323. * in the data array
  324. * @see #getElemDouble(int)
  325. * @see #getElemDouble(int, int)
  326. */
  327. public void setElemDouble(int i, double val) {
  328. setElem(i,(int)val);
  329. }
  330. /**
  331. * Sets the requested data array element in the specified bank
  332. * from the given double. The implementation in this class is to cast
  333. * val to an int and call {@link #setElem(int, int)}. Subclasses can
  334. * override this method if another implementation is needed.
  335. * @param bank the specified bank
  336. * @param i the specified index
  337. * @param val the value to set the element in the specified bank
  338. * at the specified index of the data array
  339. * @see #getElemDouble(int)
  340. * @see #getElemDouble(int, int)
  341. */
  342. public void setElemDouble(int bank, int i, double val) {
  343. setElem(bank,i,(int)val);
  344. }
  345. static int[] toIntArray(Object obj) {
  346. if (obj instanceof int[]) {
  347. return (int[])obj;
  348. } else if (obj == null) {
  349. return null;
  350. } else if (obj instanceof short[]) {
  351. short sdata[] = (short[])obj;
  352. int idata[] = new int[sdata.length];
  353. for (int i = 0; i < sdata.length; i++) {
  354. idata[i] = (int)sdata[i] & 0xffff;
  355. }
  356. return idata;
  357. } else if (obj instanceof byte[]) {
  358. byte bdata[] = (byte[])obj;
  359. int idata[] = new int[bdata.length];
  360. for (int i = 0; i < bdata.length; i++) {
  361. idata[i] = 0xff & (int)bdata[i];
  362. }
  363. return idata;
  364. }
  365. return null;
  366. }
  367. }