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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [awt/] [image/] [MultiPixelPackedSampleModel.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Copyright (C) 2004, 2006,  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
import gnu.java.lang.CPStringBuilder;
41
 
42
/**
43
 * MultiPixelPackedSampleModel provides a single band model that supports
44
 * multiple pixels in a single unit.  Pixels have 2^n bits and 2^k pixels fit
45
 * per data element.
46
 *
47
 * @author Jerry Quinn (jlquinn@optonline.net)
48
 */
49
public class MultiPixelPackedSampleModel extends SampleModel
50
{
51
  private int scanlineStride;
52
  private int[] bitMasks;
53
  private int[] bitOffsets;
54
  private int[] sampleSize;
55
  private int dataBitOffset;
56
  private int elemBits;
57
  private int numberOfBits;
58
  private int numElems;
59
 
60
  /**
61
   * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
62
   * data type, which should be one of:
63
   * <ul>
64
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
65
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
66
   *   <li>{@link DataBuffer#TYPE_INT};</li>
67
   * </ul>
68
   *
69
   * @param dataType  the data type.
70
   * @param w  the width (in pixels).
71
   * @param h  the height (in pixels).
72
   * @param numberOfBits  the number of bits per pixel (must be a power of 2).
73
   */
74
  public MultiPixelPackedSampleModel(int dataType, int w, int h,
75
                                     int numberOfBits)
76
  {
77
    this(dataType, w, h, numberOfBits, 0, 0);
78
  }
79
 
80
  /**
81
   * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
82
   * data type, which should be one of:
83
   * <ul>
84
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
85
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
86
   *   <li>{@link DataBuffer#TYPE_INT};</li>
87
   * </ul>
88
   *
89
   * @param dataType  the data type.
90
   * @param w  the width (in pixels).
91
   * @param h  the height (in pixels).
92
   * @param numberOfBits  the number of bits per pixel (must be a power of 2).
93
   * @param scanlineStride  the number of data elements from a pixel on one
94
   *     row to the corresponding pixel in the next row.
95
   * @param dataBitOffset  the offset to the first data bit.
96
   */
97
  public MultiPixelPackedSampleModel(int dataType, int w, int h,
98
                                     int numberOfBits, int scanlineStride,
99
                                     int dataBitOffset)
100
  {
101
    super(dataType, w, h, 1);
102
 
103
    switch (dataType)
104
      {
105
      case DataBuffer.TYPE_BYTE:
106
        elemBits = 8;
107
        break;
108
      case DataBuffer.TYPE_USHORT:
109
        elemBits = 16;
110
        break;
111
      case DataBuffer.TYPE_INT:
112
        elemBits = 32;
113
        break;
114
      default:
115
        throw new IllegalArgumentException("MultiPixelPackedSampleModel"
116
                                           + " unsupported dataType");
117
      }
118
 
119
    this.dataBitOffset = dataBitOffset;
120
 
121
    this.numberOfBits = numberOfBits;
122
    if (numberOfBits > elemBits)
123
      throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
124
                                      + " larger than dataType");
125
    switch (numberOfBits)
126
      {
127
      case 1: case 2: case 4: case 8: case 16: case 32: break;
128
      default:
129
        throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
130
                                        + " size not 2^n bits");
131
      }
132
    numElems = elemBits / numberOfBits;
133
 
134
    // Compute scan line large enough for w pixels.
135
    if (scanlineStride == 0)
136
      scanlineStride = ((dataBitOffset + w * numberOfBits) - 1) / elemBits + 1;
137
    this.scanlineStride = scanlineStride;
138
 
139
 
140
    sampleSize = new int[1];
141
    sampleSize[0] = numberOfBits;
142
 
143
    bitMasks = new int[numElems];
144
    bitOffsets = new int[numElems];
145
    for (int i=0; i < numElems; i++)
146
      {
147
        bitOffsets[numElems - i- 1] = numberOfBits * i;
148
        bitMasks[numElems - i - 1] = ((1 << numberOfBits) - 1) <<
149
            bitOffsets[numElems - i - 1];
150
      }
151
  }
