1. /*
  2. * @(#)ComponentSampleModel.java 1.26 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 represents image data which is stored such that each sample
  19. * of a pixel occupies one data element of the DataBuffer. It stores the
  20. * N samples which make up a pixel in N separate data array elements.
  21. * Different bands may be in different banks of the DataBuffer.
  22. * Accessor methods are provided so that image data can be manipulated
  23. * directly. This class can support different kinds of interleaving, e.g.
  24. * band interleaving, scanline interleaving, and pixel interleaving.
  25. * Pixel stride is the number of data array elements between two samples
  26. * for the same band on the same scanline. Scanline stride is the number
  27. * of data array elements between a given sample and the corresponding sample
  28. * in the same column of the next scanline. Band offsets denote the number
  29. * of data array elements from the first data array element of the bank
  30. * of the DataBuffer holding each band to the first sample of the band.
  31. * The bands are numbered from 0 to N-1. This class can represent image
  32. * data for which each sample is an integral number which can be
  33. * stored in 8, 16, or 32 bits (all samples of a given ComponentSampleModel
  34. * are stored with the same precision). All strides and offsets must be
  35. * non-negative.
  36. * @see java.awt.image.PixelInterleavedSampleModel
  37. * @see java.awt.image.BandedSampleModel
  38. */
  39. public class ComponentSampleModel extends SampleModel
  40. {
  41. /** Offsets for all bands in data array elements. */
  42. protected int bandOffsets[];
  43. /** Index for each bank storing a band of image data. */
  44. protected int[] bankIndices;
  45. protected int numBands = 1;
  46. protected int numBanks = 1;
  47. /**
  48. * Line stride (in data array elements) of the region of image
  49. * data described by this ComponentSampleModel.
  50. */
  51. protected int scanlineStride;
  52. /** Pixel stride (in data array elements) of the region of image
  53. * data described by this ComponentSampleModel.
  54. */
  55. protected int pixelStride;
  56. static private native void initIDs();
  57. static {
  58. ColorModel.loadLibraries();
  59. initIDs();
  60. }
  61. /**
  62. * Constructs a ComponentSampleModel with the specified parameters.
  63. * The number of bands will be given by the length of the bandOffsets array.
  64. * All bands will be stored in the first bank of the DataBuffer.
  65. * @param dataType The data type for storing samples.
  66. * @param w The width (in pixels) of the region of
  67. * image data described.
  68. * @param h The height (in pixels) of the region of
  69. * image data described.
  70. * @param pixelStride The pixel stride of the region of image
  71. * data described.
  72. * @param scanlineStride The line stride of the region of image
  73. * data described.
  74. * @param bandOffsets The offsets of all bands.
  75. * @throws IllegalArgumentException if <code>pixelStride</code>
  76. * is less than 0
  77. * @throws IllegalArgumentException if <code>scanlineStride</code>
  78. * is less than 0
  79. * @throws IllegalArgumentException if <code>numBands</code>
  80. * is less than 1
  81. */
  82. public ComponentSampleModel(int dataType,
  83. int w, int h,
  84. int pixelStride,
  85. int scanlineStride,
  86. int bandOffsets[]) {
  87. super(dataType, w, h, bandOffsets.length);
  88. this.dataType = dataType;
  89. this.pixelStride = pixelStride;
  90. this.scanlineStride = scanlineStride;
  91. this.bandOffsets = (int[])bandOffsets.clone();
  92. numBands = bandOffsets.length;
  93. if (pixelStride < 0) {
  94. throw new IllegalArgumentException("Pixel stride must be >= 0");
  95. }
  96. if (scanlineStride < 0) {
  97. throw new IllegalArgumentException("Scanline stride must be >= 0");
  98. }
  99. if (numBands < 1) {
  100. throw new IllegalArgumentException("Must have at least one band.");
  101. }
  102. bankIndices = new int[numBands];
  103. for (int i=0; i<numBands; i++) {
  104. bankIndices[i] = 0;
  105. }
  106. }
  107. /**
  108. * Constructs a ComponentSampleModel with the specified parameters.
  109. * The number of bands will be given by the length of the bandOffsets array.
  110. * Different bands may be stored in different banks of the DataBuffer.
  111. * @param dataType The data type for storing samples.
  112. * @param w The width (in pixels) of the region of
  113. * image data described.
  114. * @param h The height (in pixels) of the region of
  115. * image data described.
  116. * @param pixelStride The pixel stride of the region of image
  117. * data described.
  118. * @param scanlineStride The line stride of the region of image
  119. * data described.
  120. * @param bandIndices The bank indices of all bands.
  121. * @param bandOffsets The band offsets of all bands.
  122. * @throws IllegalArgumentException if <code>pixelStride</code>
  123. * is less than 0
  124. * @throws IllegalArgumentException if <code>scanlineStride</code>
  125. * is less than 0
  126. * @throws IllegalArgumentException if the length of
  127. * <code>bankIndices</code> does not equal the length of
  128. * <code>bankOffsets</code>
  129. * @throws IllegalArgumentException if any of the bank indices
  130. * of <code>bandIndices</code> is less than 0
  131. */
  132. public ComponentSampleModel(int dataType,
  133. int w, int h,
  134. int pixelStride,
  135. int scanlineStride,
  136. int bankIndices[],
  137. int bandOffsets[]) {
  138. super(dataType, w, h, bandOffsets.length);
  139. this.dataType = dataType;
  140. this.pixelStride = pixelStride;
  141. this.scanlineStride = scanlineStride;
  142. this.bandOffsets = (int[])bandOffsets.clone();
  143. this.bankIndices = (int[]) bankIndices.clone();
  144. if (pixelStride < 0) {
  145. throw new IllegalArgumentException("Pixel stride must be >= 0");
  146. }
  147. if (scanlineStride < 0) {
  148. throw new IllegalArgumentException("Scanline stride must be >= 0");
  149. }
  150. int maxBank = bankIndices[0];
  151. if (maxBank < 0) {
  152. throw new IllegalArgumentException("Index of bank 0 is less than "+
  153. "0 ("+maxBank+")");
  154. }
  155. for (int i=1; i < bankIndices.length; i++) {
  156. if (bankIndices[i] > maxBank) {
  157. maxBank = bankIndices[i];
  158. }
  159. else if (bankIndices[i] < 0) {
  160. throw new IllegalArgumentException("Index of bank "+i+
  161. " is less than 0 ("+
  162. maxBank+")");
  163. }
  164. }
  165. numBanks = maxBank+1;
  166. numBands = bandOffsets.length;
  167. if (bandOffsets.length != bankIndices.length) {
  168. throw new IllegalArgumentException("Length of bandOffsets must "+
  169. "equal length of bankIndices.");
  170. }
  171. }
  172. /**
  173. * Returns the size of the data buffer (in data elements) needed
  174. * for a data buffer that matches this ComponentSampleModel.
  175. */
  176. private long getBufferSize() {
  177. int maxBandOff=bandOffsets[0];
  178. for (int i=1; i<bandOffsets.length; i++)
  179. maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  180. long size = 0;
  181. if (maxBandOff >= 0)
  182. size += maxBandOff+1;
  183. if (pixelStride > 0)
  184. size += pixelStride * (width-1);
  185. if (scanlineStride > 0)
  186. size += scanlineStride*(height-1);
  187. return size;
  188. }
  189. /**
  190. * Preserves band ordering with new step factor...
  191. */
  192. int []orderBands(int orig[], int step) {
  193. int map[] = new int[orig.length];
  194. int ret[] = new int[orig.length];
  195. for (int i=0; i<map.length; i++) map[i] = i;
  196. for (int i = 0; i < ret.length; i++) {
  197. int index = i;
  198. for (int j = i+1; j < ret.length; j++) {
  199. if (orig[map[index]] > orig[map[j]]) {
  200. index = j;
  201. }
  202. }
  203. ret[map[index]] = i*step;
  204. map[index] = map[i];
  205. }
  206. return ret;
  207. }
  208. /**
  209. * Creates a new ComponentSampleModel with the specified
  210. * width and height. The new SampleModel will have the same
  211. * number of bands, storage data type, interleaving scheme, and
  212. * pixel stride as this SampleModel.
  213. */
  214. public SampleModel createCompatibleSampleModel(int w, int h) {
  215. SampleModel ret=null;
  216. long size;
  217. int minBandOff=bandOffsets[0];
  218. int maxBandOff=bandOffsets[0];
  219. for (int i=1; i<bandOffsets.length; i++) {
  220. minBandOff = Math.min(minBandOff,bandOffsets[i]);
  221. maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  222. }
  223. maxBandOff -= minBandOff;
  224. int bands = bandOffsets.length;
  225. int bandOff[];
  226. int pStride = Math.abs(pixelStride);
  227. int lStride = Math.abs(scanlineStride);
  228. int bStride = Math.abs(maxBandOff);
  229. if (pStride > lStride) {
  230. if (pStride > bStride) {
  231. if (lStride > bStride) { // pix > line > band
  232. bandOff = new int[bandOffsets.length];
  233. for (int i=0; i<bands; i++)
  234. bandOff[i] = bandOffsets[i]-minBandOff;
  235. lStride = bStride+1;
  236. pStride = lStride*h;
  237. } else { // pix > band > line
  238. bandOff = orderBands(bandOffsets,lStride*h);
  239. pStride = bands*lStride*h;
  240. }
  241. } else { // band > pix > line
  242. pStride = lStride*h;
  243. bandOff = orderBands(bandOffsets,pStride*w);
  244. }
  245. } else {
  246. if (pStride > bStride) { // line > pix > band
  247. bandOff = new int[bandOffsets.length];
  248. for (int i=0; i<bands; i++)
  249. bandOff[i] = bandOffsets[i]-minBandOff;
  250. pStride = bStride+1;
  251. lStride = pStride*w;
  252. } else {
  253. if (lStride > bStride) { // line > band > pix
  254. bandOff = orderBands(bandOffsets,pStride*w);
  255. lStride = bands*pStride*w;
  256. } else { // band > line > pix
  257. lStride = pStride*w;
  258. bandOff = orderBands(bandOffsets,lStride*h);
  259. }
  260. }
  261. }
  262. // make sure we make room for negative offsets...
  263. int base = 0;
  264. if (scanlineStride < 0) {
  265. base += lStride*h;
  266. lStride *= -1;
  267. }
  268. if (pixelStride < 0) {
  269. base += pStride*w;
  270. pStride *= -1;
  271. }
  272. for (int i=0; i<bands; i++)
  273. bandOff[i] += base;
  274. return new ComponentSampleModel(dataType, w, h, pStride,
  275. lStride, bandOff);
  276. }
  277. /**
  278. * This creates a new ComponentSampleModel with a subset of the bands
  279. * of this ComponentSampleModel. The new ComponentSampleModel can be
  280. * used with any DataBuffer that the existing ComponentSampleModel
  281. * can be used with. The new ComponentSampleModel/DataBuffer
  282. * combination will represent an image with a subset of the bands
  283. * of the original ComponentSampleModel/DataBuffer combination.
  284. */
  285. public SampleModel createSubsetSampleModel(int bands[]) {
  286. int newBandOffsets[] = new int[bands.length];
  287. for (int i=0; i<bands.length; i++) {
  288. newBandOffsets[i] = bandOffsets[bands[i]];
  289. }
  290. return new ComponentSampleModel(this.dataType, width, height,
  291. this.pixelStride,
  292. this.scanlineStride,
  293. newBandOffsets);
  294. }
  295. /**
  296. * Creates a DataBuffer that corresponds to this ComponentSampleModel.
  297. * The DataBuffer's data type, number of banks, and size
  298. * will be consistent with this ComponentSampleModel.
  299. */
  300. public DataBuffer createDataBuffer() {
  301. DataBuffer dataBuffer = null;
  302. int size = (int)getBufferSize();
  303. switch (dataType) {
  304. case DataBuffer.TYPE_BYTE:
  305. dataBuffer = new DataBufferByte(size, numBanks);
  306. break;
  307. case DataBuffer.TYPE_USHORT:
  308. dataBuffer = new DataBufferUShort(size, numBanks);
  309. break;
  310. case DataBuffer.TYPE_INT:
  311. dataBuffer = new DataBufferInt(size, numBanks);
  312. break;
  313. }
  314. return dataBuffer;
  315. }
  316. /** Gets the offset for the first band of pixel (x,y).
  317. * A sample of the first band can be retrieved from a DataBuffer
  318. * <code>data</code> with a ComponentSampleModel <code>csm</code> as
  319. * <pre>
  320. * data.getElem(csm.getOffset(x, y));
  321. * </pre>
  322. */
  323. public int getOffset(int x, int y) {
  324. int offset = y*scanlineStride + x*pixelStride + bandOffsets[0];
  325. return offset;
  326. }
  327. /** Gets the offset for band b of pixel (x,y).
  328. * A sample of band <code>b</code> can be retrieved from a
  329. * DataBuffer <code>data</code>
  330. * with a ComponentSampleModel <code>csm</code> as
  331. * <pre>
  332. * data.getElem(csm.getOffset(x, y, b));
  333. * </pre>
  334. */
  335. public int getOffset(int x, int y, int b) {
  336. int offset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  337. return offset;
  338. }
  339. /** Returns the number of bits per sample for all bands. */
  340. public final int[] getSampleSize() {
  341. int sampleSize[] = new int [numBands];
  342. int sizeInBits = getSampleSize(0);
  343. for (int i=0; i<numBands; i++)
  344. sampleSize[i] = sizeInBits;
  345. return sampleSize;
  346. }
  347. /** Returns the number of bits per sample for the specified band. */
  348. public final int getSampleSize(int band) {
  349. return DataBuffer.getDataTypeSize(dataType);
  350. }
  351. /** Returns the bank indices for all bands. */
  352. public final int [] getBankIndices() {
  353. return (int[]) bankIndices.clone();
  354. }
  355. /** Returns the band offset for all bands. */
  356. public final int [] getBandOffsets() {
  357. return (int[])bandOffsets.clone();
  358. }
  359. /** Returns the scanline stride of this ComponentSampleModel. */
  360. public final int getScanlineStride() {
  361. return scanlineStride;
  362. }
  363. /** Returns the pixel stride of this ComponentSampleModel. */
  364. public final int getPixelStride() {
  365. return pixelStride;
  366. }
  367. /**
  368. * Returns the number of data elements needed to transfer a pixel
  369. * via the getDataElements and setDataElements methods.
  370. * For a ComponentSampleModel this is identical to the
  371. * number of bands.
  372. * @see java.awt.image.SampleModel#getNumDataElements
  373. */
  374. public final int getNumDataElements() {
  375. return getNumBands();
  376. }
  377. /**
  378. * Returns data for a single pixel in a primitive array of type
  379. * TransferType. For a ComponentSampleModel, this will be the same
  380. * as the data type, and samples will be returned one per array
  381. * element. Generally, obj
  382. * should be passed in as null, so that the Object will be created
  383. * automatically and will be of the right primitive data type.
  384. * <p>
  385. * The following code illustrates transferring data for one pixel from
  386. * DataBuffer <code>db1</code>, whose storage layout is described by
  387. * ComponentSampleModel <code>csm1</code>, to DataBuffer <code>db2</code>,
  388. * whose storage layout is described by
  389. * ComponentSampleModel <code>csm2</code>.
  390. * The transfer will generally be more efficient than using
  391. * getPixel/setPixel.
  392. * <pre>
  393. * ComponentSampleModel csm1, csm2;
  394. * DataBufferInt db1, db2;
  395. * csm2.setDataElements(x, y,
  396. * csm1.getDataElements(x, y, null, db1), db2);
  397. * </pre>
  398. * Using getDataElements/setDataElements to transfer between two
  399. * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
  400. * the same number of bands, corresponding bands have the same number of
  401. * bits per sample, and the TransferTypes are the same.
  402. * <p>
  403. * If obj is non-null, it should be a primitive array of type TransferType.
  404. * Otherwise, a ClassCastException is thrown. An
  405. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  406. * not in bounds, or if obj is non-null and is not large enough to hold
  407. * the pixel data.
  408. * @param x The X coordinate of the pixel location.
  409. * @param y The Y coordinate of the pixel location.
  410. * @param obj If non-null, a primitive array in which to return
  411. * the pixel data.
  412. * @param data The DataBuffer containing the image data.
  413. */
  414. public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
  415. int type = getTransferType();
  416. int numDataElems = getNumDataElements();
  417. int pixelOffset = y*scanlineStride + x*pixelStride;
  418. switch(type) {
  419. case DataBuffer.TYPE_BYTE:
  420. byte[] bdata;
  421. if (obj == null)
  422. bdata = new byte[numDataElems];
  423. else
  424. bdata = (byte[])obj;
  425. for (int i=0; i<numDataElems; i++) {
  426. bdata[i] = (byte)data.getElem(bankIndices[i],
  427. pixelOffset + bandOffsets[i]);
  428. }
  429. obj = (Object)bdata;
  430. break;
  431. case DataBuffer.TYPE_USHORT:
  432. short[] sdata;
  433. if (obj == null)
  434. sdata = new short[numDataElems];
  435. else
  436. sdata = (short[])obj;
  437. for (int i=0; i<numDataElems; i++) {
  438. sdata[i] = (short)data.getElem(bankIndices[i],
  439. pixelOffset + bandOffsets[i]);
  440. }
  441. obj = (Object)sdata;
  442. break;
  443. case DataBuffer.TYPE_INT:
  444. int[] idata;
  445. if (obj == null)
  446. idata = new int[numDataElems];
  447. else
  448. idata = (int[])obj;
  449. for (int i=0; i<numDataElems; i++) {
  450. idata[i] = data.getElem(bankIndices[i],
  451. pixelOffset + bandOffsets[i]);
  452. }
  453. obj = (Object)idata;
  454. break;
  455. }
  456. return obj;
  457. }
  458. /**
  459. * Returns all samples for the specified pixel in an int array,
  460. * one sample per array element.
  461. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  462. * not in bounds.
  463. * @param x The X coordinate of the pixel location.
  464. * @param y The Y coordinate of the pixel location.
  465. * @param iArray If non-null, returns the samples in this array.
  466. * @param data The DataBuffer containing the image data.
  467. */
  468. public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
  469. int pixels[];
  470. if (iArray != null) {
  471. pixels = iArray;
  472. } else {
  473. pixels = new int [numBands];
  474. }
  475. int pixelOffset = y*scanlineStride + x*pixelStride;
  476. for (int i=0; i<numBands; i++) {
  477. pixels[i] = data.getElem(bankIndices[i],
  478. pixelOffset + bandOffsets[i]);
  479. }
  480. return pixels;
  481. }
  482. /**
  483. * Returns all samples for the specified rectangle of pixels in
  484. * an int array, one sample per array element.
  485. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  486. * not in bounds.
  487. * @param x The X coordinate of the upper left pixel location.
  488. * @param y The Y coordinate of the upper left pixel location.
  489. * @param w The width of the pixel rectangle.
  490. * @param h The height of the pixel rectangle.
  491. * @param iArray If non-null, returns the samples in this array.
  492. * @param data The DataBuffer containing the image data.
  493. */
  494. public int[] getPixels(int x, int y, int w, int h,
  495. int iArray[], DataBuffer data) {
  496. int pixels[];
  497. if (iArray != null) {
  498. pixels = iArray;
  499. } else {
  500. pixels = new int [w*h*numBands];
  501. }
  502. int lineOffset = y*scanlineStride + x*pixelStride;
  503. int srcOffset = 0;
  504. for (int i = 0; i < h; i++) {
  505. int pixelOffset = lineOffset;
  506. for (int j = 0; j < w; j++) {
  507. for (int k=0; k < numBands; k++) {
  508. pixels[srcOffset++] =
  509. data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]);
  510. }
  511. pixelOffset += pixelStride;
  512. }
  513. lineOffset += scanlineStride;
  514. }
  515. return pixels;
  516. }
  517. /**
  518. * Returns as int the sample in a specified band for the pixel
  519. * located at (x,y).
  520. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  521. * not in bounds.
  522. * @param x The X coordinate of the pixel location.
  523. * @param y The Y coordinate of the pixel location.
  524. * @param b The band to return.
  525. * @param data The DataBuffer containing the image data.
  526. */
  527. public int getSample(int x, int y, int b, DataBuffer data) {
  528. int sample = data.getElem(bankIndices[b],
  529. y*scanlineStride + x*pixelStride +
  530. bandOffsets[b]);
  531. return sample;
  532. }
  533. /**
  534. * Returns the samples in a specified band for the specified rectangle
  535. * of pixels in an int array, one sample per data array element.
  536. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  537. * not in bounds.
  538. * @param x The X coordinate of the upper left pixel location.
  539. * @param y The Y coordinate of the upper left pixel location.
  540. * @param w The width of the pixel rectangle.
  541. * @param h The height of the pixel rectangle.
  542. * @param b The band to return.
  543. * @param iArray If non-null, returns the samples in this array.
  544. * @param data The DataBuffer containing the image data.
  545. */
  546. public int[] getSamples(int x, int y, int w, int h, int b,
  547. int iArray[], DataBuffer data) {
  548. int samples[];
  549. if (iArray != null) {
  550. samples = iArray;
  551. } else {
  552. samples = new int [w*h];
  553. }
  554. int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  555. int srcOffset = 0;
  556. for (int i = 0; i < h; i++) {
  557. int sampleOffset = lineOffset;
  558. for (int j = 0; j < w; j++) {
  559. samples[srcOffset++] = data.getElem(bankIndices[b],
  560. sampleOffset);
  561. sampleOffset += pixelStride;
  562. }
  563. lineOffset += scanlineStride;
  564. }
  565. return samples;
  566. }
  567. /**
  568. * Sets the data for a single pixel in the specified DataBuffer from a
  569. * primitive array of type TransferType. For a ComponentSampleModel,
  570. * this will be the same as the data type, and samples are transferred
  571. * one per array element.
  572. * <p>
  573. * The following code illustrates transferring data for one pixel from
  574. * DataBuffer <code>db1</code>, whose storage layout is described by
  575. * ComponentSampleModel <code>csm1</code>, to DataBuffer <code>db2</code>,
  576. * whose storage layout is described by
  577. * ComponentSampleModel <code>csm2</code>.
  578. * The transfer will generally be more efficient than using
  579. * getPixel/setPixel.
  580. * <pre>
  581. * ComponentSampleModel csm1, csm2;
  582. * DataBufferInt db1, db2;
  583. * csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
  584. * db2);
  585. * </pre>
  586. * Using getDataElements/setDataElements to transfer between two
  587. * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
  588. * the same number of bands, corresponding bands have the same number of
  589. * bits per sample, and the TransferTypes are the same.
  590. * <p>
  591. * obj must be a primitive array of type TransferType. Otherwise,
  592. * a ClassCastException is thrown. An
  593. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  594. * not in bounds, or if obj is not large enough to hold the pixel data.
  595. * @param x The X coordinate of the pixel location.
  596. * @param y The Y coordinate of the pixel location.
  597. * @param obj A primitive array containing pixel data.
  598. * @param data The DataBuffer containing the image data.
  599. */
  600. public void setDataElements(int x, int y, Object obj, DataBuffer data) {
  601. int type = getTransferType();
  602. int numDataElems = getNumDataElements();
  603. int pixelOffset = y*scanlineStride + x*pixelStride;
  604. switch(type) {
  605. case DataBuffer.TYPE_BYTE:
  606. byte[] barray = (byte[])obj;
  607. for (int i=0; i<numDataElems; i++) {
  608. data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  609. ((int)barray[i])&0xff);
  610. }
  611. break;
  612. case DataBuffer.TYPE_USHORT:
  613. short[] sarray = (short[])obj;
  614. for (int i=0; i<numDataElems; i++) {
  615. data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
  616. ((int)sarray[i])&0xffff);
  617. }
  618. break;
  619. case DataBuffer.TYPE_INT:
  620. int[] iarray = (int[])obj;
  621. for (int i=0; i<numDataElems; i++) {
  622. data.setElem(bankIndices[i],
  623. pixelOffset + bandOffsets[i], iarray[i]);
  624. }
  625. break;
  626. }
  627. }
  628. /**
  629. * Sets a pixel in the DataBuffer using an int array of samples for input.
  630. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  631. * not in bounds.
  632. * @param x The X coordinate of the pixel location.
  633. * @param y The Y coordinate of the pixel location.
  634. * @param iArray The input samples in an int array.
  635. * @param data The DataBuffer containing the image data.
  636. */
  637. public void setPixel(int x, int y, int iArray[], DataBuffer data) {
  638. int pixelOffset = y*scanlineStride + x*pixelStride;
  639. for (int i=0; i<numBands; i++) {
  640. data.setElem(bankIndices[i],
  641. pixelOffset + bandOffsets[i],iArray[i]);
  642. }
  643. }
  644. /**
  645. * Sets all samples for a rectangle of pixels from an int array containing
  646. * one sample per array element.
  647. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  648. * not in bounds.
  649. * @param x The X coordinate of the upper left pixel location.
  650. * @param y The Y coordinate of the upper left pixel location.
  651. * @param w The width of the pixel rectangle.
  652. * @param h The height of the pixel rectangle.
  653. * @param iArray The input samples in an int array.
  654. * @param data The DataBuffer containing the image data.
  655. */
  656. public void setPixels(int x, int y, int w, int h,
  657. int iArray[], DataBuffer data) {
  658. int lineOffset = y*scanlineStride + x*pixelStride;
  659. int srcOffset = 0;
  660. for (int i = 0; i < h; i++) {
  661. int pixelOffset = lineOffset;
  662. for (int j = 0; j < w; j++) {
  663. for (int k=0; k < numBands; k++) {
  664. data.setElem(bankIndices[k], pixelOffset + bandOffsets[k],
  665. iArray[srcOffset++]);
  666. }
  667. pixelOffset += pixelStride;
  668. }
  669. lineOffset += scanlineStride;
  670. }
  671. }
  672. /**
  673. * Sets a sample in the specified band for the pixel located at (x,y)
  674. * in the DataBuffer using an int for input.
  675. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  676. * not in bounds.
  677. * @param x The X coordinate of the pixel location.
  678. * @param y The Y coordinate of the pixel location.
  679. * @param b The band to set.
  680. * @param s The input sample as an int.
  681. * @param data The DataBuffer containing the image data.
  682. */
  683. public void setSample(int x, int y, int b, int s,
  684. DataBuffer data) {
  685. data.setElem(bankIndices[b],
  686. y*scanlineStride + x*pixelStride + bandOffsets[b], s);
  687. }
  688. /**
  689. * Sets the samples in the specified band for the specified rectangle
  690. * of pixels from an int array containing one sample per data array element.
  691. * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
  692. * not in bounds.
  693. * @param x The X coordinate of the upper left pixel location.
  694. * @param y The Y coordinate of the upper left pixel location.
  695. * @param w The width of the pixel rectangle.
  696. * @param h The height of the pixel rectangle.
  697. * @param b The band to set.
  698. * @param iArray The input samples in an int array.
  699. * @param data The DataBuffer containing the image data.
  700. */
  701. public void setSamples(int x, int y, int w, int h, int b,
  702. int iArray[], DataBuffer data) {
  703. int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
  704. int srcOffset = 0;
  705. for (int i = 0; i < h; i++) {
  706. int sampleOffset = lineOffset;
  707. for (int j = 0; j < w; j++) {
  708. data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]);
  709. sampleOffset += pixelStride;
  710. }
  711. lineOffset += scanlineStride;
  712. }
  713. }
  714. }