OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [awt/] [image/] [ComponentSampleModel.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Copyright (C) 2000, 2002  Free Software Foundation
2
 
3
This file is part of GNU Classpath.
4
 
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.
9
 
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.
14
 
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.
19
 
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.
24
 
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. */
36
 
37
package java.awt.image;
38
 
39
import gnu.java.awt.Buffers;
40
 
41
/* FIXME: This class does not yet support data type TYPE_SHORT */
42
 
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.
47
 *
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.
52
 *
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.
58
 *
59
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
60
 */
61
public class ComponentSampleModel extends SampleModel
62
{
63
  protected int[] bandOffsets;
64
  protected int[] bankIndices;
65
 
66
  /**
67
   * Number of bands in the image described.
68
   * @specnote This field shadows the protected numBands in SampleModel.
69
   */
70
  protected int numBands;
71
 
72
  /** Used when creating data buffers. */
73
  protected int numBanks;
74
 
75
  protected int scanlineStride;
76
 
77
  protected int pixelStride;
78
 
79
  private boolean tightPixelPacking = false;
80
 
81
  public ComponentSampleModel(int dataType,
82
                              int w, int h,
83
                              int pixelStride,
84
                              int scanlineStride,
85
                              int[] bandOffsets)
86
  {
87
    this(dataType, w, h, pixelStride, scanlineStride,
88
         new int[bandOffsets.length], bandOffsets);
89
  }
90
 
91
  public ComponentSampleModel(int dataType,
92
                              int w, int h,
93
                              int pixelStride,
94
                              int scanlineStride,
95
                              int[] bankIndices,
96
                              int[] bandOffsets)
97
  {
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();
103
 
104
    this.bandOffsets = bandOffsets;
105
    this.bankIndices = bankIndices;
106
    this.numBands = bandOffsets.length;
107
 
108
    this.numBanks = 0;
109
    for (int b=0; b<bankIndices.length; b++)
110
      this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
111
 
112
    this.scanlineStride = scanlineStride;
113
    this.pixelStride = pixelStride;
114
 
115
    // See if we can use some speedups
116
 
117
    /* FIXME: May these checks should be reserved for the
118
       PixelInterleavedSampleModel? */
119
 
120
    if (pixelStride == numBands)
121
      {
122
        tightPixelPacking = true;
123
        for (int b=0; b<numBands; b++) {
124
          if ((bandOffsets[b] != b) || (bankIndices[b] !=0))
125
            {
126
              tightPixelPacking = false;
127
              break;
128
            }
129
        }
130
      }
131
  }
132
 
133
  public SampleModel createCompatibleSampleModel(int w, int h)
134
  {
135
    return new ComponentSampleModel(dataType, w, h, pixelStride,
136
                                    scanlineStride, bankIndices,
137
                                    bandOffsets);
138
  }
139
 
140
  public SampleModel createSubsetSampleModel(int[] bands)
141
  {
142
    int numBands = bands.length;
143
 
144
    int[] bankIndices = new int[numBands];
145
    int[] bandOffsets = new int[numBands];
146
    for (int b=0; b<numBands; b++)
147
      {
148
        bankIndices[b] = this.bankIndices[bands[b]];
149
        bandOffsets[b] = this.bandOffsets[bands[b]];
150
      }
151
 
152
    return new ComponentSampleModel(dataType, width, height, pixelStride,
153
                                    scanlineStride, bankIndices,
154
                                    bandOffsets);
155
  }
156
 
157
  public DataBuffer createDataBuffer()
158
  {
159
    // Maybe this value should be precalculated in the constructor?
160
    int highestOffset = 0;
161
    for (int b=0; b<numBands; b++)
162
      {
163
        highestOffset = Math.max(highestOffset, bandOffsets[b]);
164
      }
165
    int size = pixelStride*(width-1) + scanlineStride*(height-1) +
166
      highestOffset + 1;
167
 
168
    return Buffers.createBuffer(getDataType(), size, numBanks);
169
  }
170
 
171
  public int getOffset(int x, int y)
172
  {
173
    return getOffset(x, y, 0);
174
  }
175
 
176
  public int getOffset(int x, int y, int b)
177
  {
178
    return bandOffsets[b] + pixelStride*x + scanlineStride*y;
179
  }
180
 
181
  public final int[] getSampleSize()
182
  {
183
    int size = DataBuffer.getDataTypeSize(getDataType());
184
    int[] sizes = new int[numBands];
185
 
186
    java.util.Arrays.fill(sizes, size);
187
    return sizes;
188
  }
189
 
190
  public final int getSampleSize(int band)
191
  {
192
    return DataBuffer.getDataTypeSize(getDataType());
193
  }
194
 
195
  public final int[] getBankIndices()
196
  {
197
    return bankIndices;
198
  }
199
 
200
  public final int[] getBandOffsets()
201
  {
202
    return bandOffsets;
203
  }
204
 
205
  public final int getScanlineStride()
206
  {
207
    return scanlineStride;
208
  }
209
 
210
  public final int getPixelStride()
211
  {
212
    return pixelStride;
213
  }
214
 
215
  public final int getNumDataElements()
216
  {
217
    return numBands;
218
  }
219
 
220
  public Object getDataElements(int x, int y, Object obj, DataBuffer data)
221
  {
222
    int xyOffset = pixelStride*x + scanlineStride*y;
223
 
224
    int[] totalBandDataOffsets = new int[numBands];
225
 
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. */
229
 
230
    /* FIXME: For single pixels, it is probably easier to simple
231
       call getElem instead of calculating the bank offset ourself.
232
 
233
       On the other hand, then we need to push the value through
234
       the int type returned by the getElem method.  */
235
 
236
    int[] bankOffsets = data.getOffsets();
237
 
238
    for (int b=0; b<numBands; b++)
239
      {
240
        totalBandDataOffsets[b] =
241
          bandOffsets[b]+bankOffsets[bankIndices[b]] + xyOffset;
242
      }
243
 
244
    try
245
      {
246
        switch (getTransferType())
247
          {
248
          case DataBuffer.TYPE_BYTE:
249
            DataBufferByte inByte = (DataBufferByte) data;
250
            byte[] outByte = (byte[]) obj;
251
            if (outByte == null) outByte = new byte[numBands];
252
 
253
            for (int b=0; b<numBands; b++)
254
              {
255
                int dOffset = totalBandDataOffsets[b];
256
                outByte[b] = inByte.getData(bankIndices[b])[dOffset];
257
              }
258
            return outByte;
259
 
260
          case DataBuffer.TYPE_USHORT:
261
            DataBufferUShort inUShort = (DataBufferUShort) data;
262
            short[] outUShort = (short[]) obj;
263
            if (outUShort == null) outUShort = new short[numBands];
264
 
265
            for (int b=0; b<numBands; b++)
266
              {
267
                int dOffset = totalBandDataOffsets[b];
268
                outUShort[b] = inUShort.getData(bankIndices[b])[dOffset];
269
              }
270
            return outUShort;
271
 
272
          case DataBuffer.TYPE_SHORT:
273
            DataBufferShort inShort = (DataBufferShort) data;
274
            short[] outShort = (short[]) obj;
275
            if (outShort == null) outShort = new short[numBands];
276
 
277
            for (int b=0; b<numBands; b++)
278
              {
279
                int dOffset = totalBandDataOffsets[b];
280
                outShort[b] = inShort.getData(bankIndices[b])[dOffset];
281
              }
282
            return outShort;
283
 
284
          case DataBuffer.TYPE_INT:
285
            DataBufferInt inInt = (DataBufferInt) data;
286
            int[] outInt = (int[]) obj;
287
            if (outInt == null) outInt = new int[numBands];
288
 
289
            for (int b=0; b<numBands; b++)
290
              {
291
                int dOffset = totalBandDataOffsets[b];
292
                outInt[b] = inInt.getData(bankIndices[b])[dOffset];
293
              }
294
            return outInt;
295
 
296
          case DataBuffer.TYPE_FLOAT:
297
            DataBufferFloat inFloat = (DataBufferFloat) data;
298
            float[] outFloat = (float[]) obj;
299
            if (outFloat == null) outFloat = new float[numBands];
300
 
301
            for (int b=0; b<numBands; b++)
302
              {
303
                int dOffset = totalBandDataOffsets[b];
304
                outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
305
              }
306
            return outFloat;
307
 
308
          case DataBuffer.TYPE_DOUBLE:
309
            DataBufferDouble inDouble = (DataBufferDouble) data;
310
            double[] outDouble = (double[]) obj;
311
            if (outDouble == null) outDouble = new double[numBands];
312
 
313
            for (int b=0; b<numBands; b++)
314
              {
315
                int dOffset = totalBandDataOffsets[b];
316
                outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
317
              }
318
            return outDouble;
319
 
320
          default:
321
              throw new IllegalStateException("unknown transfer type " +
322
                                              getTransferType());
323
          }
324
      }
325
    catch (ArrayIndexOutOfBoundsException aioobe)
326
      {
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);
331
      }
332
  }
333
 
334
  public Object getDataElements(int x, int y, int w, int h, Object obj,
335
                                DataBuffer data)
336
  {
337
    if (!tightPixelPacking)
338
      {
339
        return super.getDataElements(x, y, w, h, obj, data);
340
      }
341
 
342
    // using get speedup
343
 
344
    // We can copy whole rows
345
    int rowSize = w*numBands;
346
    int dataSize = rowSize*h;
347
 
348
    DataBuffer transferBuffer =
349
      Buffers.createBuffer(getTransferType(), obj, dataSize);
350
    obj = Buffers.getData(transferBuffer);
351
 
352
    int inOffset =
353
      pixelStride*x +
354
      scanlineStride*y +
355
      data.getOffset(); // Assumes only one band is used
356
 
357
    /* We don't add band offsets since we assume that bands have
358
       offsets 0, 1, 2, ... */
359
 
360
    // See if we can copy everything in one go
361
    if (scanlineStride == rowSize)
362
      {
363
        // Collapse scan lines:
364
        rowSize *= h;
365
        // We ignore scanlineStride since it won't be of any use
366
        h = 1;
367
      }
368
 
369
    int outOffset = 0;
370
    Object inArray = Buffers.getData(data);
371
    for (int yd = 0; yd<h; yd++)
372
      {
373
        System.arraycopy(inArray, inOffset, obj, outOffset, rowSize);
374
        inOffset  += scanlineStride;
375
        outOffset += rowSize;
376
      }
377
    return obj;
378
  }
379
 
380
  public void setDataElements(int x, int y, int w, int h,
381
                              Object obj, DataBuffer data)
382
  {
383
    if (!tightPixelPacking)
384
      {
385
        super.setDataElements(x, y, w, h, obj, data);
386
        return;
387
      }
388
 
389
    // using set speedup, we can copy whole rows
390
    int rowSize = w*numBands;
391
    int dataSize = rowSize*h;
392
 
393
    DataBuffer transferBuffer =
394
      Buffers.createBufferFromData(getTransferType(), obj, dataSize);
395
 
396
    int[] bankOffsets = data.getOffsets();
397
 
398
    int outOffset =
399
      pixelStride*x +
400
      scanlineStride*y +
401
      bankOffsets[0]; // same assuptions as in get...
402
 
403
    // See if we can copy everything in one go
404
    if (scanlineStride == rowSize)
405
      {
406
        // Collapse scan lines:
407
        rowSize *= h;
408
        h = 1;
409
      }
410
 
411
    int inOffset = 0;
412
    Object outArray = Buffers.getData(data);
413
    for (int yd = 0; yd<h; yd++)
414
      {
415
        System.arraycopy(obj, inOffset, outArray, outOffset, rowSize);
416
        outOffset += scanlineStride;
417
        inOffset  += rowSize;
418
      }
419
  }
420
 
421
  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
422
  {
423
    int offset = pixelStride*x + scanlineStride*y;
424
    if (iArray == null) iArray = new int[numBands];
425
    for (int b=0; b<numBands; b++)
426
      {
427
        iArray[b] = data.getElem(bankIndices[b], offset+bandOffsets[b]);
428
      }
429
    return iArray;
430
  }
431
 
432
  public int[] getPixels(int x, int y, int w, int h, int[] iArray,
433
                         DataBuffer data)
434
  {
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++)
439
      {
440
        int lineOffset = offset;
441
        for (x=0; x<w; x++)
442
          {
443
            for (int b=0; b<numBands; b++)
444
              {
445
                iArray[outOffset++] =
446
                  data.getElem(bankIndices[b], lineOffset+bandOffsets[b]);
447
              }
448
            lineOffset += pixelStride;
449
          }
450
        offset += scanlineStride;
451
      }
452
    return iArray;
453
  }