152
 
153
  /**
154
   * Creates a new <code>MultiPixelPackedSample</code> model with the same
155
   * data type and bits per pixel as this model, but with the specified
156
   * dimensions.
157
   *
158
   * @param w  the width (in pixels).
159
   * @param h  the height (in pixels).
160
   *
161
   * @return The new sample model.
162
   */
163
  public SampleModel createCompatibleSampleModel(int w, int h)
164
  {
165
    /* FIXME: We can avoid recalculation of bit offsets and sample
166
       sizes here by passing these from the current instance to a
167
       special private constructor. */
168
    return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
169
  }
170
 
171
  /**
172
   * Creates a DataBuffer for holding pixel data in the format and
173
   * layout described by this SampleModel. The returned buffer will
174
   * consist of one single bank.
175
   *
176
   * @return A new data buffer.
177
   */
178
  public DataBuffer createDataBuffer()
179
  {
180
    int size = scanlineStride * height;
181
    if (dataBitOffset > 0)
182
      size += (dataBitOffset - 1) / elemBits + 1;
183
    return Buffers.createBuffer(getDataType(), size);
184
  }
185
 
186
  /**
187
   * Returns the number of data elements required to transfer a pixel in the
188
   * get/setDataElements() methods.
189
   *
190
   * @return <code>1</code>.
191
   */
192
  public int getNumDataElements()
193
  {
194
    return 1;
195
  }
196
 
197
  /**
198
   * Returns an array containing the size (in bits) of the samples in each
199
   * band.  The <code>MultiPixelPackedSampleModel</code> class supports only
200
   * one band, so this method returns an array with length <code>1</code>.
201
   *
202
   * @return An array containing the size (in bits) of the samples in band zero.
203
   *
204
   * @see #getSampleSize(int)
205
   */
206
  public int[] getSampleSize()
207
  {
208
    return (int[]) sampleSize.clone();
209
  }
210
 
211
  /**
212
   * Returns the size of the samples in the specified band.  Note that the
213
   * <code>MultiPixelPackedSampleModel</code> supports only one band -- this
214
   * method ignored the <code>band</code> argument, and always returns the size
215
   * of band zero.
216
   *
217
   * @param band  the band (this parameter is ignored).
218
   *
219
   * @return The size of the samples in band zero.
220
   *
221
   * @see #getSampleSize()
222
   */
223
  public int getSampleSize(int band)
224
  {
225
    return sampleSize[0];
226
  }
227
 
228
  /**
229
   * Returns the index in the data buffer that stores the pixel at (x, y).
230
   *
231
   * @param x  the x-coordinate.
232
   * @param y  the y-coordinate.
233
   *
234
   * @return The index in the data buffer that stores the pixel at (x, y).
235
   *
236
   * @see #getBitOffset(int)
237
   */
238
  public int getOffset(int x, int y)
239
  {
240
    return scanlineStride * y + ((dataBitOffset + x * numberOfBits) / elemBits);
241
  }
242
 
243
  /**
244
   * The bit offset (within an element in the data buffer) of the pixels with
245
   * the specified x-coordinate.
246
   *
247
   * @param x  the x-coordinate.
248
   *
249
   * @return The bit offset.
250
   */
251
  public int getBitOffset(int x)
252
  {
253
    return (dataBitOffset + x * numberOfBits) % elemBits;
254
  }
255
 
256
  /**
257
   * Returns the offset to the first data bit.
258
   *
259
   * @return The offset to the first data bit.
260
   */
261
  public int getDataBitOffset()
262
  {
263
    return dataBitOffset;
264
  }
265
 
266
  /**
267
   * Returns the number of data elements from a pixel in one row to the
268
   * corresponding pixel in the next row.
269
   *
270
   * @return The scanline stride.
271
   */
272
  public int getScanlineStride()
273
  {
274
    return scanlineStride;
275
  }
276
 
