1 /*
2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.awt.image;
27 import java.awt.image.Raster;
28 import java.awt.image.WritableRaster;
29 import java.awt.image.RasterFormatException;
30 import java.awt.image.SampleModel;
31 import java.awt.image.ComponentSampleModel;
32 import java.awt.image.PixelInterleavedSampleModel;
33 import java.awt.image.SinglePixelPackedSampleModel;
34 import java.awt.image.DataBuffer;
35 import java.awt.image.DataBufferByte;
36 import java.awt.Rectangle;
37 import java.awt.Point;
38
39 /**
40 * This class defines a Raster with pixels consisting of one or more
41 * 8-bit data elements stored in close proximity to each other in a
42 * single byte array.
43 * <p>
44 * The bit precision per data element is that of the data type (that
45 * is, the bit precision for this Raster is 8). There is only one
46 * pixel stride and one scanline stride for all bands. This type of
47 * Raster can be used with a ComponentColorModel if there are multiple
48 * bands, or an IndexColorModel if there is only one band.
49 *
50 */
51 public class ByteInterleavedRaster extends ByteComponentRaster {
52
53 /** True if the data offsets range from 0 to (pixelStride - 1) in order. */
54 boolean inOrder;
70 /** If packed == true, the SampleModel's bit offsets. */
71 int[] bitOffsets;
72
73 /** A cached copy of minX + width for use in bounds checks. */
74 private int maxX;
75
76 /** A cached copy of minY + height for use in bounds checks. */
77 private int maxY;
78
79 /**
80 * Constructs a ByteInterleavedRaster with the given SampleModel.
81 * The Raster's upper left corner is origin and it is the same
82 * size as the SampleModel. A DataBuffer large enough to describe the
83 * Raster is automatically created. SampleModel must be of type
84 * SinglePixelPackedSampleModel or InterleavedSampleModel.
85 * @param sampleModel The SampleModel that specifies the layout.
86 * @param origin The Point that specified the origin.
87 */
88 public ByteInterleavedRaster(SampleModel sampleModel, Point origin) {
89 this(sampleModel,
90 sampleModel.createDataBuffer(),
91 new Rectangle(origin.x,
92 origin.y,
93 sampleModel.getWidth(),
94 sampleModel.getHeight()),
95 origin,
96 null);
97 }
98
99 /**
100 * Constructs a ByteInterleavedRaster with the given SampleModel
101 * and DataBuffer. The Raster's upper left corner is origin and
102 * it is the same size as the SampleModel. The DataBuffer is not
103 * initialized and must be a DataBufferByte compatible with SampleModel.
104 * SampleModel must be of type SinglePixelPackedSampleModel
105 * or InterleavedSampleModel.
106 * @param sampleModel The SampleModel that specifies the layout.
107 * @param dataBuffer The DataBufferShort that contains the image data.
108 * @param origin The Point that specifies the origin.
109 */
110 public ByteInterleavedRaster(SampleModel sampleModel,
111 DataBuffer dataBuffer,
112 Point origin) {
113 this(sampleModel,
114 dataBuffer,
115 new Rectangle(origin.x,
116 origin.y,
117 sampleModel.getWidth(),
118 sampleModel.getHeight()),
119 origin,
120 null);
121 }
122
123 /*** Analyzes a ComponentSampleModel to determine if it can function
124 * as a PixelInterleavedSampleModel. In order to do so, it must use
125 * only bank 0 of its DataBuffer, and the data offsets must span a range
126 * of less than pixelStride.
127 *
128 * <p> These properties are trivially true for a 1-banded SampleModel.
129 */
130 private boolean isInterleaved(ComponentSampleModel sm) {
131 // Analyze ComponentSampleModel to determine if it has the
132 // properties of a PixelInterleavedSampleModel
161 return false;
162 }
163
164 return true;
165 }
166
167 /**
168 * Constructs a ByteInterleavedRaster with the given SampleModel,
169 * DataBuffer, and parent. DataBuffer must be a DataBufferByte and
170 * SampleModel must be of type SinglePixelPackedSampleModel
171 * or InterleavedSampleModel.
172 * When translated into the base Raster's
173 * coordinate system, aRegion must be contained by the base Raster.
174 * Origin is the coordinate in the new Raster's coordinate system of
175 * the origin of the base Raster. (The base Raster is the Raster's
176 * ancestor which has no parent.)
177 *
178 * Note that this constructor should generally be called by other
179 * constructors or create methods, it should not be used directly.
180 * @param sampleModel The SampleModel that specifies the layout.
181 * @param dataBuffer The DataBufferShort that contains the image data.
182 * @param aRegion The Rectangle that specifies the image area.
183 * @param origin The Point that specifies the origin.
184 * @param parent The parent (if any) of this raster.
185 */
186 public ByteInterleavedRaster(SampleModel sampleModel,
187 DataBuffer dataBuffer,
188 Rectangle aRegion,
189 Point origin,
190 ByteInterleavedRaster parent) {
191 super(sampleModel, dataBuffer, aRegion, origin, parent);
192 this.maxX = minX + width;
193 this.maxY = minY + height;
194
195 if (!(dataBuffer instanceof DataBufferByte)) {
196 throw new RasterFormatException("ByteInterleavedRasters must have " +
197 "byte DataBuffers");
198 }
199
200 DataBufferByte dbb = (DataBufferByte)dataBuffer;
201 this.data = stealData(dbb, 0);
202
203 int xOffset = aRegion.x - origin.x;
204 int yOffset = aRegion.y - origin.y;
205 if (sampleModel instanceof PixelInterleavedSampleModel ||
206 (sampleModel instanceof ComponentSampleModel &&
207 isInterleaved((ComponentSampleModel)sampleModel))) {
208 ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
209 this.scanlineStride = csm.getScanlineStride();
210 this.pixelStride = csm.getPixelStride();
211 this.dataOffsets = csm.getBandOffsets();
212 for (int i = 0; i < getNumDataElements(); i++) {
213 dataOffsets[i] += xOffset*pixelStride+yOffset*scanlineStride;
214 }
215 } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
216 SinglePixelPackedSampleModel sppsm =
217 (SinglePixelPackedSampleModel)sampleModel;
218 this.packed = true;
219 this.bitMasks = sppsm.getBitMasks();
220 this.bitOffsets = sppsm.getBitOffsets();
221 this.scanlineStride = sppsm.getScanlineStride();
222 this.pixelStride = 1;
223 this.dataOffsets = new int[1];
224 this.dataOffsets[0] = dbb.getOffset();
225 dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
226 } else {
227 throw new RasterFormatException("ByteInterleavedRasters must " +
228 "have PixelInterleavedSampleModel, SinglePixelPackedSampleModel"+
229 " or interleaved ComponentSampleModel. Sample model is " +
230 sampleModel);
231 }
232 this.bandOffset = this.dataOffsets[0];
233
234 this.dbOffsetPacked = dataBuffer.getOffset() -
235 sampleModelTranslateY*scanlineStride -
236 sampleModelTranslateX*pixelStride;
237 this.dbOffset = dbOffsetPacked -
238 (xOffset*pixelStride+yOffset*scanlineStride);
239
240 // Set inOrder to true if the data elements are in order and
241 // have no gaps between them
242 this.inOrder = false;
243 if (numDataElements == pixelStride) {
244 inOrder = true;
1242 throw new RasterFormatException("y lies outside the raster");
1243 }
1244 if ((x+width < x) || (x+width > this.minX + this.width)) {
1245 throw new RasterFormatException("(x + width) is outside of Raster");
1246 }
1247 if ((y+height < y) || (y+height > this.minY + this.height)) {
1248 throw new RasterFormatException("(y + height) is outside of Raster");
1249 }
1250
1251 SampleModel sm;
1252
1253 if (bandList != null)
1254 sm = sampleModel.createSubsetSampleModel(bandList);
1255 else
1256 sm = sampleModel;
1257
1258 int deltaX = x0 - x;
1259 int deltaY = y0 - y;
1260
1261 return new ByteInterleavedRaster(sm,
1262 dataBuffer,
1263 new Rectangle(x0, y0, width, height),
1264 new Point(sampleModelTranslateX+deltaX,
1265 sampleModelTranslateY+deltaY),
1266 this);
1267 }
1268
1269 /**
1270 * Creates a Raster with the same layout but using a different
1271 * width and height, and with new zeroed data arrays.
1272 */
1273 public WritableRaster createCompatibleWritableRaster(int w, int h) {
1274 if (w <= 0 || h <=0) {
1275 throw new RasterFormatException("negative "+
1276 ((w <= 0) ? "width" : "height"));
1277 }
1278
1279 SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
1280
1281 return new ByteInterleavedRaster(sm, new Point(0,0));
1282
|
1 /*
2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.awt.image;
27 import java.awt.image.Raster;
28 import java.awt.image.WritableRaster;
29 import java.awt.image.RasterFormatException;
30 import java.awt.image.SampleModel;
31 import java.awt.image.ComponentSampleModel;
32 import java.awt.image.PixelInterleavedSampleModel;
33 import java.awt.image.SinglePixelPackedSampleModel;
34 import java.awt.image.DataBufferByte;
35 import java.awt.Rectangle;
36 import java.awt.Point;
37
38 /**
39 * This class defines a Raster with pixels consisting of one or more
40 * 8-bit data elements stored in close proximity to each other in a
41 * single byte array.
42 * <p>
43 * The bit precision per data element is that of the data type (that
44 * is, the bit precision for this Raster is 8). There is only one
45 * pixel stride and one scanline stride for all bands. This type of
46 * Raster can be used with a ComponentColorModel if there are multiple
47 * bands, or an IndexColorModel if there is only one band.
48 *
49 */
50 public class ByteInterleavedRaster extends ByteComponentRaster {
51
52 /** True if the data offsets range from 0 to (pixelStride - 1) in order. */
53 boolean inOrder;
69 /** If packed == true, the SampleModel's bit offsets. */
70 int[] bitOffsets;
71
72 /** A cached copy of minX + width for use in bounds checks. */
73 private int maxX;
74
75 /** A cached copy of minY + height for use in bounds checks. */
76 private int maxY;
77
78 /**
79 * Constructs a ByteInterleavedRaster with the given SampleModel.
80 * The Raster's upper left corner is origin and it is the same
81 * size as the SampleModel. A DataBuffer large enough to describe the
82 * Raster is automatically created. SampleModel must be of type
83 * SinglePixelPackedSampleModel or InterleavedSampleModel.
84 * @param sampleModel The SampleModel that specifies the layout.
85 * @param origin The Point that specified the origin.
86 */
87 public ByteInterleavedRaster(SampleModel sampleModel, Point origin) {
88 this(sampleModel,
89 (DataBufferByte) sampleModel.createDataBuffer(),
90 new Rectangle(origin.x,
91 origin.y,
92 sampleModel.getWidth(),
93 sampleModel.getHeight()),
94 origin,
95 null);
96 }
97
98 /**
99 * Constructs a ByteInterleavedRaster with the given SampleModel
100 * and DataBuffer. The Raster's upper left corner is origin and
101 * it is the same size as the SampleModel. The DataBuffer is not
102 * initialized and must be a DataBufferByte compatible with SampleModel.
103 * SampleModel must be of type SinglePixelPackedSampleModel
104 * or InterleavedSampleModel.
105 * @param sampleModel The SampleModel that specifies the layout.
106 * @param dataBuffer The DataBufferByte that contains the image data.
107 * @param origin The Point that specifies the origin.
108 */
109 public ByteInterleavedRaster(SampleModel sampleModel,
110 DataBufferByte dataBuffer,
111 Point origin)
112 {
113 this(sampleModel,
114 dataBuffer,
115 new Rectangle(origin.x,
116 origin.y,
117 sampleModel.getWidth(),
118 sampleModel.getHeight()),
119 origin,
120 null);
121 }
122
123 /*** Analyzes a ComponentSampleModel to determine if it can function
124 * as a PixelInterleavedSampleModel. In order to do so, it must use
125 * only bank 0 of its DataBuffer, and the data offsets must span a range
126 * of less than pixelStride.
127 *
128 * <p> These properties are trivially true for a 1-banded SampleModel.
129 */
130 private boolean isInterleaved(ComponentSampleModel sm) {
131 // Analyze ComponentSampleModel to determine if it has the
132 // properties of a PixelInterleavedSampleModel
161 return false;
162 }
163
164 return true;
165 }
166
167 /**
168 * Constructs a ByteInterleavedRaster with the given SampleModel,
169 * DataBuffer, and parent. DataBuffer must be a DataBufferByte and
170 * SampleModel must be of type SinglePixelPackedSampleModel
171 * or InterleavedSampleModel.
172 * When translated into the base Raster's
173 * coordinate system, aRegion must be contained by the base Raster.
174 * Origin is the coordinate in the new Raster's coordinate system of
175 * the origin of the base Raster. (The base Raster is the Raster's
176 * ancestor which has no parent.)
177 *
178 * Note that this constructor should generally be called by other
179 * constructors or create methods, it should not be used directly.
180 * @param sampleModel The SampleModel that specifies the layout.
181 * @param dataBuffer The DataBufferByte that contains the image data.
182 * @param aRegion The Rectangle that specifies the image area.
183 * @param origin The Point that specifies the origin.
184 * @param parent The parent (if any) of this raster.
185 */
186 public ByteInterleavedRaster(SampleModel sampleModel,
187 DataBufferByte dataBuffer,
188 Rectangle aRegion,
189 Point origin,
190 ByteInterleavedRaster parent)
191 {
192 super(sampleModel, dataBuffer, aRegion, origin, parent);
193 this.maxX = minX + width;
194 this.maxY = minY + height;
195
196 this.data = stealData(dataBuffer, 0);
197
198 int xOffset = aRegion.x - origin.x;
199 int yOffset = aRegion.y - origin.y;
200 if (sampleModel instanceof PixelInterleavedSampleModel ||
201 (sampleModel instanceof ComponentSampleModel &&
202 isInterleaved((ComponentSampleModel)sampleModel))) {
203 ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
204 this.scanlineStride = csm.getScanlineStride();
205 this.pixelStride = csm.getPixelStride();
206 this.dataOffsets = csm.getBandOffsets();
207 for (int i = 0; i < getNumDataElements(); i++) {
208 dataOffsets[i] += xOffset*pixelStride+yOffset*scanlineStride;
209 }
210 } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
211 SinglePixelPackedSampleModel sppsm =
212 (SinglePixelPackedSampleModel)sampleModel;
213 this.packed = true;
214 this.bitMasks = sppsm.getBitMasks();
215 this.bitOffsets = sppsm.getBitOffsets();
216 this.scanlineStride = sppsm.getScanlineStride();
217 this.pixelStride = 1;
218 this.dataOffsets = new int[1];
219 this.dataOffsets[0] = dataBuffer.getOffset();
220 dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
221 } else {
222 throw new RasterFormatException("ByteInterleavedRasters must " +
223 "have PixelInterleavedSampleModel, SinglePixelPackedSampleModel"+
224 " or interleaved ComponentSampleModel. Sample model is " +
225 sampleModel);
226 }
227 this.bandOffset = this.dataOffsets[0];
228
229 this.dbOffsetPacked = dataBuffer.getOffset() -
230 sampleModelTranslateY*scanlineStride -
231 sampleModelTranslateX*pixelStride;
232 this.dbOffset = dbOffsetPacked -
233 (xOffset*pixelStride+yOffset*scanlineStride);
234
235 // Set inOrder to true if the data elements are in order and
236 // have no gaps between them
237 this.inOrder = false;
238 if (numDataElements == pixelStride) {
239 inOrder = true;
1237 throw new RasterFormatException("y lies outside the raster");
1238 }
1239 if ((x+width < x) || (x+width > this.minX + this.width)) {
1240 throw new RasterFormatException("(x + width) is outside of Raster");
1241 }
1242 if ((y+height < y) || (y+height > this.minY + this.height)) {
1243 throw new RasterFormatException("(y + height) is outside of Raster");
1244 }
1245
1246 SampleModel sm;
1247
1248 if (bandList != null)
1249 sm = sampleModel.createSubsetSampleModel(bandList);
1250 else
1251 sm = sampleModel;
1252
1253 int deltaX = x0 - x;
1254 int deltaY = y0 - y;
1255
1256 return new ByteInterleavedRaster(sm,
1257 (DataBufferByte) dataBuffer,
1258 new Rectangle(x0, y0, width, height),
1259 new Point(sampleModelTranslateX+deltaX,
1260 sampleModelTranslateY+deltaY),
1261 this);
1262 }
1263
1264 /**
1265 * Creates a Raster with the same layout but using a different
1266 * width and height, and with new zeroed data arrays.
1267 */
1268 public WritableRaster createCompatibleWritableRaster(int w, int h) {
1269 if (w <= 0 || h <=0) {
1270 throw new RasterFormatException("negative "+
1271 ((w <= 0) ? "width" : "height"));
1272 }
1273
1274 SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
1275
1276 return new ByteInterleavedRaster(sm, new Point(0,0));
1277
|