2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / awt / image / ComponentSampleModel.java
blob0a40161adeb78b0a09cd415994ef15eec13559a3
1 /* Copyright (C) 2000, 2002 Free Software Foundation
3 This file is part of GNU Classpath.
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA.
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library. Thus, the terms and
22 conditions of the GNU General Public License cover the whole
23 combination.
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module. An independent module is a module which is not derived from
32 or based on this library. If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so. If you do not wish to do so, delete this
35 exception statement from your version. */
37 package java.awt.image;
39 import gnu.java.awt.Buffers;
41 /* FIXME: This class does not yet support data type TYPE_SHORT */
43 /**
44 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
46 public class ComponentSampleModel extends SampleModel
48 protected int[] bandOffsets;
49 protected int[] bankIndices;
51 // FIXME: Should we really shadow the numBands in the superclass?
52 //protected int numBands;
54 /** Used when creating data buffers. */
55 protected int numBanks;
57 protected int scanlineStride;
59 protected int pixelStride;
61 private boolean tightPixelPacking = false;
63 public ComponentSampleModel(int dataType,
64 int w, int h,
65 int pixelStride,
66 int scanlineStride,
67 int[] bandOffsets)
69 this(dataType, w, h, pixelStride, scanlineStride,
70 new int[bandOffsets.length], bandOffsets);
73 public ComponentSampleModel(int dataType,
74 int w, int h,
75 int pixelStride,
76 int scanlineStride,
77 int[] bankIndices,
78 int[] bandOffsets)
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();
86 this.bandOffsets = bandOffsets;
87 this.bankIndices = bankIndices;
89 for (int b=0; b<bankIndices.length; b++)
90 this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
92 this.scanlineStride = scanlineStride;
93 this.pixelStride = pixelStride;
95 // See if we can use some speedups
97 /* FIXME: May these checks should be reserved for the
98 PixelInterleavedSampleModel? */
100 if (pixelStride == numBands)
102 tightPixelPacking = true;
103 for (int b=0; b<numBands; b++) {
104 if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
106 tightPixelPacking = false;
107 break;
113 public SampleModel createCompatibleSampleModel(int w, int h)
115 return new ComponentSampleModel(dataType, w, h, pixelStride,
116 scanlineStride, bankIndices,
117 bandOffsets);
120 public SampleModel createSubsetSampleModel(int[] bands)
122 int numBands = bands.length;
124 int[] bankIndices = new int[numBands];
125 int[] bandOffsets = new int[numBands];
126 for (int b=0; b<numBands; b++)
128 bankIndices[b] = this.bankIndices[bands[b]];
129 bandOffsets[b] = this.bandOffsets[bands[b]];
132 return new ComponentSampleModel(dataType, width, height, pixelStride,
133 scanlineStride, bankIndices,
134 bandOffsets);
137 public DataBuffer createDataBuffer()
139 // Maybe this value should be precalculated in the constructor?
140 int highestOffset = 0;
141 for (int b=0; b<numBands; b++)
143 highestOffset = Math.max(highestOffset, bandOffsets[b]);
145 int size = pixelStride*(width-1) + scanlineStride*(height-1) +
146 highestOffset + 1;
148 return Buffers.createBuffer(getDataType(), size, numBanks);
151 public int getOffset(int x, int y)
153 return getOffset(x, y, 0);
156 public int getOffset(int x, int y, int b)
158 return bandOffsets[b] + pixelStride*x + scanlineStride*y;
161 public final int[] getSampleSize()
163 int size = DataBuffer.getDataTypeSize(getDataType());
164 int[] sizes = new int[numBands];
166 java.util.Arrays.fill(sizes, size);
167 return sizes;
170 public final int getSampleSize(int band)
172 return DataBuffer.getDataTypeSize(getDataType());
175 public final int[] getBankIndices()
177 return bankIndices;
180 public final int[] getBandOffsets()
182 return bandOffsets;
185 public final int getScanlineStride()
187 return scanlineStride;
190 public final int getPixelStride()
192 return pixelStride;
195 public final int getNumDataElements()
197 return numBands;
200 public Object getDataElements(int x, int y, Object obj, DataBuffer data)
202 int xyOffset = pixelStride*x + scanlineStride*y;
204 int[] totalBandDataOffsets = new int[numBands];
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. */
210 /* FIXME: For single pixels, it is probably easier to simple
211 call getElem instead of calculating the bank offset ourself.
213 On the other hand, then we need to push the value through
214 the int type returned by the getElem method. */
216 int[] bankOffsets = data.getOffsets();
218 for (int b=0; b<numBands; b++)
220 totalBandDataOffsets[b] =
221 bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
226 switch (getTransferType())
228 case DataBuffer.TYPE_BYTE:
229 DataBufferByte inByte = (DataBufferByte) data;
230 byte[] outByte = (byte[]) obj;
231 if (outByte == null) outByte = new byte[numBands];
233 for (int b=0; b<numBands; b++)
235 int dOffset = totalBandDataOffsets[b];
236 outByte[b] = inByte.getData(bankIndices[b])[dOffset];
238 return outByte;
240 case DataBuffer.TYPE_USHORT:
241 DataBufferUShort inUShort = (DataBufferUShort) data;
242 short[] outUShort = (short[]) obj;
243 if (outUShort == null) outUShort = new short[numBands];
245 for (int b=0; b<numBands; b++)
247 int dOffset = totalBandDataOffsets[b];
248 outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
250 return outUShort;
252 case DataBuffer.TYPE_INT:
253 DataBufferInt inInt = (DataBufferInt) data;
254 int[] outInt = (int[]) obj;
255 if (outInt == null) outInt = new int[numBands];
257 for (int b=0; b<numBands; b++)
259 int dOffset = totalBandDataOffsets[b];
260 outInt[b] = inInt.getData(bankIndices[b])[dOffset];
262 return outInt;
264 // FIXME: Fill in the other possible types.
265 default:
266 throw new IllegalStateException("unknown transfer type " +
267 getTransferType());
270 catch (ArrayIndexOutOfBoundsException aioobe)
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);
279 public Object getDataElements(int x, int y, int w, int h, Object obj,
280 DataBuffer data)
282 if (!tightPixelPacking)
284 return super.getDataElements(x, y, w, h, obj, data);
287 // using get speedup
289 // We can copy whole rows
290 int rowSize = w*numBands;
291 int dataSize = rowSize*h;
293 DataBuffer transferBuffer =
294 Buffers.createBuffer(getTransferType(), obj, dataSize);
295 obj = Buffers.getData(transferBuffer);
297 int inOffset =
298 pixelStride*x +
299 scanlineStride*y +
300 data.getOffset(); // Assumes only one band is used
302 /* We don't add band offsets since we assume that bands have
303 offsets 0, 1, 2, ... */
305 // See if we can copy everything in one go
306 if (scanlineStride == rowSize)
308 // Collapse scan lines:
309 rowSize *= h;
310 // We ignore scanlineStride since it won't be of any use
311 h = 1;
314 int outOffset = 0;
315 Object inArray = Buffers.getData(data);
316 for (int yd = 0; yd<h; yd++)
318 System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
319 inOffset += scanlineStride;
320 outOffset += rowSize;
322 return obj;
325 public void setDataElements(int x, int y, int w, int h,
326 Object obj, DataBuffer data)
328 if (!tightPixelPacking)
330 super.setDataElements(x, y, w, h, obj, data);
331 return;
334 // using set speedup, we can copy whole rows
335 int rowSize = w*numBands;
336 int dataSize = rowSize*h;
338 DataBuffer transferBuffer =
339 Buffers.createBufferFromData(getTransferType(), obj, dataSize);
341 int[] bankOffsets = data.getOffsets();
343 int outOffset =
344 pixelStride*x +
345 scanlineStride*y +
346 bankOffsets[0]; // same assuptions as in get...
348 // See if we can copy everything in one go
349 if (scanlineStride == rowSize)
351 // Collapse scan lines:
352 scanlineStride = rowSize *= h;
353 h = 1;
356 int inOffset = 0;
357 Object outArray = Buffers.getData(data);
358 for (int yd = 0; yd<h; yd++)
360 System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
361 outOffset += scanlineStride;
362 inOffset += rowSize;
366 public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
368 int offset = pixelStride*x + scanlineStride*y;
369 if (iArray == null) iArray = new int[numBands];
370 for (int b=0; b<numBands; b++)
372 iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
374 return iArray;
377 public int[] getPixels(int x, int y, int w, int h, int[] iArray,
378 DataBuffer data)
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++)
385 int lineOffset = offset;
386 for (x=0; x<w; x++)
388 for (int b=0; b<numBands; b++)
390 iArray[outOffset++] =
391 data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
393 lineOffset += pixelStride;
395 offset += scanlineStride;
397 return iArray;
400 public int getSample(int x, int y, int b, DataBuffer data)
402 return data.getElem(bankIndices[b], getOffset(x, y, b));
405 public void setDataElements(int x, int y, Object obj, DataBuffer data)
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;
414 switch (getTransferType())
416 case DataBuffer.TYPE_BYTE:
418 DataBufferByte out = (DataBufferByte) data;
419 byte[] in = (byte[]) obj;
421 for (int b=0; b<numBands; b++)
422 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
424 return;
426 case DataBuffer.TYPE_USHORT:
428 DataBufferUShort out = (DataBufferUShort) data;
429 short[] in = (short[]) obj;
431 for (int b=0; b<numBands; b++)
432 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
434 return;
436 case DataBuffer.TYPE_INT:
438 DataBufferInt out = (DataBufferInt) data;
439 int[] in = (int[]) obj;
441 for (int b=0; b<numBands; b++)
442 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
444 return;
446 default:
447 throw new UnsupportedOperationException("transfer type not " +
448 "implemented");
452 public void setPixel(int x, int y, int[] iArray, DataBuffer data)
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]);
459 public void setSample(int x, int y, int b, int s, DataBuffer data)
461 data.setElem(bankIndices[b], getOffset(x, y, b), s);