277
  /**
278
   * Returns the number of bits per pixel.
279
   *
280
   * @return The number of bits per pixel.
281
   */
282
  public int getPixelBitStride()
283
  {
284
    return numberOfBits;
285
  }
286
 
287
  /**
288
   * Returns the transfer type, which is one of the following (depending on
289
   * the number of bits per sample for this model):
290
   * <ul>
291
   *   <li>{@link DataBuffer#TYPE_BYTE};</li>
292
   *   <li>{@link DataBuffer#TYPE_USHORT};</li>
293
   *   <li>{@link DataBuffer#TYPE_INT};</li>
294
   * </ul>
295
   *
296
   * @return The transfer type.
297
   */
298
  public int getTransferType()
299
  {
300
    if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_BYTE))
301
      return DataBuffer.TYPE_BYTE;
302
    else if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_USHORT))
303
      return DataBuffer.TYPE_USHORT;
304
    return DataBuffer.TYPE_INT;
305
  }
306
 
307
  /**
308
   * Normally this method returns a sample model for accessing a subset of
309
   * bands of image data, but since <code>MultiPixelPackedSampleModel</code>
310
   * only supports a single band, this overridden implementation just returns
311
   * a new instance of <code>MultiPixelPackedSampleModel</code>, with the same
312
   * attributes as this instance.
313
   *
314
   * @param bands  the bands to include in the subset (this is ignored, except
315
   *     that if it is non-<code>null</code> a check is made to ensure that the
316
   *     array length is equal to <code>1</code>).
317
   *
318
   * @throws RasterFormatException if <code>bands</code> is not
319
   *     <code>null</code> and <code>bands.length != 1</code>.
320
   */
321
  public SampleModel createSubsetSampleModel(int[] bands)
322
  {
323
    if (bands != null && bands.length != 1)
324
      throw new RasterFormatException("MultiPixelPackedSampleModel only"
325
          + " supports one band");
326
    return new MultiPixelPackedSampleModel(dataType, width, height,
327
        numberOfBits, scanlineStride, dataBitOffset);
328
  }
329
 
330
  /**
331
   * Extract one pixel and return in an array of transfer type.
332
   *
333
   * Extracts the pixel at x, y from data and stores into the 0th index of the
334
   * array obj, since there is only one band.  If obj is null, a new array of
335
   * getTransferType() is created.
336
   *
337
   * @param x The x-coordinate of the pixel rectangle to store in
338
   *     <code>obj</code>.
339
   * @param y The y-coordinate of the pixel rectangle to store in
340
   *     <code>obj</code>.
341
   * @param obj The primitive array to store the pixels into or null to force
342
   *     creation.
343
   * @param data The DataBuffer that is the source of the pixel data.
344
   * @return The primitive array containing the pixel data.
345
   * @see java.awt.image.SampleModel#getDataElements(int, int, Object,
346
   *     DataBuffer)
347
   */
348
  public Object getDataElements(int x, int y, Object obj, DataBuffer data)
349
  {
350
    int pixel = getSample(x, y, 0, data);
351
    switch (getTransferType())
352
      {
353
        case DataBuffer.TYPE_BYTE:
354
          if (obj == null)
355
            obj = new byte[1];
356
          ((byte[]) obj)[0] = (byte) pixel;
357
          return obj;
358
        case DataBuffer.TYPE_USHORT:
359
          if (obj == null)
360
            obj = new short[1];
361
          ((short[]) obj)[0] = (short) pixel;
362
          return obj;
363
        case DataBuffer.TYPE_INT:
364
          if (obj == null)
365
            obj = new int[1];
366
          ((int[]) obj)[0] = pixel;
367
          return obj;
368
        default:
369
          // Seems like the only sensible thing to do.
370
          throw new ClassCastException();
371
      }
372
  }
373
 
