1. /*
  2. * @(#)PixelInterleavedSampleModel.java 1.20 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt.image;
  8. /**
  9. * This class represents image data which is stored in a pixel interleaved
  10. * fashion and for
  11. * which each sample of a pixel occupies one data element of the DataBuffer.
  12. * It subclasses ComponentSampleModel but provides a more efficent
  13. * implementation for accessing pixel interleaved image data than is provided
  14. * by ComponentSampleModel. This class
  15. * stores sample data for all bands in a single bank of the
  16. * DataBuffer. Accessor methods are provided so that image data can be
  17. * manipulated directly. Pixel stride is the number of
  18. * data array elements between two samples for the same band on the same
  19. * scanline. Scanline stride is the number of data array elements between
  20. * a given sample and the corresponding sample in the same column of the next
  21. * scanline. Band offsets denote the number
  22. * of data array elements from the first data array element of the bank
  23. * of the DataBuffer holding each band to the first sample of the band.
  24. * The bands are numbered from 0 to N-1.
  25. * Bank indices denote the correspondence between a bank of the data buffer
  26. * and a band of image data.
  27. * This class supports
  28. * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
  29. * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
  30. * {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
  31. * {@link DataBuffer#TYPE_INT TYPE_INT},
  32. * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT} and
  33. * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes.
  34. */
  35. public class PixelInterleavedSampleModel extends ComponentSampleModel
  36. {
  37. /**
  38. * Constructs a PixelInterleavedSampleModel with the specified parameters.
  39. * The number of bands will be given by the length of the bandOffsets
  40. * array.
  41. * @param dataType The data type for storing samples.
  42. * @param w The width (in pixels) of the region of
  43. * image data described.
  44. * @param h The height (in pixels) of the region of
  45. * image data described.
  46. * @param pixelStride The pixel stride of the image data.
  47. * @param scanlineStride The line stride of the image data.
  48. * @param bandOffsets The offsets of all bands.
  49. * @throws IllegalArgumentException if <code>w</code> or
  50. * <code>h</code> is not greater than 0
  51. * @throws IllegalArgumentException if any offset between bands is
  52. * greater than the scanline stride
  53. * @throws IllegalArgumentException if the product of
  54. * <code>pixelStride</code> and <code>w</code> is greater
  55. * than <code>scanlineStride</code>
  56. * @throws IllegalArgumentException if <code>pixelStride</code> is
  57. * less than any offset between bands
  58. * @throws IllegalArgumentException if <code>dataType</code> is not
  59. * one of the supported data types
  60. */
  61. public PixelInterleavedSampleModel(int dataType,
  62. int w, int h,
  63. int pixelStride,
  64. int scanlineStride,
  65. int bandOffsets[]) {
  66. super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
  67. int minBandOff=bandOffsets[0];
  68. int maxBandOff=bandOffsets[0];
  69. for (int i=1; i<bandOffsets.length; i++) {
  70. minBandOff = Math.min(minBandOff,bandOffsets[i]);
  71. maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
  72. }
  73. maxBandOff -= minBandOff;
  74. if (maxBandOff > scanlineStride) {
  75. throw new IllegalArgumentException("Offsets between bands must be"+
  76. " less than the scanline "+
  77. " stride");
  78. }
  79. if (pixelStride*w > scanlineStride) {
  80. throw new IllegalArgumentException("Pixel stride times width "+
  81. "must be less than or "+
  82. "equal to the scanline "+
  83. "stride");
  84. }
  85. if (pixelStride < maxBandOff) {
  86. throw new IllegalArgumentException("Pixel stride must be greater"+
  87. " than or equal to the offsets"+
  88. " between bands");
  89. }
  90. }
  91. /**
  92. * Creates a new PixelInterleavedSampleModel with the specified
  93. * width and height. The new PixelInterleavedSampleModel will have the
  94. * same number of bands, storage data type, and pixel stride
  95. * as this PixelInterleavedSampleModel. The band offsets may be
  96. * compressed such that the minimum of all of the band offsets is zero.
  97. * @param w the width of the resulting <code>SampleModel</code>
  98. * @param h the height of the resulting <code>SampleModel</code>
  99. * @return a new <code>SampleModel</code> with the specified width
  100. * and height.
  101. * @throws IllegalArgumentException if <code>w</code> or
  102. * <code>h</code> is not greater than 0
  103. */
  104. public SampleModel createCompatibleSampleModel(int w, int h) {
  105. int minBandoff=bandOffsets[0];
  106. int numBands = bandOffsets.length;
  107. for (int i=1; i < numBands; i++) {
  108. if (bandOffsets[i] < minBandoff) {
  109. minBandoff = bandOffsets[i];
  110. }
  111. }
  112. int[] bandOff;
  113. if (minBandoff > 0) {
  114. bandOff = new int[numBands];
  115. for (int i=0; i < numBands; i++) {
  116. bandOff[i] = bandOffsets[i] - minBandoff;
  117. }
  118. }
  119. else {
  120. bandOff = bandOffsets;
  121. }
  122. return new PixelInterleavedSampleModel(dataType, w, h, pixelStride,
  123. pixelStride*w, bandOff);
  124. }
  125. /**
  126. * Creates a new PixelInterleavedSampleModel with a subset of the
  127. * bands of this PixelInterleavedSampleModel. The new
  128. * PixelInterleavedSampleModel can be used with any DataBuffer that the
  129. * existing PixelInterleavedSampleModel can be used with. The new
  130. * PixelInterleavedSampleModel/DataBuffer combination will represent
  131. * an image with a subset of the bands of the original
  132. * PixelInterleavedSampleModel/DataBuffer combination.
  133. */
  134. public SampleModel createSubsetSampleModel(int bands[]) {
  135. int newBandOffsets[] = new int[bands.length];
  136. for (int i=0; i<bands.length; i++) {
  137. newBandOffsets[i] = bandOffsets[bands[i]];
  138. }
  139. return new PixelInterleavedSampleModel(this.dataType, width, height,
  140. this.pixelStride,
  141. scanlineStride, newBandOffsets);
  142. }
  143. // Differentiate hash code from other ComponentSampleModel subclasses
  144. public int hashCode() {
  145. return super.hashCode() ^ 0x1;
  146. }
  147. }