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