374
  /**
375
   * Returns an array (of length 1) containing the sample for the pixel at
376
   * (x, y) in the specified data buffer.  If <code>iArray</code> is not
377
   * <code>null</code>, it will be populated with the sample value and
378
   * returned as the result of this function (this avoids allocating a new
379
   * array instance).
380
   *
381
   * @param x  the x-coordinate of the pixel.
382
   * @param y  the y-coordinate of the pixel.
383
   * @param iArray  an array to populate with the sample values and return as
384
   *     the result (if <code>null</code>, a new array will be allocated).
385
   * @param data  the data buffer (<code>null</code> not permitted).
386
   *
387
   * @return An array containing the pixel sample value.
388
   *
389
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
390
   */
391
  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
392
  {
393
    if (iArray == null)
394
      iArray = new int[1];
395
    iArray[0] = getSample(x, y, 0, data);
396
    return iArray;
397
  }
398
 
399
  /**
400
   * Returns the sample value for the pixel at (x, y) in the specified data
401
   * buffer.
402
   *
403
   * @param x  the x-coordinate of the pixel.
404
   * @param y  the y-coordinate of the pixel.
405
   * @param b  the band (in the range <code>0</code> to
406
   *     <code>getNumBands() - 1</code>).
407
   * @param data  the data buffer (<code>null</code> not permitted).
408
   *
409
   * @return The sample value.
410
   *
411
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
412
   */
413
  public int getSample(int x, int y, int b, DataBuffer data)
414
  {
415
    int pos =
416
      ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
417
    int offset = getOffset(x, y);
418
    int samples = data.getElem(offset);
419
    return (samples & bitMasks[pos]) >>> bitOffsets[pos];
420
  }
421
 
422
  /**
423
   * Set the pixel at x, y to the value in the first element of the primitive
424
   * array obj.
425
   *
426
   * @param x The x-coordinate of the data elements in <code>obj</code>.
427
   * @param y The y-coordinate of the data elements in <code>obj</code>.
428
   * @param obj The primitive array containing the data elements to set.
429
   * @param data The DataBuffer to store the data elements into.
430
   */
431
  public void setDataElements(int x, int y, Object obj, DataBuffer data)
432
  {
433
    int transferType = getTransferType();
434
    try
435
      {
436
        switch (transferType)
437
          {
438
            case DataBuffer.TYPE_BYTE:
439
              {
440
                byte[] in = (byte[]) obj;
441
                setSample(x, y, 0, in[0] & 0xFF, data);
442
                return;
443
              }
444
            case DataBuffer.TYPE_USHORT:
445
              {
446
                short[] in = (short[]) obj;
447
                setSample(x, y, 0, in[0] & 0xFFFF, data);
448
                return;
449
              }
450
            case DataBuffer.TYPE_INT:
451
              {
452
                int[] in = (int[]) obj;
453
                setSample(x, y, 0, in[0], data);
454
                return;
455
              }
456
            default:
457
              throw new ClassCastException("Unsupported data type");
458
          }
459
      }
460
    catch (ArrayIndexOutOfBoundsException aioobe)
461
      {
462
        String msg = "While writing data elements" +
463
          ", x=" + x + ", y=" + y +
464
          ", width=" + width + ", height=" + height +
465
          ", scanlineStride=" + scanlineStride +
466
          ", offset=" + getOffset(x, y) +
467
          ", data.getSize()=" + data.getSize() +
468
          ", data.getOffset()=" + data.getOffset() +
469
          ": " + aioobe;
470
        throw new ArrayIndexOutOfBoundsException(msg);
471
      }
472
  }
473
 
474
  /**
475
   * Sets the sample value for the pixel at (x, y) in the specified data
476
   * buffer to the specified value.
477
   *
478
   * @param x  the x-coordinate of the pixel.
479
   * @param y  the y-coordinate of the pixel.
480
   * @param iArray  the sample value (<code>null</code> not permitted).
481
   * @param data  the data buffer (<code>null</code> not permitted).
482
   *
483
   * @throws NullPointerException if either <code>iArray</code> or
484
   *     <code>data</code> is <code>null</code>.
485
   *
486
   * @see #setSample(int, int, int, int, DataBuffer)
487
   */
