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
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 this(sampleModel,
113 dataBuffer,
114 new Rectangle(origin.x,
115 origin.y,
116 sampleModel.getWidth(),
117 sampleModel.getHeight()),
118 origin,
119 null);
120 }
121
122 /*** Analyzes a ComponentSampleModel to determine if it can function
123 * as a PixelInterleavedSampleModel. In order to do so, it must use
124 * only bank 0 of its DataBuffer, and the data offsets must span a range
125 * of less than pixelStride.
126 *
127 * <p> These properties are trivially true for a 1-banded SampleModel.
128 */
129 private boolean isInterleaved(ComponentSampleModel sm) {
130 // Analyze ComponentSampleModel to determine if it has the
160 return false;
161 }
162
163 return true;
164 }
165
166 /**
167 * Constructs a ByteInterleavedRaster with the given SampleModel,
168 * DataBuffer, and parent. DataBuffer must be a DataBufferByte and
169 * SampleModel must be of type SinglePixelPackedSampleModel
170 * or InterleavedSampleModel.
171 * When translated into the base Raster's
172 * coordinate system, aRegion must be contained by the base Raster.
173 * Origin is the coordinate in the new Raster's coordinate system of
174 * the origin of the base Raster. (The base Raster is the Raster's
175 * ancestor which has no parent.)
176 *
177 * Note that this constructor should generally be called by other
178 * constructors or create methods, it should not be used directly.
179 * @param sampleModel The SampleModel that specifies the layout.
180 * @param dataBuffer The DataBufferByte that contains the image data.
181 * @param aRegion The Rectangle that specifies the image area.
182 * @param origin The Point that specifies the origin.
183 * @param parent The parent (if any) of this raster.
184 */
185 public ByteInterleavedRaster(SampleModel sampleModel,
186 DataBufferByte dataBuffer,
187 Rectangle aRegion,
188 Point origin,
189 ByteInterleavedRaster parent) {
190 super(sampleModel, dataBuffer, aRegion, origin, parent);
191 this.maxX = minX + width;
192 this.maxY = minY + height;
193
194 this.data = stealData(dataBuffer, 0);
195
196 int xOffset = aRegion.x - origin.x;
197 int yOffset = aRegion.y - origin.y;
198 if (sampleModel instanceof PixelInterleavedSampleModel ||
199 (sampleModel instanceof ComponentSampleModel &&
200 isInterleaved((ComponentSampleModel)sampleModel))) {
201 ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
202 this.scanlineStride = csm.getScanlineStride();
203 this.pixelStride = csm.getPixelStride();
204 this.dataOffsets = csm.getBandOffsets();
205 for (int i = 0; i < getNumDataElements(); i++) {
206 dataOffsets[i] += xOffset*pixelStride+yOffset*scanlineStride;
207 }
208 } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
209 SinglePixelPackedSampleModel sppsm =
210 (SinglePixelPackedSampleModel)sampleModel;
211 this.packed = true;
212 this.bitMasks = sppsm.getBitMasks();
213 this.bitOffsets = sppsm.getBitOffsets();
214 this.scanlineStride = sppsm.getScanlineStride();
215 this.pixelStride = 1;
216 this.dataOffsets = new int[1];
217 this.dataOffsets[0] = dataBuffer.getOffset();
218 dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
219 } else {
220 throw new RasterFormatException("ByteInterleavedRasters must " +
221 "have PixelInterleavedSampleModel, SinglePixelPackedSampleModel"+
222 " or interleaved ComponentSampleModel. Sample model is " +
223 sampleModel);
224 }
225 this.bandOffset = this.dataOffsets[0];
226
227 this.dbOffsetPacked = dataBuffer.getOffset() -
228 sampleModelTranslateY*scanlineStride -
229 sampleModelTranslateX*pixelStride;
230 this.dbOffset = dbOffsetPacked -
231 (xOffset*pixelStride+yOffset*scanlineStride);
232
233 // Set inOrder to true if the data elements are in order and
234 // have no gaps between them
235 this.inOrder = false;
236 if (numDataElements == pixelStride) {
237 inOrder = true;
1235 throw new RasterFormatException("y lies outside the raster");
1236 }
1237 if ((x+width < x) || (x+width > this.minX + this.width)) {
1238 throw new RasterFormatException("(x + width) is outside of Raster");
1239 }
1240 if ((y+height < y) || (y+height > this.minY + this.height)) {
1241 throw new RasterFormatException("(y + height) is outside of Raster");
1242 }
1243
1244 SampleModel sm;
1245
1246 if (bandList != null)
1247 sm = sampleModel.createSubsetSampleModel(bandList);
1248 else
1249 sm = sampleModel;
1250
1251 int deltaX = x0 - x;
1252 int deltaY = y0 - y;
1253
1254 return new ByteInterleavedRaster(sm,
1255 (DataBufferByte)dataBuffer,
1256 new Rectangle(x0, y0, width, height),
1257 new Point(sampleModelTranslateX+deltaX,
1258 sampleModelTranslateY+deltaY),
1259 this);
1260 }
1261
1262 /**
1263 * Creates a Raster with the same layout but using a different
1264 * width and height, and with new zeroed data arrays.
1265 */
1266 public WritableRaster createCompatibleWritableRaster(int w, int h) {
1267 if (w <= 0 || h <=0) {
1268 throw new RasterFormatException("negative "+
1269 ((w <= 0) ? "width" : "height"));
1270 }
1271
1272 SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
1273
1274 return new ByteInterleavedRaster(sm, new Point(0,0));
1275
|