1. /*
  2. * @(#)Raster.java 1.59 03/01/23
  3. *
  4. * Copyright 2003 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. import java.awt.Rectangle;
  18. import java.awt.Point;
  19. import sun.awt.image.ByteInterleavedRaster;
  20. import sun.awt.image.ShortInterleavedRaster;
  21. import sun.awt.image.IntegerInterleavedRaster;
  22. import sun.awt.image.ByteBandedRaster;
  23. import sun.awt.image.ShortBandedRaster;
  24. import sun.awt.image.BytePackedRaster;
  25. import sun.awt.image.SunWritableRaster;
  26. /**
  27. * A class representing a rectangular array of pixels. A Raster
  28. * encapsulates a DataBuffer that stores the sample values and a
  29. * SampleModel that describes how to locate a given sample value in a
  30. * DataBuffer.
  31. * <p>
  32. * A Raster defines values for pixels occupying a particular
  33. * rectangular area of the plane, not necessarily including (0, 0).
  34. * The rectangle, known as the Raster's bounding rectangle and
  35. * available by means of the getBounds method, is defined by minX,
  36. * minY, width, and height values. The minX and minY values define
  37. * the coordinate of the upper left corner of the Raster. References
  38. * to pixels outside of the bounding rectangle may result in an
  39. * exception being thrown, or may result in references to unintended
  40. * elements of the Raster's associated DataBuffer. It is the user's
  41. * responsibility to avoid accessing such pixels.
  42. * <p>
  43. * A SampleModel describes how samples of a Raster
  44. * are stored in the primitive array elements of a DataBuffer.
  45. * Samples may be stored one per data element, as in a
  46. * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
  47. * an element, as in a SinglePixelPackedSampleModel or
  48. * MultiPixelPackedSampleModel. The SampleModel is also
  49. * controls whether samples are sign extended, allowing unsigned
  50. * data to be stored in signed Java data types such as byte, short, and
  51. * int.
  52. * <p>
  53. * Although a Raster may live anywhere in the plane, a SampleModel
  54. * makes use of a simple coordinate system that starts at (0, 0). A
  55. * Raster therefore contains a translation factor that allows pixel
  56. * locations to be mapped between the Raster's coordinate system and
  57. * that of the SampleModel. The translation from the SampleModel
  58. * coordinate system to that of the Raster may be obtained by the
  59. * getSampleModelTranslateX and getSampleModelTranslateY methods.
  60. * <p>
  61. * A Raster may share a DataBuffer with another Raster either by
  62. * explicit construction or by the use of the createChild and
  63. * createTranslatedChild methods. Rasters created by these methods
  64. * can return a reference to the Raster they were created from by
  65. * means of the getParent method. For a Raster that was not
  66. * constructed by means of a call to createTranslatedChild or
  67. * createChild, getParent will return null.
  68. * <p>
  69. * The createTranslatedChild method returns a new Raster that
  70. * shares all of the data of the current Raster, but occupies a
  71. * bounding rectangle of the same width and height but with a
  72. * different starting point. For example, if the parent Raster
  73. * occupied the region (10, 10) to (100, 100), and the translated
  74. * Raster was defined to start at (50, 50), then pixel (20, 20) of the
  75. * parent and pixel (60, 60) of the child occupy the same location in
  76. * the DataBuffer shared by the two Rasters. In the first case, (-10,
  77. * -10) should be added to a pixel coordinate to obtain the
  78. * corresponding SampleModel coordinate, and in the second case (-50,
  79. * -50) should be added.
  80. * <p>
  81. * The translation between a parent and child Raster may be
  82. * determined by subtracting the child's sampleModelTranslateX and
  83. * sampleModelTranslateY values from those of the parent.
  84. * <p>
  85. * The createChild method may be used to create a new Raster
  86. * occupying only a subset of its parent's bounding rectangle
  87. * (with the same or a translated coordinate system) or
  88. * with a subset of the bands of its parent.
  89. * <p>
  90. * All constructors are protected. The correct way to create a
  91. * Raster is to use one of the static create methods defined in this
  92. * class. These methods create instances of Raster that use the
  93. * standard Interleaved, Banded, and Packed SampleModels and that may
  94. * be processed more efficiently than a Raster created by combining
  95. * an externally generated SampleModel and DataBuffer.
  96. * @see java.awt.image.DataBuffer
  97. * @see java.awt.image.SampleModel
  98. * @see java.awt.image.PixelInterleavedSampleModel
  99. * @see java.awt.image.BandedSampleModel
  100. * @see java.awt.image.SinglePixelPackedSampleModel
  101. * @see java.awt.image.MultiPixelPackedSampleModel
  102. */
  103. public class Raster {
  104. /**
  105. * The SampleModel that describes how pixels from this Raster
  106. * are stored in the DataBuffer.
  107. */
  108. protected SampleModel sampleModel;
  109. /** The DataBuffer that stores the image data. */
  110. protected DataBuffer dataBuffer;
  111. /** The X coordinate of the upper-left pixel of this Raster. */
  112. protected int minX;
  113. /** The Y coordinate of the upper-left pixel of this Raster. */
  114. protected int minY;
  115. /** The width of this Raster. */
  116. protected int width;
  117. /** The height of this Raster. */
  118. protected int height;
  119. /**
  120. * The X translation from the coordinate space of the
  121. * Raster's SampleModel to that of the Raster.
  122. */
  123. protected int sampleModelTranslateX;
  124. /**
  125. * The Y translation from the coordinate space of the
  126. * Raster's SampleModel to that of the Raster.
  127. */
  128. protected int sampleModelTranslateY;
  129. /** The number of bands in the Raster. */
  130. protected int numBands;
  131. /** The number of DataBuffer data elements per pixel. */
  132. protected int numDataElements;
  133. /** The parent of this Raster, or null. */
  134. protected Raster parent;
  135. static private native void initIDs();
  136. static {
  137. ColorModel.loadLibraries();
  138. initIDs();
  139. }
  140. /**
  141. * Creates a Raster based on a PixelInterleavedSampleModel with the
  142. * specified data type, width, height, and number of bands.
  143. *
  144. * <p> The upper left corner of the Raster is given by the
  145. * location argument. If location is null, (0, 0) will be used.
  146. * The dataType parameter should be one of the enumerated values
  147. * defined in the DataBuffer class.
  148. *
  149. * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
  150. * Rasters are not supported. To create a 1-band Raster of type
  151. * <code>DataBuffer.TYPE_INT</code>, use
  152. * Raster.createPackedRaster().
  153. * <p> The only dataTypes supported currently are TYPE_BYTE
  154. * and TYPE_USHORT.
  155. * @param dataType the data type for storing samples
  156. * @param w the width in pixels of the image data
  157. * @param h the height in pixels of the image data
  158. * @param bands the number of bands
  159. * @param location the upper-left corner of the <code>Raster</code>
  160. * @return a WritableRaster object with the specified data type,
  161. * width, height and number of bands.
  162. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  163. * is less than or equal to zero, or computing either
  164. * <code>location.x + w</code> or
  165. * <code>location.y + h</code> results in integer
  166. * overflow
  167. */
  168. public static WritableRaster createInterleavedRaster(int dataType,
  169. int w, int h,
  170. int bands,
  171. Point location) {
  172. int[] bandOffsets = new int[bands];
  173. for (int i = 0; i < bands; i++) {
  174. bandOffsets[i] = i;
  175. }
  176. return createInterleavedRaster(dataType, w, h, w*bands, bands,
  177. bandOffsets, location);
  178. }
  179. /**
  180. * Creates a Raster based on a PixelInterleavedSampleModel with the
  181. * specified data type, width, height, scanline stride, pixel
  182. * stride, and band offsets. The number of bands is inferred from
  183. * bandOffsets.length.
  184. *
  185. * <p> The upper left corner of the Raster is given by the
  186. * location argument. If location is null, (0, 0) will be used.
  187. * The dataType parameter should be one of the enumerated values
  188. * defined in the DataBuffer class.
  189. *
  190. * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
  191. * Rasters are not supported. To create a 1-band Raster of type
  192. * <code>DataBuffer.TYPE_INT</code>, use
  193. * Raster.createPackedRaster().
  194. * <p> The only dataTypes supported currently are TYPE_BYTE
  195. * and TYPE_USHORT.
  196. * @param dataType the data type for storing samples
  197. * @param w the width in pixels of the image data
  198. * @param h the height in pixels of the image data
  199. * @param scanlineStride the line stride of the image data
  200. * @param pixelStride the pixel stride of the image data
  201. * @param bandOffsets the offsets of all bands
  202. * @param location the upper-left corner of the <code>Raster</code>
  203. * @return a WritableRaster object with the specified data type,
  204. * width, height, scanline stride, pixel stride and band
  205. * offsets.
  206. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  207. * is less than or equal to zero, or computing either
  208. * <code>location.x + w</code> or
  209. * <code>location.y + h</code> results in integer
  210. * overflow
  211. * @throws IllegalArgumentException if <code>dataType</code> is not
  212. * one of the supported data types, which are
  213. * <code>DataBuffer.TYPE_BYTE</code>, or
  214. * <code>DataBuffer.TYPE_USHORT</code>.
  215. */
  216. public static WritableRaster createInterleavedRaster(int dataType,
  217. int w, int h,
  218. int scanlineStride,
  219. int pixelStride,
  220. int bandOffsets[],
  221. Point location) {
  222. DataBuffer d;
  223. int bands = bandOffsets.length;
  224. int maxBandOff = bandOffsets[0];
  225. for (int i=1; i < bands; i++) {
  226. if (bandOffsets[i] > maxBandOff) {
  227. maxBandOff = bandOffsets[i];
  228. }
  229. }
  230. int size = maxBandOff + scanlineStride*(h-1) + pixelStride*(w-1) + 1;
  231. switch(dataType) {
  232. case DataBuffer.TYPE_BYTE:
  233. d = new DataBufferByte(size);
  234. break;
  235. case DataBuffer.TYPE_USHORT:
  236. d = new DataBufferUShort(size);
  237. break;
  238. default:
  239. throw new IllegalArgumentException("Unsupported data type " +
  240. dataType);
  241. }
  242. return createInterleavedRaster(d, w, h, scanlineStride,
  243. pixelStride, bandOffsets, location);
  244. }
  245. /**
  246. * Creates a Raster based on a BandedSampleModel with the
  247. * specified data type, width, height, and number of bands.
  248. *
  249. * <p> The upper left corner of the Raster is given by the
  250. * location argument. If location is null, (0, 0) will be used.
  251. * The dataType parameter should be one of the enumerated values
  252. * defined in the DataBuffer class.
  253. *
  254. * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
  255. * and TYPE_INT.
  256. * @param dataType the data type for storing samples
  257. * @param w the width in pixels of the image data
  258. * @param h the height in pixels of the image data
  259. * @param bands the number of bands
  260. * @param location the upper-left corner of the <code>Raster</code>
  261. * @return a WritableRaster object with the specified data type,
  262. * width, height and number of bands.
  263. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  264. * is less than or equal to zero, or computing either
  265. * <code>location.x + w</code> or
  266. * <code>location.y + h</code> results in integer
  267. * overflow
  268. * @throws ArrayIndexOutOfBoundsException if <code>bands</code>
  269. * is less than 1
  270. */
  271. public static WritableRaster createBandedRaster(int dataType,
  272. int w, int h,
  273. int bands,
  274. Point location) {
  275. if (bands < 1) {
  276. throw new ArrayIndexOutOfBoundsException("Number of bands ("+
  277. bands+") must"+
  278. " be greater than 0");
  279. }
  280. int[] bankIndices = new int[bands];
  281. int[] bandOffsets = new int[bands];
  282. for (int i = 0; i < bands; i++) {
  283. bankIndices[i] = i;
  284. bandOffsets[i] = 0;
  285. }
  286. return createBandedRaster(dataType, w, h, w,
  287. bankIndices, bandOffsets,
  288. location);
  289. }
  290. /**
  291. * Creates a Raster based on a BandedSampleModel with the
  292. * specified data type, width, height, scanline stride, bank
  293. * indices and band offsets. The number of bands is inferred from
  294. * bankIndices.length and bandOffsets.length, which must be the
  295. * same.
  296. *
  297. * <p> The upper left corner of the Raster is given by the
  298. * location argument. The dataType parameter should be one of the
  299. * enumerated values defined in the DataBuffer class.
  300. *
  301. * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
  302. * and TYPE_INT.
  303. * @param dataType the data type for storing samples
  304. * @param w the width in pixels of the image data
  305. * @param h the height in pixels of the image data
  306. * @param scanlineStride the line stride of the image data
  307. * @param bankIndices the bank indices for each band
  308. * @param bandOffsets the offsets of all bands
  309. * @param location the upper-left corner of the <code>Raster</code>
  310. * @return a WritableRaster object with the specified data type,
  311. * width, height, scanline stride, bank indices and band
  312. * offsets.
  313. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  314. * is less than or equal to zero, or computing either
  315. * <code>location.x + w</code> or
  316. * <code>location.y + h</code> results in integer
  317. * overflow
  318. * @throws IllegalArgumentException if <code>dataType</code> is not
  319. * one of the supported data types, which are
  320. * <code>DataBuffer.TYPE_BYTE</code>,
  321. * <code>DataBuffer.TYPE_USHORT</code>
  322. * or <code>DataBuffer.TYPE_INT</code>
  323. * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code>
  324. * or <code>bandOffsets</code> is <code>null</code>
  325. */
  326. public static WritableRaster createBandedRaster(int dataType,
  327. int w, int h,
  328. int scanlineStride,
  329. int bankIndices[],
  330. int bandOffsets[],
  331. Point location) {
  332. DataBuffer d;
  333. int bands = bandOffsets.length;
  334. if (bankIndices == null) {
  335. throw new
  336. ArrayIndexOutOfBoundsException("Bank indices array is null");
  337. }
  338. if (bandOffsets == null) {
  339. throw new
  340. ArrayIndexOutOfBoundsException("Band offsets array is null");
  341. }
  342. // Figure out the #banks and the largest band offset
  343. int maxBank = bankIndices[0];
  344. int maxBandOff = bandOffsets[0];
  345. for (int i = 1; i < bands; i++) {
  346. if (bankIndices[i] > maxBank) {
  347. maxBank = bankIndices[i];
  348. }
  349. if (bandOffsets[i] > maxBandOff) {
  350. maxBandOff = bandOffsets[i];
  351. }
  352. }
  353. int banks = maxBank + 1;
  354. int size = maxBandOff + scanlineStride*(h-1) + (w-1) + 1;
  355. switch(dataType) {
  356. case DataBuffer.TYPE_BYTE:
  357. d = new DataBufferByte(size, banks);
  358. break;
  359. case DataBuffer.TYPE_USHORT:
  360. d = new DataBufferUShort(size, banks);
  361. break;
  362. case DataBuffer.TYPE_INT:
  363. d = new DataBufferInt(size, banks);
  364. break;
  365. default:
  366. throw new IllegalArgumentException("Unsupported data type " +
  367. dataType);
  368. }
  369. return createBandedRaster(d, w, h, scanlineStride,
  370. bankIndices, bandOffsets, location);
  371. }
  372. /**
  373. * Creates a Raster based on a SinglePixelPackedSampleModel with
  374. * the specified data type, width, height, and band masks.
  375. * The number of bands is inferred from bandMasks.length.
  376. *
  377. * <p> The upper left corner of the Raster is given by the
  378. * location argument. If location is null, (0, 0) will be used.
  379. * The dataType parameter should be one of the enumerated values
  380. * defined in the DataBuffer class.
  381. *
  382. * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
  383. * and TYPE_INT.
  384. * @param dataType the data type for storing samples
  385. * @param w the width in pixels of the image data
  386. * @param h the height in pixels of the image data
  387. * @param bandMasks an array containing an entry for each band
  388. * @param location the upper-left corner of the <code>Raster</code>
  389. * @return a WritableRaster object with the specified data type,
  390. * width, height, and band masks.
  391. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  392. * is less than or equal to zero, or computing either
  393. * <code>location.x + w</code> or
  394. * <code>location.y + h</code> results in integer
  395. * overflow
  396. * @throws IllegalArgumentException if <code>dataType</code> is not
  397. * one of the supported data types, which are
  398. * <code>DataBuffer.TYPE_BYTE</code>,
  399. * <code>DataBuffer.TYPE_USHORT</code>
  400. * or <code>DataBuffer.TYPE_INT</code>
  401. */
  402. public static WritableRaster createPackedRaster(int dataType,
  403. int w, int h,
  404. int bandMasks[],
  405. Point location) {
  406. DataBuffer d;
  407. switch(dataType) {
  408. case DataBuffer.TYPE_BYTE:
  409. d = new DataBufferByte(w*h);
  410. break;
  411. case DataBuffer.TYPE_USHORT:
  412. d = new DataBufferUShort(w*h);
  413. break;
  414. case DataBuffer.TYPE_INT:
  415. d = new DataBufferInt(w*h);
  416. break;
  417. default:
  418. throw new IllegalArgumentException("Unsupported data type " +
  419. dataType);
  420. }
  421. return createPackedRaster(d, w, h, w, bandMasks, location);
  422. }
  423. /**
  424. * Creates a Raster based on a packed SampleModel with the
  425. * specified data type, width, height, number of bands, and bits
  426. * per band. If the number of bands is one, the SampleModel will
  427. * be a MultiPixelPackedSampleModel.
  428. *
  429. * <p> If the number of bands is more than one, the SampleModel
  430. * will be a SinglePixelPackedSampleModel, with each band having
  431. * bitsPerBand bits. In either case, the requirements on dataType
  432. * and bitsPerBand imposed by the corresponding SampleModel must
  433. * be met.
  434. *
  435. * <p> The upper left corner of the Raster is given by the
  436. * location argument. If location is null, (0, 0) will be used.
  437. * The dataType parameter should be one of the enumerated values
  438. * defined in the DataBuffer class.
  439. *
  440. * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
  441. * and TYPE_INT.
  442. * @param dataType the data type for storing samples
  443. * @param w the width in pixels of the image data
  444. * @param h the height in pixels of the image data
  445. * @param bands the number of bands
  446. * @param bitsPerBand the number of bits per band
  447. * @param location the upper-left corner of the <code>Raster</code>
  448. * @return a WritableRaster object with the specified data type,
  449. * width, height, number of bands, and bits per band.
  450. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  451. * is less than or equal to zero, or computing either
  452. * <code>location.x + w</code> or
  453. * <code>location.y + h</code> results in integer
  454. * overflow
  455. * @throws IllegalArgumentException if the product of
  456. * <code>bitsPerBand</code> and <code>bands</code> is
  457. * greater than the number of bits held by
  458. * <code>dataType</code>
  459. * @throws IllegalArgumentException if <code>bitsPerBand</code> or
  460. * <code>bands</code> is not greater than zero
  461. * @throws IllegalArgumentException if <code>dataType</code> is not
  462. * one of the supported data types, which are
  463. * <code>DataBuffer.TYPE_BYTE</code>,
  464. * <code>DataBuffer.TYPE_USHORT</code>
  465. * or <code>DataBuffer.TYPE_INT</code>
  466. */
  467. public static WritableRaster createPackedRaster(int dataType,
  468. int w, int h,
  469. int bands,
  470. int bitsPerBand,
  471. Point location) {
  472. DataBuffer d;
  473. if (bands <= 0) {
  474. throw new IllegalArgumentException("Number of bands ("+bands+
  475. ") must be greater than 0");
  476. }
  477. if (bitsPerBand <= 0) {
  478. throw new IllegalArgumentException("Bits per band ("+bitsPerBand+
  479. ") must be greater than 0");
  480. }
  481. if (bands != 1) {
  482. int[] masks = new int[bands];
  483. int mask = (1 << bitsPerBand) - 1;
  484. int shift = (bands-1)*bitsPerBand;
  485. /* Make sure the total mask size will fit in the data type */
  486. if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
  487. throw new IllegalArgumentException("bitsPerBand("+
  488. bitsPerBand+") * bands is "+
  489. " greater than data type "+
  490. "size.");
  491. }
  492. switch(dataType) {
  493. case DataBuffer.TYPE_BYTE:
  494. case DataBuffer.TYPE_USHORT:
  495. case DataBuffer.TYPE_INT:
  496. break;
  497. default:
  498. throw new IllegalArgumentException("Unsupported data type " +
  499. dataType);
  500. }
  501. for (int i = 0; i < bands; i++) {
  502. masks[i] = mask << shift;
  503. shift = shift - bitsPerBand;
  504. }
  505. return createPackedRaster(dataType, w, h, masks, location);
  506. }
  507. else {
  508. double fw = w;
  509. switch(dataType) {
  510. case DataBuffer.TYPE_BYTE:
  511. d = new DataBufferByte((int)(Math.ceil(fw(8/bitsPerBand)))*h);
  512. break;
  513. case DataBuffer.TYPE_USHORT:
  514. d = new DataBufferUShort((int)(Math.ceil(fw(16/bitsPerBand)))*h);
  515. break;
  516. case DataBuffer.TYPE_INT:
  517. d = new DataBufferInt((int)(Math.ceil(fw(32/bitsPerBand)))*h);
  518. break;
  519. default:
  520. throw new IllegalArgumentException("Unsupported data type " +
  521. dataType);
  522. }
  523. return createPackedRaster(d, w, h, bitsPerBand, location);
  524. }
  525. }
  526. /**
  527. * Creates a Raster based on a PixelInterleavedSampleModel with the
  528. * specified DataBuffer, width, height, scanline stride, pixel
  529. * stride, and band offsets. The number of bands is inferred from
  530. * bandOffsets.length. The upper left corner of the Raster
  531. * is given by the location argument. If location is null, (0, 0)
  532. * will be used.
  533. * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
  534. * Rasters are not supported. To create a 1-band Raster of type
  535. * <code>DataBuffer.TYPE_INT</code>, use
  536. * Raster.createPackedRaster().
  537. * @param dataBuffer the <code>DataBuffer</code> that contains the
  538. * image data
  539. * @param w the width in pixels of the image data
  540. * @param h the height in pixels of the image data
  541. * @param scanlineStride the line stride of the image data
  542. * @param pixelStride the pixel stride of the image data
  543. * @param bandOffsets the offsets of all bands
  544. * @param location the upper-left corner of the <code>Raster</code>
  545. * @return a WritableRaster object with the specified
  546. * <code>DataBuffer</code>, width, height, scanline stride,
  547. * pixel stride and band offsets.
  548. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  549. * is less than or equal to zero, or computing either
  550. * <code>location.x + w</code> or
  551. * <code>location.y + h</code> results in integer
  552. * overflow
  553. * @throws IllegalArgumentException if <code>dataType</code> is not
  554. * one of the supported data types, which are
  555. * <code>DataBuffer.TYPE_BYTE</code>,
  556. * <code>DataBuffer.TYPE_USHORT</code>
  557. * @throws RasterFormatException if <code>dataBuffer</code> has more
  558. * than one bank.
  559. * @throws NullPointerException if <code>dataBuffer</code> is null
  560. */
  561. public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
  562. int w, int h,
  563. int scanlineStride,
  564. int pixelStride,
  565. int bandOffsets[],
  566. Point location) {
  567. if (dataBuffer == null) {
  568. throw new NullPointerException("DataBuffer cannot be null");
  569. }
  570. if (location == null) {
  571. location = new Point(0, 0);
  572. }
  573. int dataType = dataBuffer.getDataType();
  574. PixelInterleavedSampleModel csm =
  575. new PixelInterleavedSampleModel(dataType, w, h,
  576. pixelStride,
  577. scanlineStride,
  578. bandOffsets);
  579. switch(dataType) {
  580. case DataBuffer.TYPE_BYTE:
  581. return new ByteInterleavedRaster(csm, dataBuffer, location);
  582. case DataBuffer.TYPE_USHORT:
  583. return new ShortInterleavedRaster(csm, dataBuffer, location);
  584. default:
  585. throw new IllegalArgumentException("Unsupported data type " +
  586. dataType);
  587. }
  588. }
  589. /**
  590. * Creates a Raster based on a BandedSampleModel with the
  591. * specified DataBuffer, width, height, scanline stride, bank
  592. * indices, and band offsets. The number of bands is inferred
  593. * from bankIndices.length and bandOffsets.length, which must be
  594. * the same. The upper left corner of the Raster is given by the
  595. * location argument. If location is null, (0, 0) will be used.
  596. * @param dataBuffer the <code>DataBuffer</code> that contains the
  597. * image data
  598. * @param w the width in pixels of the image data
  599. * @param h the height in pixels of the image data
  600. * @param scanlineStride the line stride of the image data
  601. * @param bankIndices the bank indices for each band
  602. * @param bandOffsets the offsets of all bands
  603. * @param location the upper-left corner of the <code>Raster</code>
  604. * @return a WritableRaster object with the specified
  605. * <code>DataBuffer</code>, width, height, scanline stride,
  606. * bank indices and band offsets.
  607. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  608. * is less than or equal to zero, or computing either
  609. * <code>location.x + w</code> or
  610. * <code>location.y + h</code> results in integer
  611. * overflow
  612. * @throws IllegalArgumentException if <code>dataType</code> is not
  613. * one of the supported data types, which are
  614. * <code>DataBuffer.TYPE_BYTE</code>,
  615. * <code>DataBuffer.TYPE_USHORT</code>
  616. * or <code>DataBuffer.TYPE_INT</code>
  617. * @throws NullPointerException if <code>dataBuffer</code> is null
  618. */
  619. public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
  620. int w, int h,
  621. int scanlineStride,
  622. int bankIndices[],
  623. int bandOffsets[],
  624. Point location) {
  625. if (dataBuffer == null) {
  626. throw new NullPointerException("DataBuffer cannot be null");
  627. }
  628. if (location == null) {
  629. location = new Point(0,0);
  630. }
  631. int dataType = dataBuffer.getDataType();
  632. int bands = bankIndices.length;
  633. if (bandOffsets.length != bands) {
  634. throw new IllegalArgumentException(
  635. "bankIndices.length != bandOffsets.length");
  636. }
  637. BandedSampleModel bsm =
  638. new BandedSampleModel(dataType, w, h,
  639. scanlineStride,
  640. bankIndices, bandOffsets);
  641. switch(dataType) {
  642. case DataBuffer.TYPE_BYTE:
  643. return new ByteBandedRaster(bsm, dataBuffer, location);
  644. case DataBuffer.TYPE_USHORT:
  645. return new ShortBandedRaster(bsm, dataBuffer, location);
  646. case DataBuffer.TYPE_INT:
  647. return new SunWritableRaster(bsm, dataBuffer, location);
  648. default:
  649. throw new IllegalArgumentException("Unsupported data type " +
  650. dataType);
  651. }
  652. }
  653. /**
  654. * Creates a Raster based on a SinglePixelPackedSampleModel with
  655. * the specified DataBuffer, width, height, scanline stride, and
  656. * band masks. The number of bands is inferred from bandMasks.length.
  657. * The upper left corner of the Raster is given by
  658. * the location argument. If location is null, (0, 0) will be used.
  659. * @param dataBuffer the <code>DataBuffer</code> that contains the
  660. * image data
  661. * @param w the width in pixels of the image data
  662. * @param h the height in pixels of the image data
  663. * @param scanlineStride the line stride of the image data
  664. * @param bandMasks an array containing an entry for each band
  665. * @param location the upper-left corner of the <code>Raster</code>
  666. * @return a WritableRaster object with the specified
  667. * <code>DataBuffer</code>, width, height, scanline stride,
  668. * and band masks.
  669. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  670. * is less than or equal to zero, or computing either
  671. * <code>location.x + w</code> or
  672. * <code>location.y + h</code> results in integer
  673. * overflow
  674. * @throws IllegalArgumentException if <code>dataType</code> is not
  675. * one of the supported data types, which are
  676. * <code>DataBuffer.TYPE_BYTE</code>,
  677. * <code>DataBuffer.TYPE_USHORT</code>
  678. * or <code>DataBuffer.TYPE_INT</code>
  679. * @throws RasterFormatException if <code>dataBuffer</code> has more
  680. * than one bank.
  681. * @throws NullPointerException if <code>dataBuffer</code> is null
  682. */
  683. public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
  684. int w, int h,
  685. int scanlineStride,
  686. int bandMasks[],
  687. Point location) {
  688. if (dataBuffer == null) {
  689. throw new NullPointerException("DataBuffer cannot be null");
  690. }
  691. if (location == null) {
  692. location = new Point(0,0);
  693. }
  694. int dataType = dataBuffer.getDataType();
  695. SinglePixelPackedSampleModel sppsm =
  696. new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride,
  697. bandMasks);
  698. switch(dataType) {
  699. case DataBuffer.TYPE_BYTE:
  700. return new ByteInterleavedRaster(sppsm, dataBuffer, location);
  701. case DataBuffer.TYPE_USHORT:
  702. return new ShortInterleavedRaster(sppsm, dataBuffer, location);
  703. case DataBuffer.TYPE_INT:
  704. return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
  705. default:
  706. throw new IllegalArgumentException("Unsupported data type " +
  707. dataType);
  708. }
  709. }
  710. /**
  711. * Creates a Raster based on a MultiPixelPackedSampleModel with the
  712. * specified DataBuffer, width, height, and bits per pixel. The upper
  713. * left corner of the Raster is given by the location argument. If
  714. * location is null, (0, 0) will be used.
  715. * @param dataBuffer the <code>DataBuffer</code> that contains the
  716. * image data
  717. * @param w the width in pixels of the image data
  718. * @param h the height in pixels of the image data
  719. * @param bitsPerPixel the number of bits for each pixel
  720. * @param location the upper-left corner of the <code>Raster</code>
  721. * @return a WritableRaster object with the specified
  722. * <code>DataBuffer</code>, width, height, and
  723. * bits per pixel.
  724. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  725. * is less than or equal to zero, or computing either
  726. * <code>location.x + w</code> or
  727. * <code>location.y + h</code> results in integer
  728. * overflow
  729. * @throws IllegalArgumentException if <code>dataType</code> is not
  730. * one of the supported data types, which are
  731. * <code>DataBuffer.TYPE_BYTE</code>,
  732. * <code>DataBuffer.TYPE_USHORT</code>
  733. * or <code>DataBuffer.TYPE_INT</code>
  734. * @throws RasterFormatException if <code>dataBuffer</code> has more
  735. * than one bank.
  736. * @throws NullPointerException if <code>dataBuffer</code> is null
  737. */
  738. public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
  739. int w, int h,
  740. int bitsPerPixel,
  741. Point location) {
  742. if (dataBuffer == null) {
  743. throw new NullPointerException("DataBuffer cannot be null");
  744. }
  745. if (location == null) {
  746. location = new Point(0,0);
  747. }
  748. int dataType = dataBuffer.getDataType();
  749. if (dataType != DataBuffer.TYPE_BYTE &&
  750. dataType != DataBuffer.TYPE_USHORT &&
  751. dataType != DataBuffer.TYPE_INT) {
  752. throw new IllegalArgumentException("Unsupported data type " +
  753. dataType);
  754. }
  755. if (dataBuffer.getNumBanks() != 1) {
  756. throw new
  757. RasterFormatException("DataBuffer for packed Rasters"+
  758. " must only have 1 bank.");
  759. }
  760. MultiPixelPackedSampleModel mppsm =
  761. new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
  762. if (dataType == DataBuffer.TYPE_BYTE &&
  763. (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
  764. return new BytePackedRaster(mppsm, dataBuffer, location);
  765. } else {
  766. return new SunWritableRaster(mppsm, dataBuffer, location);
  767. }
  768. }
  769. /**
  770. * Creates a Raster with the specified SampleModel and DataBuffer.
  771. * The upper left corner of the Raster is given by the location argument.
  772. * If location is null, (0, 0) will be used.
  773. * @param sm the specified <code>SampleModel</code>
  774. * @param db the specified <code>DataBuffer</code>
  775. * @param location the upper-left corner of the <code>Raster</code>
  776. * @return a <code>Raster</code> with the specified
  777. * <code>SampleModel</code>, <code>DataBuffer</code>, and
  778. * location.
  779. * @throws RasterFormatException if computing either
  780. * <code>location.x + sm.getWidth()</code> or
  781. * <code>location.y + sm.getHeight()</code> results in integer
  782. * overflow
  783. * @throws RasterFormatException if <code>dataBuffer</code> has more
  784. * than one bank and the <code>sampleModel</code> is
  785. * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
  786. * or MultiPixelPackedSampleModel.
  787. * @throws NullPointerException if either SampleModel or DataBuffer is
  788. * null
  789. */
  790. public static Raster createRaster(SampleModel sm,
  791. DataBuffer db,
  792. Point location) {
  793. if ((sm == null) || (db == null)) {
  794. throw new NullPointerException("SampleModel and DataBuffer cannot be null");
  795. }
  796. if (location == null) {
  797. location = new Point(0,0);
  798. }
  799. int dataType = sm.getDataType();
  800. if (sm instanceof PixelInterleavedSampleModel) {
  801. switch(dataType) {
  802. case DataBuffer.TYPE_BYTE:
  803. return new ByteInterleavedRaster(sm, db, location);
  804. case DataBuffer.TYPE_USHORT:
  805. return new ShortInterleavedRaster(sm, db, location);
  806. }
  807. } else if (sm instanceof SinglePixelPackedSampleModel) {
  808. switch(dataType) {
  809. case DataBuffer.TYPE_BYTE:
  810. return new ByteInterleavedRaster(sm, db, location);
  811. case DataBuffer.TYPE_USHORT:
  812. return new ShortInterleavedRaster(sm, db, location);
  813. case DataBuffer.TYPE_INT:
  814. return new IntegerInterleavedRaster(sm, db, location);
  815. }
  816. } else if (sm instanceof MultiPixelPackedSampleModel &&
  817. dataType == DataBuffer.TYPE_BYTE &&
  818. sm.getSampleSize(0) < 8) {
  819. return new BytePackedRaster(sm, db, location);
  820. }
  821. // we couldn't do anything special - do the generic thing
  822. return new Raster(sm,db,location);
  823. }
  824. /**
  825. * Creates a WritableRaster with the specified SampleModel.
  826. * The upper left corner of the Raster is given by the location argument.
  827. * If location is null, (0, 0) will be used.
  828. * @param sm the specified <code>SampleModel</code>
  829. * @param location the upper-left corner of the
  830. * <code>WritableRaster</code>
  831. * @return a <code>WritableRaster</code> with the specified
  832. * <code>SampleModel</code> and location.
  833. * @throws RasterFormatException if computing either
  834. * <code>location.x + sm.getWidth()</code> or
  835. * <code>location.y + sm.getHeight()</code> results in integer
  836. * overflow
  837. */
  838. public static WritableRaster createWritableRaster(SampleModel sm,
  839. Point location) {
  840. if (location == null) {
  841. location = new Point(0,0);
  842. }
  843. return createWritableRaster(sm,
  844. sm.createDataBuffer(),
  845. location);
  846. }
  847. /**
  848. * Creates a WritableRaster with the specified SampleModel and DataBuffer.
  849. * The upper left corner of the Raster is given by the location argument.
  850. * If location is null, (0, 0) will be used.
  851. * @param sm the specified <code>SampleModel</code>
  852. * @param db the specified <code>DataBuffer</code>
  853. * @param location the upper-left corner of the
  854. * <code>WritableRaster</code>
  855. * @return a <code>WritableRaster</code> with the specified
  856. * <code>SampleModel</code>, <code>DataBuffer</code>, and
  857. * location.
  858. * @throws RasterFormatException if computing either
  859. * <code>location.x + sm.getWidth()</code> or
  860. * <code>location.y + sm.getHeight()</code> results in integer
  861. * overflow
  862. * @throws RasterFormatException if <code>dataBuffer</code> has more
  863. * than one bank and the <code>sampleModel</code> is
  864. * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
  865. * or MultiPixelPackedSampleModel.
  866. * @throws NullPointerException if either SampleModel or DataBuffer is null
  867. */
  868. public static WritableRaster createWritableRaster(SampleModel sm,
  869. DataBuffer db,
  870. Point location) {
  871. if ((sm == null) || (db == null)) {
  872. throw new NullPointerException("SampleModel and DataBuffer cannot be null");
  873. }
  874. if (location == null) {
  875. location = new Point(0,0);
  876. }
  877. int dataType = sm.getDataType();
  878. if (sm instanceof PixelInterleavedSampleModel) {
  879. switch(dataType) {
  880. case DataBuffer.TYPE_BYTE:
  881. return new ByteInterleavedRaster(sm, db, location);
  882. case DataBuffer.TYPE_USHORT:
  883. return new ShortInterleavedRaster(sm, db, location);
  884. }
  885. } else if (sm instanceof SinglePixelPackedSampleModel) {
  886. switch(dataType) {
  887. case DataBuffer.TYPE_BYTE:
  888. return new ByteInterleavedRaster(sm, db, location);
  889. case DataBuffer.TYPE_USHORT:
  890. return new ShortInterleavedRaster(sm, db, location);
  891. case DataBuffer.TYPE_INT:
  892. return new IntegerInterleavedRaster(sm, db, location);
  893. }
  894. } else if (sm instanceof MultiPixelPackedSampleModel &&
  895. dataType == DataBuffer.TYPE_BYTE &&
  896. sm.getSampleSize(0) < 8) {
  897. return new BytePackedRaster(sm, db, location);
  898. }
  899. // we couldn't do anything special - do the generic thing
  900. return new SunWritableRaster(sm,db,location);
  901. }
  902. /**
  903. * Constructs a Raster with the given SampleModel. The Raster's
  904. * upper left corner is origin and it is the same size as the
  905. * SampleModel. A DataBuffer large enough to describe the
  906. * Raster is automatically created.
  907. * @param sampleModel The SampleModel that specifies the layout
  908. * @param origin The Point that specified the origin
  909. * @throws RasterFormatException if computing either
  910. * <code>origin.x + sampleModel.getWidth()</code> or
  911. * <code>origin.y + sampleModel.getHeight()</code> results in
  912. * integer overflow
  913. * @throws NullPointerException either <code>sampleModel</code> or
  914. * <code>origin</code> is null
  915. */
  916. protected Raster(SampleModel sampleModel,
  917. Point origin) {
  918. this(sampleModel,
  919. sampleModel.createDataBuffer(),
  920. new Rectangle(origin.x,
  921. origin.y,
  922. sampleModel.getWidth(),
  923. sampleModel.getHeight()),
  924. origin,
  925. null);
  926. }
  927. /**
  928. * Constructs a Raster with the given SampleModel and DataBuffer.
  929. * The Raster's upper left corner is origin and it is the same size
  930. * as the SampleModel. The DataBuffer is not initialized and must
  931. * be compatible with SampleModel.
  932. * @param sampleModel The SampleModel that specifies the layout
  933. * @param dataBuffer The DataBuffer that contains the image data
  934. * @param origin The Point that specifies the origin
  935. * @throws RasterFormatException if computing either
  936. * <code>origin.x + sampleModel.getWidth()</code> or
  937. * <code>origin.y + sampleModel.getHeight()</code> results in
  938. * integer overflow
  939. * @throws NullPointerException either <code>sampleModel</code> or
  940. * <code>origin</code> is null
  941. */
  942. protected Raster(SampleModel sampleModel,
  943. DataBuffer dataBuffer,
  944. Point origin) {
  945. this(sampleModel,
  946. dataBuffer,
  947. new Rectangle(origin.x,
  948. origin.y,
  949. sampleModel.getWidth(),
  950. sampleModel.getHeight()),
  951. origin,
  952. null);
  953. }
  954. /**
  955. * Constructs a Raster with the given SampleModel, DataBuffer, and
  956. * parent. aRegion specifies the bounding rectangle of the new
  957. * Raster. When translated into the base Raster's coordinate
  958. * system, aRegion must be contained by the base Raster.
  959. * (The base Raster is the Raster's ancestor which has no parent.)
  960. * sampleModelTranslate specifies the sampleModelTranslateX and
  961. * sampleModelTranslateY values of the new Raster.
  962. *
  963. * Note that this constructor should generally be called by other
  964. * constructors or create methods, it should not be used directly.
  965. * @param sampleModel The SampleModel that specifies the layout
  966. * @param dataBuffer The DataBuffer that contains the image data
  967. * @param aRegion The Rectangle that specifies the image area
  968. * @param sampleModelTranslate The Point that specifies the translation
  969. * from SampleModel to Raster coordinates
  970. * @param parent The parent (if any) of this raster
  971. * @throws NullPointerException if any of <code>sampleModel</code>,
  972. * <code>dataBuffer</code>, <code>aRegion</code> or
  973. * <code>sampleModelTranslate</code> is null
  974. * @throws RasterFormatException if <code>aRegion</code> has width
  975. * or height less than or equal to zero, or computing either
  976. * <code>aRegion.x + aRegion.width</code> or
  977. * <code>aRegion.y + aRegion.height</code> results in integer
  978. * overflow
  979. */
  980. protected Raster(SampleModel sampleModel,
  981. DataBuffer dataBuffer,
  982. Rectangle aRegion,
  983. Point sampleModelTranslate,
  984. Raster parent) {
  985. if ((sampleModel == null) || (dataBuffer == null) ||
  986. (aRegion == null) || (sampleModelTranslate == null)) {
  987. throw new NullPointerException("SampleModel, dataBuffer, aRegion and " +
  988. "sampleModelTranslate cannot be null");
  989. }
  990. this.sampleModel = sampleModel;
  991. this.dataBuffer = dataBuffer;
  992. minX = aRegion.x;
  993. minY = aRegion.y;
  994. width = aRegion.width;
  995. height = aRegion.height;
  996. if (width <= 0 || height <= 0) {
  997. throw new RasterFormatException("negative or zero " +
  998. ((width <= 0) ? "width" : "height"));
  999. }
  1000. if ((minX + width) < minX) {
  1001. throw new RasterFormatException(
  1002. "overflow condition for X coordinates of Raster");
  1003. }
  1004. if ((minY + height) < minY) {
  1005. throw new RasterFormatException(
  1006. "overflow condition for Y coordinates of Raster");
  1007. }
  1008. sampleModelTranslateX = sampleModelTranslate.x;
  1009. sampleModelTranslateY = sampleModelTranslate.y;
  1010. numBands = sampleModel.getNumBands();
  1011. numDataElements = sampleModel.getNumDataElements();
  1012. this.parent = parent;
  1013. }
  1014. /**
  1015. * Returns the parent Raster (if any) of this Raster or null.
  1016. * @return the parent Raster or <code>null</code>.
  1017. */
  1018. public Raster getParent() {
  1019. return parent;
  1020. }
  1021. /**
  1022. * Returns the X translation from the coordinate system of the
  1023. * SampleModel to that of the Raster. To convert a pixel's X
  1024. * coordinate from the Raster coordinate system to the SampleModel
  1025. * coordinate system, this value must be subtracted.
  1026. * @return the X translation from the coordinate space of the
  1027. * Raster's SampleModel to that of the Raster.
  1028. */
  1029. final public int getSampleModelTranslateX() {
  1030. return sampleModelTranslateX;
  1031. }
  1032. /**
  1033. * Returns the Y translation from the coordinate system of the
  1034. * SampleModel to that of the Raster. To convert a pixel's Y
  1035. * coordinate from the Raster coordinate system to the SampleModel
  1036. * coordinate system, this value must be subtracted.
  1037. * @return the Y translation from the coordinate space of the
  1038. * Raster's SampleModel to that of the Raster.
  1039. */
  1040. final public int getSampleModelTranslateY() {
  1041. return sampleModelTranslateY;
  1042. }
  1043. /**
  1044. * Create a compatible WritableRaster the same size as this Raster with
  1045. * the same SampleModel and a new initialized DataBuffer.
  1046. * @return a compatible <code>WritableRaster</code> with the same sample
  1047. * model and a new data buffer.
  1048. */
  1049. public WritableRaster createCompatibleWritableRaster() {
  1050. return new SunWritableRaster(sampleModel, new Point(0,0));
  1051. }
  1052. /**
  1053. * Create a compatible WritableRaster with the specified size, a new
  1054. * SampleModel, and a new initialized DataBuffer.
  1055. * @param w the specified width of the new <code>WritableRaster</code>
  1056. * @param h the specified height of the new <code>WritableRaster</code>
  1057. * @return a compatible <code>WritableRaster</code> with the specified
  1058. * size and a new sample model and data buffer.
  1059. * @exception RasterFormatException if the width or height is less than
  1060. * or equal to zero.
  1061. */
  1062. public WritableRaster createCompatibleWritableRaster(int w, int h) {
  1063. if (w <= 0 || h <=0) {
  1064. throw new RasterFormatException("negative " +
  1065. ((w <= 0) ? "width" : "height"));
  1066. }
  1067. SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
  1068. return new SunWritableRaster(sm, new Point(0,0));
  1069. }
  1070. /**
  1071. * Create a compatible WritableRaster with location (minX, minY)
  1072. * and size (width, height) specified by rect, a
  1073. * new SampleModel, and a new initialized DataBuffer.
  1074. * @param rect a <code>Rectangle</code> that specifies the size and
  1075. * location of the <code>WritableRaster</code>
  1076. * @return a compatible <code>WritableRaster</code> with the specified
  1077. * size and location and a new sample model and data buffer.
  1078. * @throws RasterFormatException if <code>rect</code> has width
  1079. * or height less than or equal to zero, or computing either
  1080. * <code>rect.x + rect.width</code> or
  1081. * <code>rect.y + rect.height</code> results in integer
  1082. * overflow
  1083. * @throws NullPointerException if <code>rect<code> is null
  1084. */
  1085. public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
  1086. if (rect == null) {
  1087. throw new NullPointerException("Rect cannot be null");
  1088. }
  1089. return createCompatibleWritableRaster(rect.x, rect.y,
  1090. rect.width, rect.height);
  1091. }
  1092. /**
  1093. * Create a compatible WritableRaster with the specified
  1094. * location (minX, minY) and size (width, height), a
  1095. * new SampleModel, and a new initialized DataBuffer.
  1096. * @param x, y the coordinates of the upper-left corner of
  1097. * the <code>WritableRaster</code>
  1098. * @param w the specified width of the <code>WritableRaster</code>
  1099. * @param h the specified height of the <code>WritableRaster</code>
  1100. * @return a compatible <code>WritableRaster</code> with the specified
  1101. * size and location and a new sample model and data buffer.
  1102. * @throws RasterFormatException if <code>w</code> or <code>h</code>
  1103. * is less than or equal to zero, or computing either
  1104. * <code>x + w</code> or
  1105. * <code>y + h</code> results in integer
  1106. * overflow
  1107. */
  1108. public WritableRaster createCompatibleWritableRaster(int x, int y,
  1109. int w, int h) {
  1110. WritableRaster ret = createCompatibleWritableRaster(w, h);
  1111. return ret.createWritableChild(0,0,w,h,x,y,null);
  1112. }
  1113. /**
  1114. * Create a Raster with the same size, SampleModel and DataBuffer
  1115. * as this one, but with a different location. The new Raster
  1116. * will possess a reference to the current Raster, accessible
  1117. * through its getParent() method.
  1118. *
  1119. * @param childMinX, childMinY coordinates of the upper-left
  1120. * corner of the new <code>Raster</code>
  1121. * @return a new <code>Raster</code> with the same size, SampleModel,
  1122. * and DataBuffer as this <code>Raster</code>, but with the
  1123. * specified location.
  1124. * @throws RasterFormatException if computing either
  1125. * <code>childMinX + this.getWidth()</code> or
  1126. * <code>childMinY + this.getHeight()</code> results in integer
  1127. * overflow
  1128. */
  1129. public Raster createTranslatedChild(int childMinX, int childMinY) {
  1130. return createChild(minX,minY,width,height,
  1131. childMinX,childMinY,null);
  1132. }
  1133. /**
  1134. * Returns a new Raster which shares all or part of this Raster's
  1135. * DataBuffer. The new Raster will possess a reference to the
  1136. * current Raster, accessible through its getParent() method.
  1137. *
  1138. * <p> The parentX, parentY, width and height parameters
  1139. * form a Rectangle in this Raster's coordinate space,
  1140. * indicating the area of pixels to be shared. An error will
  1141. * be thrown if this Rectangle is not contained with the bounds
  1142. * of the current Raster.
  1143. *
  1144. * <p> The new Raster may additionally be translated to a
  1145. * different coordinate system for the plane than that used by the current
  1146. * Raster. The childMinX and childMinY parameters give the new
  1147. * (x, y) coordinate of the upper-left pixel of the returned
  1148. * Raster; the coordinate (childMinX, childMinY) in the new Raster
  1149. * will map to the same pixel as the coordinate (parentX, parentY)
  1150. * in the current Raster.
  1151. *
  1152. * <p> The new Raster may be defined to contain only a subset of
  1153. * the bands of the current Raster, possibly reordered, by means
  1154. * of the bandList parameter. If bandList is null, it is taken to
  1155. * include all of the bands of the current Raster in their current
  1156. * order.
  1157. *
  1158. * <p> To create a new Raster that contains a subregion of the current
  1159. * Raster, but shares its coordinate system and bands,
  1160. * this method should be called with childMinX equal to parentX,
  1161. * childMinY equal to parentY, and bandList equal to null.
  1162. *
  1163. * @param parentX, parentY coordinates of the upper-left corner
  1164. * in this Raster's coordinates
  1165. * @param width Width of the region starting at (parentX, parentY)
  1166. * @param height Height of the region starting at (parentX, parentY).
  1167. * @param childMinX, childMinY coordinates of the upper-left corner
  1168. * of the returned Raster
  1169. * @param bandList Array of band indices, or null to use all bands
  1170. * @return a new <code>Raster</code>.
  1171. * @exception RasterFormatException if the specified subregion is outside
  1172. * of the raster bounds.
  1173. * @throws RasterFormatException if <code>width</code> or
  1174. * <code>height</code>
  1175. * is less than or equal to zero, or computing any of
  1176. * <code>parentX + width</code>, <code>parentY + height</code>,
  1177. * <code>childMinX + width</code>, or
  1178. * <code>childMinY + height</code> results in integer
  1179. * overflow
  1180. */
  1181. public Raster createChild(int parentX, int parentY,
  1182. int width, int height,
  1183. int childMinX, int childMinY,
  1184. int bandList[]) {
  1185. if (parentX < this.minX) {
  1186. throw new RasterFormatException("parentX lies outside raster");
  1187. }
  1188. if (parentY < this.minY) {
  1189. throw new RasterFormatException("parentY lies outside raster");
  1190. }
  1191. if ((parentX + width < parentX) ||
  1192. (parentX + width > this.width + this.minX)) {
  1193. throw new RasterFormatException("(parentX + width) is outside raster");
  1194. }
  1195. if ((parentY + height < parentY) ||
  1196. (parentY + height > this.height + this.minY)) {
  1197. throw new RasterFormatException("(parentY + height) is outside raster");
  1198. }
  1199. SampleModel subSampleModel;
  1200. // Note: the SampleModel for the child Raster should have the same
  1201. // width and height as that for the parent, since it represents
  1202. // the physical layout of the pixel data. The child Raster's width
  1203. // and height represent a "virtual" view of the pixel data, so
  1204. // they may be different than those of the SampleModel.
  1205. if (bandList == null) {
  1206. subSampleModel = sampleModel;
  1207. } else {
  1208. subSampleModel = sampleModel.createSubsetSampleModel(bandList);
  1209. }
  1210. int deltaX = childMinX - parentX;
  1211. int deltaY = childMinY - parentY;
  1212. return new Raster(subSampleModel, dataBuffer,
  1213. new Rectangle(childMinX, childMinY, width, height),
  1214. new Point(sampleModelTranslateX + deltaX,
  1215. sampleModelTranslateY + deltaY), this);
  1216. }
  1217. /**
  1218. * Returns the bounding Rectangle of this Raster. This function returns
  1219. * the same information as getMinX/MinY/Width/Height.
  1220. * @return the bounding box of this <code>Raster</code>.
  1221. */
  1222. public Rectangle getBounds() {
  1223. return new Rectangle(minX, minY, width, height);
  1224. }
  1225. /** Returns the minimum valid X coordinate of the Raster.
  1226. * @return the minimum x coordinate of this <code>Raster</code>.
  1227. */
  1228. final public int getMinX() {
  1229. return minX;
  1230. }
  1231. /** Returns the minimum valid Y coordinate of the Raster.
  1232. * @return the minimum y coordinate of this <code>Raster</code>.
  1233. */
  1234. final public int getMinY() {
  1235. return minY;
  1236. }
  1237. /** Returns the width in pixels of the Raster.
  1238. * @return the width of this <code>Raster</code>.
  1239. */
  1240. final public int getWidth() {
  1241. return width;
  1242. }
  1243. /** Returns the height in pixels of the Raster.
  1244. * @return the height of this <code>Raster</code>.
  1245. */
  1246. final public int getHeight() {
  1247. return height;
  1248. }
  1249. /** Returns the number of bands (samples per pixel) in this Raster.
  1250. * @return the number of bands of this <code>Raster</code>.
  1251. */
  1252. final public int getNumBands() {
  1253. return numBands;
  1254. }
  1255. /**
  1256. * Returns the number of data elements needed to transfer one pixel
  1257. * via the getDataElements and setDataElements methods. When pixels
  1258. * are transferred via these methods, they may be transferred in a
  1259. * packed or unpacked format, depending on the implementation of the
  1260. * underlying SampleModel. Using these methods, pixels are transferred
  1261. * as an array of getNumDataElements() elements of a primitive type given
  1262. * by getTransferType(). The TransferType may or may not be the same
  1263. * as the storage data type of the DataBuffer.
  1264. * @return the number of data elements.
  1265. */
  1266. final public int getNumDataElements() {
  1267. return sampleModel.getNumDataElements();
  1268. }
  1269. /**
  1270. * Returns the TransferType used to transfer pixels via the
  1271. * getDataElements and setDataElements methods. When pixels
  1272. * are transferred via these methods, they may be transferred in a
  1273. * packed or unpacked format, depending on the implementation of the
  1274. * underlying SampleModel. Using these methods, pixels are transferred
  1275. * as an array of getNumDataElements() elements of a primitive type given
  1276. * by getTransferType(). The TransferType may or may not be the same
  1277. * as the storage data type of the DataBuffer. The TransferType will
  1278. * be one of the types defined in DataBuffer.
  1279. * @return this transfer type.
  1280. */
  1281. final public int getTransferType() {
  1282. return sampleModel.getTransferType();
  1283. }
  1284. /** Returns the DataBuffer associated with this Raster.
  1285. * @return the <code>DataBuffer</code> of this <code>Raster</code>.
  1286. */
  1287. public DataBuffer getDataBuffer() {
  1288. return dataBuffer;
  1289. }
  1290. /** Returns the SampleModel that describes the layout of the image data.
  1291. * @return the <code>SampleModel</code> of this <code>Raster</code>.
  1292. */
  1293. public SampleModel getSampleModel() {
  1294. return sampleModel;
  1295. }
  1296. /**
  1297. * Returns data for a single pixel in a primitive array of type
  1298. * TransferType. For image data supported by the Java 2D(tm) API,
  1299. * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
  1300. * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
  1301. * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
  1302. * thus increasing efficiency for data transfers.
  1303. * An ArrayIndexOutOfBoundsException may be thrown
  1304. * if the coordinates are not in bounds. However, explicit bounds
  1305. * checking is not guaranteed.
  1306. * A ClassCastException will be thrown if the input object is non null
  1307. * and references anything other than an array of TransferType.
  1308. * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
  1309. * @param x, y the coordinates of the pixel location
  1310. * @param outData An object reference to an array of type defined by
  1311. * getTransferType() and length getNumDataElements().
  1312. * If null, an array of appropriate type and size will be
  1313. * allocated
  1314. * @return An object reference to an array of type defined by
  1315. * getTransferType() with the requested pixel data.
  1316. *
  1317. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1318. * in bounds, or if outData is too small to hold the output.
  1319. */
  1320. public Object getDataElements(int x, int y, Object outData) {
  1321. return sampleModel.getDataElements(x - sampleModelTranslateX,
  1322. y - sampleModelTranslateY,
  1323. outData, dataBuffer);
  1324. }
  1325. /**
  1326. * Returns the pixel data for the specified rectangle of pixels in a
  1327. * primitive array of type TransferType.
  1328. * For image data supported by the Java 2D API, this
  1329. * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
  1330. * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
  1331. * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
  1332. * thus increasing efficiency for data transfers.
  1333. * An ArrayIndexOutOfBoundsException may be thrown
  1334. * if the coordinates are not in bounds. However, explicit bounds
  1335. * checking is not guaranteed.
  1336. * A ClassCastException will be thrown if the input object is non null
  1337. * and references anything other than an array of TransferType.
  1338. * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
  1339. * @param x, y the coordinates of the upper-left pixel location
  1340. * @param w Width of the pixel rectangle
  1341. * @param h Height of the pixel rectangle
  1342. * @param outData An object reference to an array of type defined by
  1343. * getTransferType() and length w*h*getNumDataElements().
  1344. * If null, an array of appropriate type and size will be
  1345. * allocated.
  1346. * @return An object reference to an array of type defined by
  1347. * getTransferType() with the requested pixel data.
  1348. *
  1349. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1350. * in bounds, or if outData is too small to hold the output.
  1351. */
  1352. public Object getDataElements(int x, int y, int w, int h, Object outData) {
  1353. return sampleModel.getDataElements(x - sampleModelTranslateX,
  1354. y - sampleModelTranslateY,
  1355. w, h, outData, dataBuffer);
  1356. }
  1357. /**
  1358. * Returns the samples in an array of int for the specified pixel.
  1359. * An ArrayIndexOutOfBoundsException may be thrown
  1360. * if the coordinates are not in bounds. However, explicit bounds
  1361. * checking is not guaranteed.
  1362. * @param x, y the coordinates of the pixel location
  1363. * @param iArray An optionally preallocated int array
  1364. * @return the samples for the specified pixel.
  1365. *
  1366. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1367. * in bounds, or if iArray is too small to hold the output.
  1368. */
  1369. public int[] getPixel(int x, int y, int iArray[]) {
  1370. return sampleModel.getPixel(x - sampleModelTranslateX,
  1371. y - sampleModelTranslateY,
  1372. iArray, dataBuffer);
  1373. }
  1374. /**
  1375. * Returns the samples in an array of float for the
  1376. * specified pixel.
  1377. * An ArrayIndexOutOfBoundsException may be thrown
  1378. * if the coordinates are not in bounds. However, explicit bounds
  1379. * checking is not guaranteed.
  1380. * @param x, y the coordinates of the pixel location
  1381. * @param fArray An optionally preallocated float array
  1382. * @return the samples for the specified pixel.
  1383. *
  1384. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1385. * in bounds, or if fArray is too small to hold the output.
  1386. */
  1387. public float[] getPixel(int x, int y, float fArray[]) {
  1388. return sampleModel.getPixel(x - sampleModelTranslateX,
  1389. y - sampleModelTranslateY,
  1390. fArray, dataBuffer);
  1391. }
  1392. /**
  1393. * Returns the samples in an array of double for the specified pixel.
  1394. * An ArrayIndexOutOfBoundsException may be thrown
  1395. * if the coordinates are not in bounds. However, explicit bounds
  1396. * checking is not guaranteed.
  1397. * @param x, y the coordinates of the pixel location
  1398. * @param dArray An optionally preallocated double array
  1399. * @return the samples for the specified pixel.
  1400. *
  1401. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1402. * in bounds, or if dArray is too small to hold the output.
  1403. */
  1404. public double[] getPixel(int x, int y, double dArray[]) {
  1405. return sampleModel.getPixel(x - sampleModelTranslateX,
  1406. y - sampleModelTranslateY,
  1407. dArray, dataBuffer);
  1408. }
  1409. /**
  1410. * Returns an int array containing all samples for a rectangle of pixels,
  1411. * one sample per array element.
  1412. * An ArrayIndexOutOfBoundsException may be thrown
  1413. * if the coordinates are not in bounds. However, explicit bounds
  1414. * checking is not guaranteed.
  1415. * @param x, y the coordinates of the upper-left pixel location
  1416. * @param w Width of the pixel rectangle
  1417. * @param h Height of the pixel rectangle
  1418. * @param iArray An optionally pre-allocated int array
  1419. * @return the samples for the specified rectangle of pixels.
  1420. *
  1421. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1422. * in bounds, or if iArray is too small to hold the output.
  1423. */
  1424. public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
  1425. return sampleModel.getPixels(x - sampleModelTranslateX,
  1426. y - sampleModelTranslateY, w, h,
  1427. iArray, dataBuffer);
  1428. }
  1429. /**
  1430. * Returns a float array containing all samples for a rectangle of pixels,
  1431. * one sample per array element.
  1432. * An ArrayIndexOutOfBoundsException may be thrown
  1433. * if the coordinates are not in bounds. However, explicit bounds
  1434. * checking is not guaranteed.
  1435. * @param x, y the coordinates of the pixel location
  1436. * @param w Width of the pixel rectangle
  1437. * @param h Height of the pixel rectangle
  1438. * @param fArray An optionally pre-allocated float array
  1439. * @return the samples for the specified rectangle of pixels.
  1440. *
  1441. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1442. * in bounds, or if fArray is too small to hold the output.
  1443. */
  1444. public float[] getPixels(int x, int y, int w, int h,
  1445. float fArray[]) {
  1446. return sampleModel.getPixels(x - sampleModelTranslateX,
  1447. y - sampleModelTranslateY, w, h,
  1448. fArray, dataBuffer);
  1449. }
  1450. /**
  1451. * Returns a double array containing all samples for a rectangle of pixels,
  1452. * one sample per array element.
  1453. * An ArrayIndexOutOfBoundsException may be thrown
  1454. * if the coordinates are not in bounds. However, explicit bounds
  1455. * checking is not guaranteed.
  1456. * @param x, y the coordinates of the upper-left pixel location
  1457. * @param w Width of the pixel rectangle
  1458. * @param h Height of the pixel rectangle
  1459. * @param dArray An optionally pre-allocated double array
  1460. * @return the samples for the specified rectangle of pixels.
  1461. *
  1462. * @throws ArrayIndexOutOfBoundsException if the coordinates are not
  1463. * in bounds, or if dArray is too small to hold the output.
  1464. */
  1465. public double[] getPixels(int x, int y, int w, int h,
  1466. double dArray[]) {
  1467. return sampleModel.getPixels(x - sampleModelTranslateX,
  1468. y - sampleModelTranslateY,
  1469. w, h, dArray, dataBuffer);
  1470. }
  1471. /**
  1472. * Returns the sample in a specified band for the pixel located
  1473. * at (x,y) as an int.
  1474. * An ArrayIndexOutOfBoundsException may be thrown
  1475. * if the coordinates are not in bounds. However, explicit bounds
  1476. * checking is not guaranteed.
  1477. * @param x, y the coordinates of the pixel location
  1478. * @param b The band to return
  1479. * @return the sample in the specified band for the pixel at the
  1480. * specified coordinate.
  1481. *
  1482. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1483. * the band index are not in bounds.
  1484. */
  1485. public int getSample(int x, int y, int b) {
  1486. return sampleModel.getSample(x - sampleModelTranslateX,
  1487. y - sampleModelTranslateY, b,
  1488. dataBuffer);
  1489. }
  1490. /**
  1491. * Returns the sample in a specified band
  1492. * for the pixel located at (x,y) as a float.
  1493. * An ArrayIndexOutOfBoundsException may be thrown
  1494. * if the coordinates are not in bounds. However, explicit bounds
  1495. * checking is not guaranteed.
  1496. * @param x, y the coordinates of the pixel location
  1497. * @param b The band to return
  1498. * @return the sample in the specified band for the pixel at the
  1499. * specified coordinate.
  1500. *
  1501. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1502. * the band index are not in bounds.
  1503. */
  1504. public float getSampleFloat(int x, int y, int b) {
  1505. return sampleModel.getSampleFloat(x - sampleModelTranslateX,
  1506. y - sampleModelTranslateY, b,
  1507. dataBuffer);
  1508. }
  1509. /**
  1510. * Returns the sample in a specified band
  1511. * for a pixel located at (x,y) as a double.
  1512. * An ArrayIndexOutOfBoundsException may be thrown
  1513. * if the coordinates are not in bounds. However, explicit bounds
  1514. * checking is not guaranteed.
  1515. * @param x, y the coordinates of the pixel location
  1516. * @param b The band to return
  1517. * @return the sample in the specified band for the pixel at the
  1518. * specified coordinate.
  1519. *
  1520. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1521. * the band index are not in bounds.
  1522. */
  1523. public double getSampleDouble(int x, int y, int b) {
  1524. return sampleModel.getSampleDouble(x - sampleModelTranslateX,
  1525. y - sampleModelTranslateY,
  1526. b, dataBuffer);
  1527. }
  1528. /**
  1529. * Returns the samples for a specified band for the specified rectangle
  1530. * of pixels in an int array, one sample per array element.
  1531. * An ArrayIndexOutOfBoundsException may be thrown
  1532. * if the coordinates are not in bounds. However, explicit bounds
  1533. * checking is not guaranteed.
  1534. * @param x, y the coordinates of the upper-left pixel location
  1535. * @param w Width of the pixel rectangle
  1536. * @param h Height of the pixel rectangle
  1537. * @param b The band to return
  1538. * @param iArray An optionally pre-allocated int array
  1539. * @return the samples for the specified band for the specified
  1540. * rectangle of pixels.
  1541. *
  1542. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1543. * the band index are not in bounds, or if iArray is too small to
  1544. * hold the output.
  1545. */
  1546. public int[] getSamples(int x, int y, int w, int h, int b,
  1547. int iArray[]) {
  1548. return sampleModel.getSamples(x - sampleModelTranslateX,
  1549. y - sampleModelTranslateY,
  1550. w, h, b, iArray,
  1551. dataBuffer);
  1552. }
  1553. /**
  1554. * Returns the samples for a specified band for the specified rectangle
  1555. * of pixels in a float array, one sample per array element.
  1556. * An ArrayIndexOutOfBoundsException may be thrown
  1557. * if the coordinates are not in bounds. However, explicit bounds
  1558. * checking is not guaranteed.
  1559. * @param x, y the coordinates of the upper-left pixel location
  1560. * @param w Width of the pixel rectangle
  1561. * @param h Height of the pixel rectangle
  1562. * @param b The band to return
  1563. * @param fArray An optionally pre-allocated float array
  1564. * @return the samples for the specified band for the specified
  1565. * rectangle of pixels.
  1566. *
  1567. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1568. * the band index are not in bounds, or if fArray is too small to
  1569. * hold the output.
  1570. */
  1571. public float[] getSamples(int x, int y, int w, int h, int b,
  1572. float fArray[]) {
  1573. return sampleModel.getSamples(x - sampleModelTranslateX,
  1574. y - sampleModelTranslateY,
  1575. w, h, b, fArray, dataBuffer);
  1576. }
  1577. /**
  1578. * Returns the samples for a specified band for a specified rectangle
  1579. * of pixels in a double array, one sample per array element.
  1580. * An ArrayIndexOutOfBoundsException may be thrown
  1581. * if the coordinates are not in bounds. However, explicit bounds
  1582. * checking is not guaranteed.
  1583. * @param x, y the coordinates of the upper-left pixel location
  1584. * @param w Width of the pixel rectangle
  1585. * @param h Height of the pixel rectangle
  1586. * @param b The band to return
  1587. * @param dArray An optionally pre-allocated double array
  1588. * @return the samples for the specified band for the specified
  1589. * rectangle of pixels.
  1590. *
  1591. * @throws ArrayIndexOutOfBoundsException if the coordinates or
  1592. * the band index are not in bounds, or if dArray is too small to
  1593. * hold the output.
  1594. */
  1595. public double[] getSamples(int x, int y, int w, int h, int b,
  1596. double dArray[]) {
  1597. return sampleModel.getSamples(x - sampleModelTranslateX,
  1598. y - sampleModelTranslateY,
  1599. w, h, b, dArray, dataBuffer);
  1600. }
  1601. }