488
  public void setPixel(int x, int y, int[] iArray, DataBuffer data)
489
  {
490
    setSample(x, y, 0, iArray[0], data);
491
  }
492
 
493
  /**
494
   * Sets the sample value for a band for the pixel at (x, y) in the
495
   * specified data buffer.
496
   *
497
   * @param x  the x-coordinate of the pixel.
498
   * @param y  the y-coordinate of the pixel.
499
   * @param b  the band (in the range <code>0</code> to
500
   *     <code>getNumBands() - 1</code>).
501
   * @param s  the sample value.
502
   * @param data  the data buffer (<code>null</code> not permitted).
503
   *
504
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
505
   */
506
  public void setSample(int x, int y, int b, int s, DataBuffer data)
507
  {
508
    int bitpos =
509
      ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
510
    int offset = getOffset(x, y);
511
 
512
    s = s << bitOffsets[bitpos];
513
    s = s & bitMasks[bitpos];
514
 
515
    int sample = data.getElem(offset);
516
    sample |= s;
517
    data.setElem(offset, sample);
518
  }
519
 
520
  /**
521
   * Tests this sample model for equality with an arbitrary object.  This
522
   * method returns <code>true</code> if and only if:
523
   * <ul>
524
   *   <li><code>obj</code> is not <code>null</code>;
525
   *   <li><code>obj</code> is an instance of
526
   *       <code>MultiPixelPackedSampleModel</code>;
527
   *   <li>both models have the same:
528
   *     <ul>
529
   *       <li><code>dataType</code>;
530
   *       <li><code>width</code>;
531
   *       <li><code>height</code>;
532
   *       <li><code>numberOfBits</code>;
533
   *       <li><code>scanlineStride</code>;
534
   *       <li><code>dataBitOffsets</code>.
535
   *     </ul>
536
   *   </li>
537
   * </ul>
538
   *
539
   * @param obj  the object (<code>null</code> permitted)
540
   *
541
   * @return <code>true</code> if this model is equal to <code>obj</code>, and
542
   *     <code>false</code> otherwise.
543
   */
544
  public boolean equals(Object obj)
545
  {
546
    if (this == obj)
547
      return true;
548
    if (! (obj instanceof MultiPixelPackedSampleModel))
549
      return false;
550
    MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel) obj;
551
    if (this.dataType != that.dataType)
552
      return false;
553
    if (this.width != that.width)
554
      return false;
555
    if (this.height != that.height)
556
      return false;
557
    if (this.numberOfBits != that.numberOfBits)
558
      return false;
559
    if (this.scanlineStride != that.scanlineStride)
560
      return false;
561
    if (this.dataBitOffset != that.dataBitOffset)
562
      return false;
563
    return true;
564
  }
565
 
566
  /**
567
   * Returns a hash code for this <code>MultiPixelPackedSampleModel</code>.
568
   *
569
   * @return A hash code.
570
   */
571
  public int hashCode()
572
  {
573
    // this hash code won't match Sun's, but that shouldn't matter...
574
    int result = 193;
575
    result = 37 * result + dataType;
576
    result = 37 * result + width;
577
    result = 37 * result + height;
578
    result = 37 * result + numberOfBits;
579
    result = 37 * result + scanlineStride;
580
    result = 37 * result + dataBitOffset;
581
    return result;
582
  }
583
 
584
  /**
585
   * Creates a String with some information about this SampleModel.
586
   * @return A String describing this SampleModel.
587
   * @see java.lang.Object#toString()
588
   */
589
  public String toString()
590
  {
591
    CPStringBuilder result = new CPStringBuilder();
592
    result.append(getClass().getName());
593
    result.append("[");
594
    result.append("scanlineStride=").append(scanlineStride);
595
    for(int i=0; i < bitMasks.length; i+=1)
596
    {
597
      result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
598
    }
599
 
600
    result.append("]");
601
    return result.toString();
602
  }
603
}

powered by: WebSVN 2.1.0

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