source: trunk/gcc/libjava/java/awt/image/ComponentSampleModel.java

Last change on this file was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 12.3 KB
Line 
1/* Copyright (C) 2000, 2002 Free Software Foundation
2
3This file is part of GNU Classpath.
4
5GNU Classpath is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2, or (at your option)
8any later version.
9
10GNU Classpath is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GNU Classpath; see the file COPYING. If not, write to the
17Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1802111-1307 USA.
19
20Linking this library statically or dynamically with other modules is
21making a combined work based on this library. Thus, the terms and
22conditions of the GNU General Public License cover the whole
23combination.
24
25As a special exception, the copyright holders of this library give you
26permission to link this library with independent modules to produce an
27executable, regardless of the license terms of these independent
28modules, and to copy and distribute the resulting executable under
29terms of your choice, provided that you also meet, for each linked
30independent module, the terms and conditions of the license of that
31module. An independent module is a module which is not derived from
32or based on this library. If you modify this library, you may extend
33this exception to your version of the library, but you are not
34obligated to do so. If you do not wish to do so, delete this
35exception statement from your version. */
36
37package java.awt.image;
38
39import gnu.java.awt.Buffers;
40
41/* FIXME: This class does not yet support data type TYPE_SHORT */
42
43/**
44 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
45 */
46public class ComponentSampleModel extends SampleModel
47{
48 protected int[] bandOffsets;
49 protected int[] bankIndices;
50
51 // FIXME: Should we really shadow the numBands in the superclass?
52 //protected int numBands;
53
54 /** Used when creating data buffers. */
55 protected int numBanks;
56
57 protected int scanlineStride;
58
59 protected int pixelStride;
60
61 private boolean tightPixelPacking = false;
62
63 public ComponentSampleModel(int dataType,
64 int w, int h,
65 int pixelStride,
66 int scanlineStride,
67 int[] bandOffsets)
68 {
69 this(dataType, w, h, pixelStride, scanlineStride,
70 new int[bandOffsets.length], bandOffsets);
71 }
72
73 public ComponentSampleModel(int dataType,
74 int w, int h,
75 int pixelStride,
76 int scanlineStride,
77 int[] bankIndices,
78 int[] bandOffsets)
79 {
80 super(dataType, w, h, bandOffsets.length);
81 if ((pixelStride<0) || (scanlineStride<0) ||
82 (bandOffsets.length<1) ||
83 (bandOffsets.length != bankIndices.length))
84 throw new IllegalArgumentException();
85
86 this.bandOffsets = bandOffsets;
87 this.bankIndices = bankIndices;
88
89 for (int b=0; b<bankIndices.length; b++)
90 this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
91
92 this.scanlineStride = scanlineStride;
93 this.pixelStride = pixelStride;
94
95 // See if we can use some speedups
96
97 /* FIXME: May these checks should be reserved for the
98 PixelInterleavedSampleModel? */
99
100 if (pixelStride == numBands)
101 {
102 tightPixelPacking = true;
103 for (int b=0; b<numBands; b++) {
104 if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
105 {
106 tightPixelPacking = false;
107 break;
108 }
109 }
110 }
111 }
112
113 public SampleModel createCompatibleSampleModel(int w, int h)
114 {
115 return new ComponentSampleModel(dataType, w, h, pixelStride,
116 scanlineStride, bankIndices,
117 bandOffsets);
118 }
119
120 public SampleModel createSubsetSampleModel(int[] bands)
121 {
122 int numBands = bands.length;
123
124 int[] bankIndices = new int[numBands];
125 int[] bandOffsets = new int[numBands];
126 for (int b=0; b<numBands; b++)
127 {
128 bankIndices[b] = this.bankIndices[bands[b]];
129 bandOffsets[b] = this.bandOffsets[bands[b]];
130 }
131
132 return new ComponentSampleModel(dataType, width, height, pixelStride,
133 scanlineStride, bankIndices,
134 bandOffsets);
135 }
136
137 public DataBuffer createDataBuffer()
138 {
139 // Maybe this value should be precalculated in the constructor?
140 int highestOffset = 0;
141 for (int b=0; b<numBands; b++)
142 {
143 highestOffset = Math.max(highestOffset, bandOffsets[b]);
144 }
145 int size = pixelStride*(width-1) + scanlineStride*(height-1) +
146 highestOffset + 1;
147
148 return Buffers.createBuffer(getDataType(), size, numBanks);
149 }
150
151 public int getOffset(int x, int y)
152 {
153 return getOffset(x, y, 0);
154 }
155
156 public int getOffset(int x, int y, int b)
157 {
158 return bandOffsets[b] + pixelStride*x + scanlineStride*y;
159 }
160
161 public final int[] getSampleSize()
162 {
163 int size = DataBuffer.getDataTypeSize(getDataType());
164 int[] sizes = new int[numBands];
165
166 java.util.Arrays.fill(sizes, size);
167 return sizes;
168 }
169
170 public final int getSampleSize(int band)
171 {
172 return DataBuffer.getDataTypeSize(getDataType());
173 }
174
175 public final int[] getBankIndices()
176 {
177 return bankIndices;
178 }
179
180 public final int[] getBandOffsets()
181 {
182 return bandOffsets;
183 }
184
185 public final int getScanlineStride()
186 {
187 return scanlineStride;
188 }
189
190 public final int getPixelStride()
191 {
192 return pixelStride;
193 }
194
195 public final int getNumDataElements()
196 {
197 return numBands;
198 }
199
200 public Object getDataElements(int x, int y, Object obj, DataBuffer data)
201 {
202 int xyOffset = pixelStride*x + scanlineStride*y;
203
204 int[] totalBandDataOffsets = new int[numBands];
205
206 /* Notice that band and bank offsets are different. Band offsets
207 are managed by the sample model, and bank offsets are managed
208 by the data buffer. Both must be accounted for. */
209
210 /* FIXME: For single pixels, it is probably easier to simple
211 call getElem instead of calculating the bank offset ourself.
212
213 On the other hand, then we need to push the value through
214 the int type returned by the getElem method. */
215
216 int[] bankOffsets = data.getOffsets();
217
218 for (int b=0; b<numBands; b++)
219 {
220 totalBandDataOffsets[b] =
221 bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
222 }
223
224 try
225 {
226 switch (getTransferType())
227 {
228 case DataBuffer.TYPE_BYTE:
229 DataBufferByte inByte = (DataBufferByte) data;
230 byte[] outByte = (byte[]) obj;
231 if (outByte == null) outByte = new byte[numBands];
232
233 for (int b=0; b<numBands; b++)
234 {
235 int dOffset = totalBandDataOffsets[b];
236 outByte[b] = inByte.getData(bankIndices[b])[dOffset];
237 }
238 return outByte;
239
240 case DataBuffer.TYPE_USHORT:
241 DataBufferUShort inUShort = (DataBufferUShort) data;
242 short[] outUShort = (short[]) obj;
243 if (outUShort == null) outUShort = new short[numBands];
244
245 for (int b=0; b<numBands; b++)
246 {
247 int dOffset = totalBandDataOffsets[b];
248 outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
249 }
250 return outUShort;
251
252 case DataBuffer.TYPE_INT:
253 DataBufferInt inInt = (DataBufferInt) data;
254 int[] outInt = (int[]) obj;
255 if (outInt == null) outInt = new int[numBands];
256
257 for (int b=0; b<numBands; b++)
258 {
259 int dOffset = totalBandDataOffsets[b];
260 outInt[b] = inInt.getData(bankIndices[b])[dOffset];
261 }
262 return outInt;
263
264 // FIXME: Fill in the other possible types.
265 default:
266 throw new IllegalStateException("unknown transfer type " +
267 getTransferType());
268 }
269 }
270 catch (ArrayIndexOutOfBoundsException aioobe)
271 {
272 String msg = "While reading data elements, " +
273 "x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
274 ", data.getSize()=" + data.getSize() + ": " + aioobe;
275 throw new ArrayIndexOutOfBoundsException(msg);
276 }
277 }
278
279 public Object getDataElements(int x, int y, int w, int h, Object obj,
280 DataBuffer data)
281 {
282 if (!tightPixelPacking)
283 {
284 return super.getDataElements(x, y, w, h, obj, data);
285 }
286
287 // using get speedup
288
289 // We can copy whole rows
290 int rowSize = w*numBands;
291 int dataSize = rowSize*h;
292
293 DataBuffer transferBuffer =
294 Buffers.createBuffer(getTransferType(), obj, dataSize);
295 obj = Buffers.getData(transferBuffer);
296
297 int inOffset =
298 pixelStride*x +
299 scanlineStride*y +
300 data.getOffset(); // Assumes only one band is used
301
302 /* We don't add band offsets since we assume that bands have
303 offsets 0, 1, 2, ... */
304
305 // See if we can copy everything in one go
306 if (scanlineStride == rowSize)
307 {
308 // Collapse scan lines:
309 rowSize *= h;
310 // We ignore scanlineStride since it won't be of any use
311 h = 1;
312 }
313
314 int outOffset = 0;
315 Object inArray = Buffers.getData(data);
316 for (int yd = 0; yd<h; yd++)
317 {
318 System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
319 inOffset += scanlineStride;
320 outOffset += rowSize;
321 }
322 return obj;
323 }
324
325 public void setDataElements(int x, int y, int w, int h,
326 Object obj, DataBuffer data)
327 {
328 if (!tightPixelPacking)
329 {
330 super.setDataElements(x, y, w, h, obj, data);
331 return;
332 }
333
334 // using set speedup, we can copy whole rows
335 int rowSize = w*numBands;
336 int dataSize = rowSize*h;
337
338 DataBuffer transferBuffer =
339 Buffers.createBufferFromData(getTransferType(), obj, dataSize);
340
341 int[] bankOffsets = data.getOffsets();
342
343 int outOffset =
344 pixelStride*x +
345 scanlineStride*y +
346 bankOffsets[0]; // same assuptions as in get...
347
348 // See if we can copy everything in one go
349 if (scanlineStride == rowSize)
350 {
351 // Collapse scan lines:
352 scanlineStride = rowSize *= h;
353 h = 1;
354 }
355
356 int inOffset = 0;
357 Object outArray = Buffers.getData(data);
358 for (int yd = 0; yd<h; yd++)
359 {
360 System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
361 outOffset += scanlineStride;
362 inOffset += rowSize;
363 }
364 }
365
366 public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
367 {
368 int offset = pixelStride*x + scanlineStride*y;
369 if (iArray == null) iArray = new int[numBands];
370 for (int b=0; b<numBands; b++)
371 {
372 iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
373 }
374 return iArray;
375 }
376
377 public int[] getPixels(int x, int y, int w, int h, int[] iArray,
378 DataBuffer data)
379 {
380 int offset = pixelStride*x + scanlineStride*y;
381 if (iArray == null) iArray = new int[numBands*w*h];
382 int outOffset = 0;
383 for (y=0; y<h; y++)
384 {
385 int lineOffset = offset;
386 for (x=0; x<w; x++)
387 {
388 for (int b=0; b<numBands; b++)
389 {
390 iArray[outOffset++] =
391 data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
392 }
393 lineOffset += pixelStride;
394 }
395 offset += scanlineStride;
396 }
397 return iArray;
398 }
399
400 public int getSample(int x, int y, int b, DataBuffer data)
401 {
402 return data.getElem(bankIndices[b], getOffset(x, y, b));
403 }
404
405 public void setDataElements(int x, int y, Object obj, DataBuffer data)
406 {
407 int offset = pixelStride*x + scanlineStride*y;
408 int[] totalBandDataOffsets = new int[numBands];
409 int[] bankOffsets = data.getOffsets();
410 for (int b=0; b<numBands; b++)
411 totalBandDataOffsets[b] =
412 bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
413
414 switch (getTransferType())
415 {
416 case DataBuffer.TYPE_BYTE:
417 {
418 DataBufferByte out = (DataBufferByte) data;
419 byte[] in = (byte[]) obj;
420
421 for (int b=0; b<numBands; b++)
422 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
423
424 return;
425 }
426 case DataBuffer.TYPE_USHORT:
427 {
428 DataBufferUShort out = (DataBufferUShort) data;
429 short[] in = (short[]) obj;
430
431 for (int b=0; b<numBands; b++)
432 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
433
434 return;
435 }
436 case DataBuffer.TYPE_INT:
437 {
438 DataBufferInt out = (DataBufferInt) data;
439 int[] in = (int[]) obj;
440
441 for (int b=0; b<numBands; b++)
442 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
443
444 return;
445 }
446 default:
447 throw new UnsupportedOperationException("transfer type not " +
448 "implemented");
449 }
450 }
451
452 public void setPixel(int x, int y, int[] iArray, DataBuffer data)
453 {
454 int offset = pixelStride*x + scanlineStride*y;
455 for (int b=0; b<numBands; b++)
456 data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
457 }
458
459 public void setSample(int x, int y, int b, int s, DataBuffer data)
460 {
461 data.setElem(bankIndices[b], getOffset(x, y, b), s);
462 }
463}
Note: See TracBrowser for help on using the repository browser.