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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Copyright (C) 2000, 2002, 2003, 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 java.util.Arrays;
40
 
41
import gnu.java.awt.BitMaskExtent;
42
import gnu.java.lang.CPStringBuilder;
43
 
44
/**
45
 * A <code>SampleModel</code> used when all samples are stored in a single
46
 * data element in the {@link DataBuffer}, and each data element contains
47
 * samples for one pixel only.
48
 *
49
 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
50
 */
51
public class SinglePixelPackedSampleModel extends SampleModel
52
{
53
  private int scanlineStride;
54
  private int[] bitMasks;
55
  private int[] bitOffsets;
56
  private int[] sampleSize;
57
 
58
  /**
59
   * Creates a new <code>SinglePixelPackedSampleModel</code>.
60
   *
61
   * @param dataType  the data buffer type.
62
   * @param w  the width (in pixels).
63
   * @param h  the height (in pixels).
64
   * @param bitMasks  an array containing the bit mask used to extract the
65
   *     sample value for each band.
66
   */
67
  public SinglePixelPackedSampleModel(int dataType, int w, int h,
68
                                      int[] bitMasks)
69
  {
70
    this(dataType, w, h, w, bitMasks);
71
  }
72
 
73
  /**
74
   * Creates a new <code>SinglePixelPackedSampleModel</code>.
75
   *
76
   * @param dataType  the data buffer type.
77
   * @param w  the width (in pixels).
78
   * @param h  the height (in pixels).
79
   * @param scanlineStride  the number of data elements between a pixel on one
80
   *     row and the corresponding pixel on the next row.
81
   * @param bitMasks  an array containing the bit mask used to extract the
82
   *     sample value for each band.
83
   */
84
  public SinglePixelPackedSampleModel(int dataType, int w, int h,
85
                                      int scanlineStride, int[] bitMasks)
86
  {
87
    super(dataType, w, h, bitMasks.length);
88
 
89
    switch (dataType)
90
      {
91
      case DataBuffer.TYPE_BYTE:
92
      case DataBuffer.TYPE_USHORT:
93
      case DataBuffer.TYPE_INT:
94
        break;
95
      default:
96
        throw new IllegalArgumentException(
97
            "SinglePixelPackedSampleModel unsupported dataType");
98
      }
99
 
100
    this.scanlineStride = scanlineStride;
101
    this.bitMasks = bitMasks;
102
 
103
    bitOffsets = new int[numBands];
104
    sampleSize = new int[numBands];
105
 
106
    BitMaskExtent extent = new BitMaskExtent();
107
    for (int b = 0; b < numBands; b++)
108
      {
109
        // the mask is an unsigned integer
110
        long mask = bitMasks[b] & 0xFFFFFFFFL;
111
        extent.setMask(mask);
112
        sampleSize[b] = extent.bitWidth;
113
        bitOffsets[b] = extent.leastSignificantBit;
114
      }
115
  }
116
 
117
  /**
118
   * Returns the number of data elements.
119
   *
120
   * @return <code>1</code>.
121
   */
122
  public int getNumDataElements()
123
  {
124
    return 1;
125
  }
126
 
127
  /**
128
   * Creates a new <code>SampleModel</code> that is compatible with this
129
   * model and has the specified width and height.
130
   *
131
   * @param w  the width (in pixels).
132
   * @param h  the height (in pixels).
133
   *
134
   * @return The new sample model.
135
   */
136
  public SampleModel createCompatibleSampleModel(int w, int h)
137
  {
138
    /* FIXME: We can avoid recalculation of bit offsets and sample
139
       sizes here by passing these from the current instance to a
140
       special private constructor. */
141
    return new SinglePixelPackedSampleModel(dataType, w, h, bitMasks);
142
  }
143
 
144
 
145
  /**
146
   * Creates a DataBuffer for holding pixel data in the format and
147
   * layout described by this SampleModel. The returned buffer will
148
   * consist of one single bank.
149
   *
150
   * @return The data buffer.
151
   */
152
  public DataBuffer createDataBuffer()
153
  {
154
    // We can save (scanlineStride - width) pixels at the very end of
155
    // the buffer. The Sun reference implementation (J2SE 1.3.1 and
156
    // 1.4.1_01) seems to do this; tested with Mauve test code.
157
    int size = scanlineStride * (height - 1) + width;
158
 
159
    DataBuffer buffer = null;
160
    switch (getTransferType())
161
      {
162
      case DataBuffer.TYPE_BYTE:
163
        buffer = new DataBufferByte(size);
164
        break;
165
      case DataBuffer.TYPE_USHORT:
166
        buffer = new DataBufferUShort(size);
167
        break;
168
      case DataBuffer.TYPE_INT:
169
        buffer = new DataBufferInt(size);
170
        break;
171
      }
172
    return buffer;
173
  }
174
 
175
  /**
176
   * Returns an array containing the size (in bits) for each band accessed by
177
   * the <code>SampleModel</code>.
178
   *
179
   * @return An array.
180
   *
181
   * @see #getSampleSize(int)
182
   */
183
  public int[] getSampleSize()
184
  {
185
    return (int[]) sampleSize.clone();
186
  }
187
 
188
  /**
189
   * Returns the size (in bits) of the samples for the specified band.
190
   *
191
   * @param band  the band (in the range <code>0</code> to
192
   *     <code>getNumBands() - 1</code>).
193
   *
194
   * @return The sample size (in bits).
195
   */
196
  public int getSampleSize(int band)
197
  {
198
    return sampleSize[band];
199
  }
200
 
201
  /**
202
   * Returns the index in the data buffer that stores the pixel at (x, y).
203
   *
204
   * @param x  the x-coordinate.
205
   * @param y  the y-coordinate.
206
   *
207
   * @return The index in the data buffer that stores the pixel at (x, y).
208
   */
209
  public int getOffset(int x, int y)
210
  {
211
    return scanlineStride*y + x;
212
  }
213
 
214
  public int[] getBitOffsets()
215
  {
216
    return bitOffsets;
217
  }
218
 
219
  public int[] getBitMasks()
220
  {
221
    return bitMasks;
222
  }
223
 
224
  /**
225
   * Returns the number of data elements from a pixel in one row to the
226
   * corresponding pixel in the next row.
227
   *
228
   * @return The scanline stride.
229
   */
230
  public int getScanlineStride()
231
  {
232
    return scanlineStride;
233
  }
234
 
235
  /**
236
   * Creates a new <code>SinglePixelPackedSampleModel</code> that accesses
237
   * the specified subset of bands.
238
   *
239
   * @param bands  an array containing band indices (<code>null</code> not
240
   *     permitted).
241
   *
242
   * @return A new sample model.
243
   *
244
   * @throws NullPointerException if <code>bands</code> is <code>null</code>.
245
   * @throws RasterFormatException if <code>bands.length</code> is greater
246
   *     than the number of bands in this model.
247
   */
248
  public SampleModel createSubsetSampleModel(int[] bands)
249
  {
250
    if (bands.length > numBands)
251
      throw new RasterFormatException("Too many bands.");
252
 
253
    int numBands = bands.length;
254
 
255
    int[] bitMasks = new int[numBands];
256
 
257
    for (int b = 0; b < numBands; b++)
258
      bitMasks[b] = this.bitMasks[bands[b]];
259
 
260
    return new SinglePixelPackedSampleModel(dataType, width, height,
261
                                            scanlineStride, bitMasks);
262
  }
263
 
264
  public Object getDataElements(int x, int y, Object obj,
265
                                DataBuffer data)
266
  {
267
    int type = getTransferType();
268
    Object ret = null;
269
    switch (type)
270
      {
271
      case DataBuffer.TYPE_BYTE:
272
        {
273
          byte[] in = (byte[]) obj;
274
          if (in == null)
275
            in = new byte[1];
276
          in[0] = (byte) data.getElem(x + y * scanlineStride);
277
          ret = in;
278
        }
279
        break;
280
      case DataBuffer.TYPE_USHORT:
281
        {
282
          short[] in = (short[]) obj;
283
          if (in == null)
284
            in = new short[1];
285
          in[0] = (short) data.getElem(x + y * scanlineStride);
286
          ret = in;
287
        }
288
        break;
289
      case DataBuffer.TYPE_INT:
290
        {
291
          int[] in = (int[]) obj;
292
          if (in == null)
293
            in = new int[1];
294
          in[0] = data.getElem(x + y * scanlineStride);
295
          ret = in;
296
        }
297
        break;
298
      }
299
    return ret;
300
  }
301
 
302
  /**
303
   * Returns an array containing the samples for the pixel at (x, y) in the
304
   * specified data buffer.  If <code>iArray</code> is not <code>null</code>,
305
   * it will be populated with the sample values and returned as the result of
306
   * this function (this avoids allocating a new array instance).
307
   *
308
   * @param x  the x-coordinate of the pixel.
309
   * @param y  the y-coordinate of the pixel.
310
   * @param iArray  an array to populate with the sample values and return as
311
   *     the result (if <code>null</code>, a new array will be allocated).
312
   * @param data  the data buffer (<code>null</code> not permitted).
313
   *
314
   * @return The pixel sample values.
315
   *
316
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
317
   */
318
  public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
319
  {
320
    int offset = scanlineStride*y + x;
321
    if (iArray == null) iArray = new int[numBands];
322
    int samples = data.getElem(offset);
323
 
324
    for (int b = 0; b < numBands; b++)
325
      iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];
326
 
327
    return iArray;
328
  }
