1. /*
  2. * @(#)DataBuffer.java 1.18 01/11/29
  3. *
  4. * Copyright 2002 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 API image classes
  36. * use only TYPE_BYTE, TYPE_USHORT, and TYPE_INT DataBuffers to store image
  37. * 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 < 0 || 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. public int getDataType() {
  154. return dataType;
  155. }
  156. /** Returns the size (in array elements) of all banks. */
  157. public int getSize() {
  158. return size;
  159. }
  160. /** Returns the offset of the default bank in array elements. */
  161. public int getOffset() {
  162. return offset;
  163. }
  164. /** Returns the offsets (in array elements) of all the banks. */
  165. public int[] getOffsets() {
  166. return (int[])offsets.clone();
  167. }
  168. /** Returns the number of banks in this DataBuffer. */
  169. public int getNumBanks() {
  170. return banks;
  171. }
  172. /**
  173. * Returns the requested data array element from the first (default) bank
  174. * as an integer.
  175. */
  176. public int getElem(int i) {
  177. return getElem(0,i);
  178. }
  179. /**
  180. * Returns the requested data array element from the specified bank
  181. * as an integer.
  182. */
  183. public abstract int getElem(int bank, int i);
  184. /**
  185. * Sets the requested data array element in the first (default) bank
  186. * from the given integer.
  187. */
  188. public void setElem(int i, int val) {
  189. setElem(0,i,val);
  190. }
  191. /**
  192. * Sets the requested data array element in the specified bank
  193. * from the given integer.
  194. */
  195. public abstract void setElem(int bank, int i, int val);
  196. /**
  197. * Returns the requested data array element from the first (default) bank
  198. * as a float. The implementation in this class is to cast getElem(i)
  199. * to a float. Subclasses may override this method if another
  200. * implementation is needed.
  201. */
  202. public float getElemFloat(int i) {
  203. return (float)getElem(i);
  204. }
  205. /**
  206. * Returns the requested data array element from the specified bank
  207. * as a float. The implementation in this class is to cast getElem(bank, i)
  208. * to a float. Subclasses may override this method if another
  209. * implementation is needed.
  210. */
  211. public float getElemFloat(int bank, int i) {
  212. return (float)getElem(bank,i);
  213. }
  214. /**
  215. * Sets the requested data array element in the first (default) bank
  216. * from the given float. The implementation in this class is to cast
  217. * val to an int and call setElem. Subclasses may override this method
  218. * if another implementation is needed.
  219. */
  220. public void setElemFloat(int i, float val) {
  221. setElem(i,(int)val);
  222. }
  223. /**
  224. * Sets the requested data array element in the specified bank
  225. * from the given float. The implementation in this class is to cast * val to an int and call setElem. Subclasses may override this method
  226. * if another implementation is needed.
  227. */
  228. public void setElemFloat(int bank, int i, float val) {
  229. setElem(bank,i,(int)val);
  230. }
  231. /**
  232. * Returns the requested data array element from the first (default) bank
  233. * as a double. The implementation in this class is to cast getElem(i)
  234. * to a double. Subclasses may override this method if another
  235. * implementation is needed.
  236. */
  237. public double getElemDouble(int i) {
  238. return (double)getElem(i);
  239. }
  240. /**
  241. * Returns the requested data array element from the specified bank as
  242. * a double. The implementation in this class is to cast getElem(bank, i)
  243. * to a double. Subclasses may override this method if another
  244. * implementation is needed.
  245. */
  246. public double getElemDouble(int bank, int i) {
  247. return (double)getElem(bank,i);
  248. }
  249. /**
  250. * Sets the requested data array element in the first (default) bank
  251. * from the given double. The implementation in this class is to cast
  252. * val to an int and call setElem. Subclasses may override this method
  253. * if another implementation is needed.
  254. */
  255. public void setElemDouble(int i, double val) {
  256. setElem(i,(int)val);
  257. }
  258. /**
  259. * Sets the requested data array element in the specified bank
  260. * from the given double. The implementation in this class is to cast
  261. * val to an int and call setElem. Subclasses may override this method
  262. * if another implementation is needed.
  263. */
  264. public void setElemDouble(int bank, int i, double val) {
  265. setElem(bank,i,(int)val);
  266. }
  267. static int[] toIntArray(Object obj) {
  268. if (obj instanceof int[]) {
  269. return (int[])obj;
  270. } else if (obj == null) {
  271. return null;
  272. } else if (obj instanceof short[]) {
  273. short sdata[] = (short[])obj;
  274. int idata[] = new int[sdata.length];
  275. for (int i = 0; i < sdata.length; i++) {
  276. idata[i] = (int)sdata[i];
  277. }
  278. return idata;
  279. } else if (obj instanceof byte[]) {
  280. byte bdata[] = (byte[])obj;
  281. int idata[] = new int[bdata.length];
  282. for (int i = 0; i < bdata.length; i++) {
  283. idata[i] = 0xff & (int)bdata[i];
  284. }
  285. return idata;
  286. }
  287. return null;
  288. }
  289. }