454
 
455
  public int getSample(int x, int y, int b, DataBuffer data)
456
  {
457
    return data.getElem(bankIndices[b], getOffset(x, y, b));
458
  }
459
 
460
  public void setDataElements(int x, int y, Object obj, DataBuffer data)
461
  {
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;
468
 
469
    switch (getTransferType())
470
      {
471
      case DataBuffer.TYPE_BYTE:
472
        {
473
          DataBufferByte out = (DataBufferByte) data;
474
          byte[] in = (byte[]) obj;
475
 
476
          for (int b=0; b<numBands; b++)
477
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
478
 
479
          return;
480
        }
481
      case DataBuffer.TYPE_USHORT:
482
        {
483
          DataBufferUShort out = (DataBufferUShort) data;
484
          short[] in = (short[]) obj;
485
 
486
          for (int b=0; b<numBands; b++)
487
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
488
 
489
          return;
490
        }
491
      case DataBuffer.TYPE_SHORT:
492
        {
493
          DataBufferShort out = (DataBufferShort) data;
494
          short[] in = (short[]) obj;
495
 
496
          for (int b=0; b<numBands; b++)
497
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
498
 
499
          return;
500
        }
501
      case DataBuffer.TYPE_INT:
502
        {
503
          DataBufferInt out = (DataBufferInt) data;
504
          int[] in = (int[]) obj;
505
 
506
          for (int b=0; b<numBands; b++)
507
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
508
 
509
          return;
510
        }
511
      case DataBuffer.TYPE_FLOAT:
512
        {
513
          DataBufferFloat out = (DataBufferFloat) data;
514
          float[] in = (float[]) obj;
515
 
516
          for (int b=0; b<numBands; b++)
517
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
518
 
519
          return;
520
        }
521
      case DataBuffer.TYPE_DOUBLE:
522
        {
523
          DataBufferDouble out = (DataBufferDouble) data;
524
          double[] in = (double[]) obj;
525
 
526
          for (int b=0; b<numBands; b++)
527
            out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
528
 
529
          return;
530
        }
531
      default:
532
        throw new UnsupportedOperationException("transfer type not " +
533
                                                "implemented");
534
      }
535
  }
536
 
537
  public void setPixel(int x, int y, int[] iArray, DataBuffer data)
538
  {
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]);
542
  }
543
 
544
  public void setSample(int x, int y, int b, int s, DataBuffer data)
545
  {
546
    data.setElem(bankIndices[b], getOffset(x, y, b), s);
547
  }
548
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.