Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / java / awt / image / ComponentSampleModel.java
blob5cf06e4a17f994f02cb82ec2434f3fd3b67e35b5
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., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 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 * ComponentSampleModel supports a flexible organization of pixel samples in
45 * memory, permitting pixel samples to be interleaved by band, by scanline,
46 * and by pixel.
48 * A DataBuffer for this sample model has K banks of data. Pixels have N
49 * samples, so there are N bands in the DataBuffer. Each band is completely
50 * contained in one bank of data, but a bank may contain more than one band.
51 * Each pixel sample is stored in a single data element.
53 * Within a bank, each band begins at an offset stored in bandOffsets. The
54 * banks containing the band is given by bankIndices. Within the bank, there
55 * are three dimensions - band, pixel, and scanline. The dimension ordering
56 * is controlled by bandOffset, pixelStride, and scanlineStride, which means
57 * that any combination of interleavings is supported.
59 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
61 public class ComponentSampleModel extends SampleModel
63 protected int[] bandOffsets;
64 protected int[] bankIndices;
66 /**
67 * Number of bands in the image described.
68 * @specnote This field shadows the protected numBands in SampleModel.
70 protected int numBands;
72 /** Used when creating data buffers. */
73 protected int numBanks;
75 protected int scanlineStride;
77 protected int pixelStride;
79 private boolean tightPixelPacking = false;
81 public ComponentSampleModel(int dataType,
82 int w, int h,
83 int pixelStride,
84 int scanlineStride,
85 int[] bandOffsets)
87 this(dataType, w, h, pixelStride, scanlineStride,
88 new int[bandOffsets.length], bandOffsets);
91 public ComponentSampleModel(int dataType,
92 int w, int h,
93 int pixelStride,
94 int scanlineStride,
95 int[] bankIndices,
96 int[] bandOffsets)
98 super(dataType, w, h, bandOffsets.length);
99 if ((pixelStride<0) || (scanlineStride<0) ||
100 (bandOffsets.length<1) ||
101 (bandOffsets.length != bankIndices.length))
102 throw new IllegalArgumentException();
104 this.bandOffsets = bandOffsets;
105 this.bankIndices = bankIndices;
106 this.numBands = bandOffsets.length;
108 this.numBanks = 0;
109 for (int b=0; b<bankIndices.length; b++)
110 this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
112 this.scanlineStride = scanlineStride;
113 this.pixelStride = pixelStride;
115 // See if we can use some speedups
117 /* FIXME: May these checks should be reserved for the
118 PixelInterleavedSampleModel? */
120 if (pixelStride == numBands)
122 tightPixelPacking = true;
123 for (int b=0; b<numBands; b++) {
124 if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
126 tightPixelPacking = false;
127 break;
133 public SampleModel createCompatibleSampleModel(int w, int h)
135 return new ComponentSampleModel(dataType, w, h, pixelStride,
136 scanlineStride, bankIndices,
137 bandOffsets);
140 public SampleModel createSubsetSampleModel(int[] bands)
142 int numBands = bands.length;
144 int[] bankIndices = new int[numBands];
145 int[] bandOffsets = new int[numBands];
146 for (int b=0; b<numBands; b++)
148 bankIndices[b] = this.bankIndices[bands[b]];
149 bandOffsets[b] = this.bandOffsets[bands[b]];
152 return new ComponentSampleModel(dataType, width, height, pixelStride,
153 scanlineStride, bankIndices,
154 bandOffsets);
157 public DataBuffer createDataBuffer()
159 // Maybe this value should be precalculated in the constructor?
160 int highestOffset = 0;
161 for (int b=0; b<numBands; b++)
163 highestOffset = Math.max(highestOffset, bandOffsets[b]);
165 int size = pixelStride*(width-1) + scanlineStride*(height-1) +
166 highestOffset + 1;
168 return Buffers.createBuffer(getDataType(), size, numBanks);
171 public int getOffset(int x, int y)
173 return getOffset(x, y, 0);
176 public int getOffset(int x, int y, int b)
178 return bandOffsets[b] + pixelStride*x + scanlineStride*y;
181 public final int[] getSampleSize()
183 int size = DataBuffer.getDataTypeSize(getDataType());
184 int[] sizes = new int[numBands];
186 java.util.Arrays.fill(sizes, size);
187 return sizes;
190 public final int getSampleSize(int band)
192 return DataBuffer.getDataTypeSize(getDataType());
195 public final int[] getBankIndices()
197 return bankIndices;
200 public final int[] getBandOffsets()
202 return bandOffsets;
205 public final int getScanlineStride()
207 return scanlineStride;
210 public final int getPixelStride()
212 return pixelStride;
215 public final int getNumDataElements()
217 return numBands;
220 public Object getDataElements(int x, int y, Object obj, DataBuffer data)
222 int xyOffset = pixelStride*x + scanlineStride*y;
224 int[] totalBandDataOffsets = new int[numBands];
226 /* Notice that band and bank offsets are different. Band offsets
227 are managed by the sample model, and bank offsets are managed
228 by the data buffer. Both must be accounted for. */
230 /* FIXME: For single pixels, it is probably easier to simple
231 call getElem instead of calculating the bank offset ourself.
233 On the other hand, then we need to push the value through
234 the int type returned by the getElem method. */
236 int[] bankOffsets = data.getOffsets();
238 for (int b=0; b<numBands; b++)
240 totalBandDataOffsets[b] =
241 bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
246 switch (getTransferType())
248 case DataBuffer.TYPE_BYTE:
249 DataBufferByte inByte = (DataBufferByte) data;
250 byte[] outByte = (byte[]) obj;
251 if (outByte == null) outByte = new byte[numBands];
253 for (int b=0; b<numBands; b++)
255 int dOffset = totalBandDataOffsets[b];
256 outByte[b] = inByte.getData(bankIndices[b])[dOffset];
258 return outByte;
260 case DataBuffer.TYPE_USHORT:
261 DataBufferUShort inUShort = (DataBufferUShort) data;
262 short[] outUShort = (short[]) obj;
263 if (outUShort == null) outUShort = new short[numBands];
265 for (int b=0; b<numBands; b++)
267 int dOffset = totalBandDataOffsets[b];
268 outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
270 return outUShort;
272 case DataBuffer.TYPE_SHORT:
273 DataBufferShort inShort = (DataBufferShort) data;
274 short[] outShort = (short[]) obj;
275 if (outShort == null) outShort = new short[numBands];
277 for (int b=0; b<numBands; b++)
279 int dOffset = totalBandDataOffsets[b];
280 outShort[b] = inShort.getData(bankIndices[b])[dOffset];
282 return outShort;
284 case DataBuffer.TYPE_INT:
285 DataBufferInt inInt = (DataBufferInt) data;
286 int[] outInt = (int[]) obj;
287 if (outInt == null) outInt = new int[numBands];
289 for (int b=0; b<numBands; b++)
291 int dOffset = totalBandDataOffsets[b];
292 outInt[b] = inInt.getData(bankIndices[b])[dOffset];
294 return outInt;
296 case DataBuffer.TYPE_FLOAT:
297 DataBufferFloat inFloat = (DataBufferFloat) data;
298 float[] outFloat = (float[]) obj;
299 if (outFloat == null) outFloat = new float[numBands];
301 for (int b=0; b<numBands; b++)
303 int dOffset = totalBandDataOffsets[b];
304 outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
306 return outFloat;
308 case DataBuffer.TYPE_DOUBLE:
309 DataBufferDouble inDouble = (DataBufferDouble) data;
310 double[] outDouble = (double[]) obj;
311 if (outDouble == null) outDouble = new double[numBands];
313 for (int b=0; b<numBands; b++)
315 int dOffset = totalBandDataOffsets[b];
316 outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
318 return outDouble;
320 default:
321 throw new IllegalStateException("unknown transfer type " +
322 getTransferType());
325 catch (ArrayIndexOutOfBoundsException aioobe)
327 String msg = "While reading data elements, " +
328 "x=" + x + ", y=" + y +", " + ", xyOffset=" + xyOffset +
329 ", data.getSize()=" + data.getSize() + ": " + aioobe;
330 throw new ArrayIndexOutOfBoundsException(msg);
334 public Object getDataElements(int x, int y, int w, int h, Object obj,
335 DataBuffer data)
337 if (!tightPixelPacking)
339 return super.getDataElements(x, y, w, h, obj, data);
342 // using get speedup
344 // We can copy whole rows
345 int rowSize = w*numBands;
346 int dataSize = rowSize*h;
348 DataBuffer transferBuffer =
349 Buffers.createBuffer(getTransferType(), obj, dataSize);
350 obj = Buffers.getData(transferBuffer);
352 int inOffset =
353 pixelStride*x +
354 scanlineStride*y +
355 data.getOffset(); // Assumes only one band is used
357 /* We don't add band offsets since we assume that bands have
358 offsets 0, 1, 2, ... */
360 // See if we can copy everything in one go
361 if (scanlineStride == rowSize)
363 // Collapse scan lines:
364 rowSize *= h;
365 // We ignore scanlineStride since it won't be of any use
366 h = 1;
369 int outOffset = 0;
370 Object inArray = Buffers.getData(data);
371 for (int yd = 0; yd<h; yd++)
373 System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
374 inOffset += scanlineStride;
375 outOffset += rowSize;
377 return obj;
380 public void setDataElements(int x, int y, int w, int h,
381 Object obj, DataBuffer data)
383 if (!tightPixelPacking)
385 super.setDataElements(x, y, w, h, obj, data);
386 return;
389 // using set speedup, we can copy whole rows
390 int rowSize = w*numBands;
391 int dataSize = rowSize*h;
393 DataBuffer transferBuffer =
394 Buffers.createBufferFromData(getTransferType(), obj, dataSize);
396 int[] bankOffsets = data.getOffsets();
398 int outOffset =
399 pixelStride*x +
400 scanlineStride*y +
401 bankOffsets[0]; // same assuptions as in get...
403 // See if we can copy everything in one go
404 if (scanlineStride == rowSize)
406 // Collapse scan lines:
407 rowSize *= h;
408 h = 1;
411 int inOffset = 0;
412 Object outArray = Buffers.getData(data);
413 for (int yd = 0; yd<h; yd++)
415 System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
416 outOffset += scanlineStride;
417 inOffset += rowSize;
421 public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
423 int offset = pixelStride*x + scanlineStride*y;
424 if (iArray == null) iArray = new int[numBands];
425 for (int b=0; b<numBands; b++)
427 iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
429 return iArray;
432 public int[] getPixels(int x, int y, int w, int h, int[] iArray,
433 DataBuffer data)
435 int offset = pixelStride*x + scanlineStride*y;
436 if (iArray == null) iArray = new int[numBands*w*h];
437 int outOffset = 0;
438 for (y=0; y<h; y++)
440 int lineOffset = offset;
441 for (x=0; x<w; x++)
443 for (int b=0; b<numBands; b++)
445 iArray[outOffset++] =
446 data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
448 lineOffset += pixelStride;
450 offset += scanlineStride;
452 return iArray;
455 public int getSample(int x, int y, int b, DataBuffer data)
457 return data.getElem(bankIndices[b], getOffset(x, y, b));
460 public void setDataElements(int x, int y, Object obj, DataBuffer data)
462 int offset = pixelStride*x + scanlineStride*y;
463 int[] totalBandDataOffsets = new int[numBands];
464 int[] bankOffsets = data.getOffsets();
465 for (int b=0; b<numBands; b++)
466 totalBandDataOffsets[b] =
467 bandOffsets[b]+bankOffsets[bankIndices[b]] + offset;
469 switch (getTransferType())
471 case DataBuffer.TYPE_BYTE:
473 DataBufferByte out = (DataBufferByte) data;
474 byte[] in = (byte[]) obj;
476 for (int b=0; b<numBands; b++)
477 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
479 return;
481 case DataBuffer.TYPE_USHORT:
483 DataBufferUShort out = (DataBufferUShort) data;
484 short[] in = (short[]) obj;
486 for (int b=0; b<numBands; b++)
487 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
489 return;
491 case DataBuffer.TYPE_SHORT:
493 DataBufferShort out = (DataBufferShort) data;
494 short[] in = (short[]) obj;
496 for (int b=0; b<numBands; b++)
497 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
499 return;
501 case DataBuffer.TYPE_INT:
503 DataBufferInt out = (DataBufferInt) data;
504 int[] in = (int[]) obj;
506 for (int b=0; b<numBands; b++)
507 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
509 return;
511 case DataBuffer.TYPE_FLOAT:
513 DataBufferFloat out = (DataBufferFloat) data;
514 float[] in = (float[]) obj;
516 for (int b=0; b<numBands; b++)
517 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
519 return;
521 case DataBuffer.TYPE_DOUBLE:
523 DataBufferDouble out = (DataBufferDouble) data;
524 double[] in = (double[]) obj;
526 for (int b=0; b<numBands; b++)
527 out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
529 return;
531 default:
532 throw new UnsupportedOperationException("transfer type not " +
533 "implemented");
537 public void setPixel(int x, int y, int[] iArray, DataBuffer data)
539 int offset = pixelStride*x + scanlineStride*y;
540 for (int b=0; b<numBands; b++)
541 data.setElem(bankIndices[b], offset+bandOffsets[b], iArray[b]);
544 public void setSample(int x, int y, int b, int s, DataBuffer data)
546 data.setElem(bankIndices[b], getOffset(x, y, b), s);