329
 
330
  /**
331
   * Returns an array containing the samples for the pixels in the region
332
   * specified by (x, y, w, h) in the specified data buffer.  The array is
333
   * ordered by pixels (that is, all the samples for the first pixel are
334
   * grouped together, followed by all the samples for the second pixel, and so
335
   * on).  If <code>iArray</code> is not <code>null</code>, it will be
336
   * populated with the sample values and returned as the result of this
337
   * function (this avoids allocating a new array instance).
338
   *
339
   * @param x  the x-coordinate of the top-left pixel.
340
   * @param y  the y-coordinate of the top-left pixel.
341
   * @param w  the width of the region of pixels.
342
   * @param h  the height of the region of pixels.
343
   * @param iArray  an array to populate with the sample values and return as
344
   *     the result (if <code>null</code>, a new array will be allocated).
345
   * @param data  the data buffer (<code>null</code> not permitted).
346
   *
347
   * @return The pixel sample values.
348
   *
349
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
350
   */
351
  public int[] getPixels(int x, int y, int w, int h, int[] iArray,
352
                         DataBuffer data)
353
  {
354
    int offset = scanlineStride*y + x;
355
    if (iArray == null) iArray = new int[numBands*w*h];
356
    int outOffset = 0;
357
    for (y = 0; y < h; y++)
358
      {
359
        int lineOffset = offset;
360
        for (x = 0; x < w; x++)
361
          {
362
            int samples = data.getElem(lineOffset++);
363
            for (int b = 0; b < numBands; b++)
364
              iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
365
          }
366
        offset += scanlineStride;
367
      }
368
    return iArray;
369
  }
