001 /*
002 * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.awt.image;
027
028 /**
029 * This class represents image data which is stored in a pixel interleaved
030 * fashion and for
031 * which each sample of a pixel occupies one data element of the DataBuffer.
032 * It subclasses ComponentSampleModel but provides a more efficent
033 * implementation for accessing pixel interleaved image data than is provided
034 * by ComponentSampleModel. This class
035 * stores sample data for all bands in a single bank of the
036 * DataBuffer. Accessor methods are provided so that image data can be
037 * manipulated directly. Pixel stride is the number of
038 * data array elements between two samples for the same band on the same
039 * scanline. Scanline stride is the number of data array elements between
040 * a given sample and the corresponding sample in the same column of the next
041 * scanline. Band offsets denote the number
042 * of data array elements from the first data array element of the bank
043 * of the DataBuffer holding each band to the first sample of the band.
044 * The bands are numbered from 0 to N-1.
045 * Bank indices denote the correspondence between a bank of the data buffer
046 * and a band of image data.
047 * This class supports
048 * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
049 * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
050 * {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
051 * {@link DataBuffer#TYPE_INT TYPE_INT},
052 * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT} and
053 * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes.
054 */
055
056 public class PixelInterleavedSampleModel extends ComponentSampleModel {
057 /**
058 * Constructs a PixelInterleavedSampleModel with the specified parameters.
059 * The number of bands will be given by the length of the bandOffsets
060 * array.
061 * @param dataType The data type for storing samples.
062 * @param w The width (in pixels) of the region of
063 * image data described.
064 * @param h The height (in pixels) of the region of
065 * image data described.
066 * @param pixelStride The pixel stride of the image data.
067 * @param scanlineStride The line stride of the image data.
068 * @param bandOffsets The offsets of all bands.
069 * @throws IllegalArgumentException if <code>w</code> or
070 * <code>h</code> is not greater than 0
071 * @throws IllegalArgumentException if any offset between bands is
072 * greater than the scanline stride
073 * @throws IllegalArgumentException if the product of
074 * <code>pixelStride</code> and <code>w</code> is greater
075 * than <code>scanlineStride</code>
076 * @throws IllegalArgumentException if <code>pixelStride</code> is
077 * less than any offset between bands
078 * @throws IllegalArgumentException if <code>dataType</code> is not
079 * one of the supported data types
080 */
081 public PixelInterleavedSampleModel(int dataType, int w, int h,
082 int pixelStride, int scanlineStride, int bandOffsets[]) {
083 super (dataType, w, h, pixelStride, scanlineStride, bandOffsets);
084 int minBandOff = bandOffsets[0];
085 int maxBandOff = bandOffsets[0];
086 for (int i = 1; i < bandOffsets.length; i++) {
087 minBandOff = Math.min(minBandOff, bandOffsets[i]);
088 maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
089 }
090 maxBandOff -= minBandOff;
091 if (maxBandOff > scanlineStride) {
092 throw new IllegalArgumentException(
093 "Offsets between bands must be"
094 + " less than the scanline " + " stride");
095 }
096 if (pixelStride * w > scanlineStride) {
097 throw new IllegalArgumentException(
098 "Pixel stride times width "
099 + "must be less than or "
100 + "equal to the scanline " + "stride");
101 }
102 if (pixelStride < maxBandOff) {
103 throw new IllegalArgumentException(
104 "Pixel stride must be greater"
105 + " than or equal to the offsets"
106 + " between bands");
107 }
108 }
109
110 /**
111 * Creates a new PixelInterleavedSampleModel with the specified
112 * width and height. The new PixelInterleavedSampleModel will have the
113 * same number of bands, storage data type, and pixel stride
114 * as this PixelInterleavedSampleModel. The band offsets may be
115 * compressed such that the minimum of all of the band offsets is zero.
116 * @param w the width of the resulting <code>SampleModel</code>
117 * @param h the height of the resulting <code>SampleModel</code>
118 * @return a new <code>SampleModel</code> with the specified width
119 * and height.
120 * @throws IllegalArgumentException if <code>w</code> or
121 * <code>h</code> is not greater than 0
122 */
123 public SampleModel createCompatibleSampleModel(int w, int h) {
124 int minBandoff = bandOffsets[0];
125 int numBands = bandOffsets.length;
126 for (int i = 1; i < numBands; i++) {
127 if (bandOffsets[i] < minBandoff) {
128 minBandoff = bandOffsets[i];
129 }
130 }
131 int[] bandOff;
132 if (minBandoff > 0) {
133 bandOff = new int[numBands];
134 for (int i = 0; i < numBands; i++) {
135 bandOff[i] = bandOffsets[i] - minBandoff;
136 }
137 } else {
138 bandOff = bandOffsets;
139 }
140 return new PixelInterleavedSampleModel(dataType, w, h,
141 pixelStride, pixelStride * w, bandOff);
142 }
143
144 /**
145 * Creates a new PixelInterleavedSampleModel with a subset of the
146 * bands of this PixelInterleavedSampleModel. The new
147 * PixelInterleavedSampleModel can be used with any DataBuffer that the
148 * existing PixelInterleavedSampleModel can be used with. The new
149 * PixelInterleavedSampleModel/DataBuffer combination will represent
150 * an image with a subset of the bands of the original
151 * PixelInterleavedSampleModel/DataBuffer combination.
152 */
153 public SampleModel createSubsetSampleModel(int bands[]) {
154 int newBandOffsets[] = new int[bands.length];
155 for (int i = 0; i < bands.length; i++) {
156 newBandOffsets[i] = bandOffsets[bands[i]];
157 }
158 return new PixelInterleavedSampleModel(this .dataType, width,
159 height, this .pixelStride, scanlineStride,
160 newBandOffsets);
161 }
162
163 // Differentiate hash code from other ComponentSampleModel subclasses
164 public int hashCode() {
165 return super .hashCode() ^ 0x1;
166 }
167 }
|