370
 
371
  /**
372
   * Returns the sample value for the pixel at (x, y) in the specified data
373
   * buffer.
374
   *
375
   * @param x  the x-coordinate of the pixel.
376
   * @param y  the y-coordinate of the pixel.
377
   * @param b  the band (in the range <code>0</code> to
378
   *     <code>getNumBands() - 1</code>).
379
   * @param data  the data buffer (<code>null</code> not permitted).
380
   *
381
   * @return The sample value.
382
   *
383
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
384
   */
385
  public int getSample(int x, int y, int b, DataBuffer data)
386
  {
387
    int offset = scanlineStride*y + x;
388
    int samples = data.getElem(offset);
389
    return (samples & bitMasks[b]) >>> bitOffsets[b];
390
  }
391
 
392
  public void setDataElements(int x, int y, Object obj, DataBuffer data)
393
  {
394
    int transferType = getTransferType();
395
    switch (transferType)
396
      {
397
      case DataBuffer.TYPE_BYTE:
398
        {
399
          byte[] in = (byte[]) obj;
400
          data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xff);
401
        }
402
        break;
403
      case DataBuffer.TYPE_USHORT:
404
        {
405
          short[] in = (short[]) obj;
406
          data.setElem(y * scanlineStride + x, ((int) in[0]) & 0xffff);
407
        }
408
        break;
409
      case DataBuffer.TYPE_INT:
410
        {
411
          int[] in = (int[]) obj;
412
          data.setElem(y * scanlineStride + x, in[0]);
413
          break;
414
        }
415
      }
416
  }
417
 
418
  /**
419
   * Sets the samples for the pixel at (x, y) in the specified data buffer to
420
   * the specified values.
421
   *
422
   * @param x  the x-coordinate of the pixel.
423
   * @param y  the y-coordinate of the pixel.
424
   * @param iArray  the sample values (<code>null</code> not permitted).
425
   * @param data  the data buffer (<code>null</code> not permitted).
426
   *
427
   * @throws NullPointerException if either <code>iArray</code> or
428
   *     <code>data</code> is <code>null</code>.
429
   */
430
  public void setPixel(int x, int y, int[] iArray, DataBuffer data)
431
  {
432
    int offset = scanlineStride*y + x;
433
 
434
    int samples = 0;
435
    for (int b = 0; b < numBands; b++)
436
      samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b];
437
 
438
    data.setElem(offset, samples);
439
  }
440
 
441
  /**
442
   * This method implements a more efficient way to set pixels than the default
443
   * implementation of the super class. It copies the pixel components directly
444
   * from the input array instead of creating a intermediate buffer.
445
   * @param x The x-coordinate of the pixel rectangle in <code>obj</code>.
446
   * @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
447
   * @param w The width of the pixel rectangle in <code>obj</code>.
448
   * @param h The height of the pixel rectangle in <code>obj</code>.
449
   * @param iArray The primitive array containing the pixels to set.
450
   * @param data The DataBuffer to store the pixels into.
451
   * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[],
452
   *     java.awt.image.DataBuffer)
453
   */
454
  public void setPixels(int x, int y, int w, int h, int[] iArray,
455
                                                DataBuffer data)
456
  {
457
    int inOffset = 0;
458
    for (int yy=y; yy<(y+h); yy++)
459
     {
460
      int offset = scanlineStride*yy + x;
461
      for (int xx=x; xx<(x+w); xx++)
462
       {
463
        int samples = 0;
464
        for (int b = 0; b < numBands; b++)
465
          samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
466
        data.setElem(0, offset, samples);
467
        inOffset += numBands;
468
        offset += 1;
469
      }
470
    }
471
  }
472
 
473
  /**
474
   * Sets the sample value for a band for the pixel at (x, y) in the
475
   * specified data buffer.
476
   *
477
   * @param x  the x-coordinate of the pixel.
478
   * @param y  the y-coordinate of the pixel.
479
   * @param b  the band (in the range <code>0</code> to
480
   *     <code>getNumBands() - 1</code>).
481
   * @param s  the sample value.
482
   * @param data  the data buffer (<code>null</code> not permitted).
483
   *
484
   * @throws NullPointerException if <code>data</code> is <code>null</code>.
485
   */
486
  public void setSample(int x, int y, int b, int s, DataBuffer data)
487
  {
488
    int offset = scanlineStride*y + x;
489
    int samples = data.getElem(offset);
490
    int bitMask = bitMasks[b];
491
    samples &= ~bitMask;
492
    samples |= (s << bitOffsets[b]) & bitMask;
493
    data.setElem(offset, samples);
494
  }
495
 
496
  /**
497
   * Tests this sample model for equality with an arbitrary object.  This
498
   * method returns <code>true</code> if and only if:
499
   * <ul>
500
   *   <li><code>obj</code> is not <code>null</code>;
501
   *   <li><code>obj</code> is an instance of
502
   *       <code>SinglePixelPackedSampleModel</code>;
503
   *   <li>both models have the same:
504
   *     <ul>
505
   *       <li><code>dataType</code>;
506
   *       <li><code>width</code>;
507
   *       <li><code>height</code>;
508
   *       <li><code>numBands</code>;
509
   *       <li><code>scanlineStride</code>;
510
   *       <li><code>bitMasks</code>;
511
   *       <li><code>bitOffsets</code>.
512
   *     </ul>
513
   *   </li>
514
   * </ul>
515
   *
516
   * @param obj  the object (<code>null</code> permitted)
517
   *
518
   * @return <code>true</code> if this model is equal to <code>obj</code>, and
519
   *     <code>false</code> otherwise.
520
   */
521
  public boolean equals(Object obj)
522
  {
523
    if (this == obj)
524
      return true;
525
    if (! (obj instanceof SinglePixelPackedSampleModel))
526
      return false;
527
    SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel) obj;
528
    if (this.dataType != that.dataType)
529
      return false;
530
    if (this.width != that.width)
531
      return false;
532
    if (this.height != that.height)
533
      return false;
534
    if (this.numBands != that.numBands)
535
      return false;
536
    if (this.scanlineStride != that.scanlineStride)
537
      return false;
538
    if (!Arrays.equals(this.bitMasks, that.bitMasks))
539
      return false;
540
    if (!Arrays.equals(this.bitOffsets, that.bitOffsets))
541
      return false;
542
    return true;
543
  }
544
 
545
  /**
546
   * Returns a hash code for this <code>SinglePixelPackedSampleModel</code>.
547
   *
548
   * @return A hash code.
549
   */
550
  public int hashCode()
551
  {
552
    // this hash code won't match Sun's, but that shouldn't matter...
553
    int result = 193;
554
    result = 37 * result + dataType;
555
    result = 37 * result + width;
556
    result = 37 * result + height;
557
    result = 37 * result + numBands;
558
    result = 37 * result + scanlineStride;
559
    for (int i = 0; i < bitMasks.length; i++)
560
      result = 37 * result + bitMasks[i];
561
    for (int i = 0; i < bitOffsets.length; i++)
562
      result = 37 * result + bitOffsets[i];
563
    return result;
564
  }
565
 
566
  /**
567
   * Creates a String with some information about this SampleModel.
568
   * @return A String describing this SampleModel.
569
   * @see java.lang.Object#toString()
570
   */
571
  public String toString()
572
  {
573
    CPStringBuilder result = new CPStringBuilder();
574
    result.append(getClass().getName());
575
    result.append("[");
576
    result.append("scanlineStride=").append(scanlineStride);
577
    for(int i = 0; i < bitMasks.length; i+=1)
578
    {
579
      result.append(", mask[").append(i).append("]=0x").append(
580
          Integer.toHexString(bitMasks[i]));
581
    }
582
 
583
    result.append("]");
584
    return result.toString();
585
  }
586
}

powered by: WebSVN 2.1.0

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