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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* ComponentColorModel.java --
2
   Copyright (C) 2000, 2002, 2004  Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.awt.image;
40
 
41
import gnu.java.awt.Buffers;
42
 
43
import java.awt.Point;
44
import java.awt.color.ColorSpace;
45
import java.util.Arrays;
46
 
47
public class ComponentColorModel extends ColorModel
48
{
49
  // Find sum of all elements of the array.
50
  private static int sum(int[] values)
51
  {
52
    int sum = 0;
53
    for (int i=0; i<values.length; i++)
54
      sum += values[i];
55
    return sum;
56
  }
57
 
58
  // Create an appropriate array of bits, given a colorspace (ie, number of
59
  // bands), size of the storage data type, and presence of an alpha band.
60
  private static int[] findBits(ColorSpace colorSpace, int transferType,
61
                                boolean hasAlpha)
62
  {
63
    int[] bits;
64
    if (hasAlpha)
65
      bits = new int[colorSpace.getNumComponents()+1];
66
    else
67
      bits = new int[colorSpace.getNumComponents()];
68
 
69
    Arrays.fill(bits, DataBuffer.getDataTypeSize(transferType));
70
 
71
    return bits;
72
  }
73
 
74
  public ComponentColorModel(ColorSpace colorSpace, int[] bits,
75
                             boolean hasAlpha,
76
                             boolean isAlphaPremultiplied,
77
                             int transparency, int transferType)
78
  {
79
    super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
80
          transparency, transferType);
81
  }
82
 
83
  /**
84
   * Construct a new ComponentColorModel.
85
   *
86
   * This constructor makes all bits of each sample significant, so for a
87
   * transferType of DataBuffer.BYTE, the bits per sample is 8, etc.  If
88
   * both hasAlpha and isAlphaPremultiplied are true, color samples are
89
   * assumed to be premultiplied by the alpha component.  Transparency may be
90
   * one of OPAQUE, BITMASK, or TRANSLUCENT.
91
   *
92
   * @param colorSpace The colorspace for this color model.
93
   * @param hasAlpha True if there is an alpha component.
94
   * @param isAlphaPremultiplied True if colors are already multiplied by
95
   * alpha.
96
   * @param transparency The type of alpha values.
97
   * @param transferType Data type of pixel sample values.
98
   * @since 1.4
99
   */
100
  public ComponentColorModel(ColorSpace colorSpace,
101
                             boolean hasAlpha,
102
                             boolean isAlphaPremultiplied,
103
                             int transparency, int transferType)
104
  {
105
    this(colorSpace, findBits(colorSpace, transferType, hasAlpha), hasAlpha,
106
         isAlphaPremultiplied, transparency, transferType);
107
  }
108
 
109
  public int getRed(int pixel)
110
  {
111
    if (getNumComponents()>1) throw new IllegalArgumentException();
112
    return (int) getRGBFloat(pixel)[0];
113
  }
114
 
115
  public int getGreen(int pixel)
116
  {
117
    if (getNumComponents()>1) throw new IllegalArgumentException();
118
    return (int) getRGBFloat(pixel)[0];
119
  }
120
 
121
  public int getBlue(int pixel)
122
  {
123
    if (getNumComponents()>1) throw new IllegalArgumentException();
124
    return (int) getRGBFloat(pixel)[0];
125
  }
126
 
127
  public int getAlpha(int pixel)
128
  {
129
    if (getNumComponents()>1) throw new IllegalArgumentException();
130
    int shift = 8 - getComponentSize(getNumColorComponents());
131
    if (shift >= 0) return pixel << shift;
132
    return pixel >> (-shift);
133
  }
134
 
135
  public int getRGB(int pixel)
136
  {
137
    float[] rgb = getRGBFloat(pixel);
138
    int ret = getRGB(rgb);
139
    if (hasAlpha()) ret |= getAlpha(pixel) << 24;
140
    return ret;
141
  }
142
 
143
 
144
  /* Note, it's OK to pass a to large array to toRGB(). Extra
145
     elements are ignored. */
146
 
147
  private float[] getRGBFloat(int pixel)
148
  {
149
    float[] data = { pixel };
150
    return cspace.toRGB(data);
151
  }
152
 
153
  private float[] getRGBFloat(Object inData)
154
  {
155
    DataBuffer buffer =
156
    Buffers.createBufferFromData(transferType, inData,
157
                                 getNumComponents());
158
    int colors = getNumColorComponents();
159
    float[] data = new float[colors];
160
 
161
    // FIXME: unpremultiply data that is premultiplied
162
    for (int i=0; i<colors; i++)
163
      {
164
        float maxValue = (1<<getComponentSize(i))-1;
165
        data[i] = buffer.getElemFloat(i)/maxValue;
166
      }
167
    float[] rgb = cspace.toRGB(data);
168
    return rgb;
169
  }
170
 
171
  public int getRed(Object inData)
172
  {
173
    return (int) getRGBFloat(inData)[0]*255;
174
  }
175
 
176
  public int getGreen(Object inData)
177
  {
178
    return (int) getRGBFloat(inData)[1]*255;
179
  }
180
 
181
  public int getBlue(Object inData)
182
  {
183
    return (int) getRGBFloat(inData)[2]*255;
184
  }
185
 
186
  public int getAlpha(Object inData)
187
  {
188
    DataBuffer buffer =
189
      Buffers.createBufferFromData(transferType, inData,
190
                                   getNumComponents());
191
    int shift = 8 - getComponentSize(getNumColorComponents());
192
    int alpha = buffer.getElem(getNumColorComponents());
193
    if (shift >= 0) return alpha << shift;
194
    return alpha >> (-shift);
195
  }
196
 
197
  private int getRGB(float[] rgb)
198
  {
199
    /* NOTE: We could cast to byte instead of int here. This would
200
       avoid bits spilling over from one bit field to
201
       another. But, if we assume that floats are in the [0.0,
202
       1.0] range, this will never happen anyway. */
203
 
204
    /* Remember to multiply BEFORE casting to int, otherwise, decimal
205
       point data will be lost. */
206
    int ret =
207
      (((int) (rgb[0]*255F)) << 16) |
208
      (((int) (rgb[1]*255F)) <<  8) |
209
      (((int) (rgb[2]*255F)) <<  0);
210
    return ret;
211
  }
212
 
213
  /**
214
   * @param inData pixel data of transferType, as returned by the
215
   * getDataElements method in SampleModel.
216
   */
217
  public int getRGB(Object inData)
218
  {
219
    float[] rgb = getRGBFloat(inData);
220
    int ret = getRGB(rgb);
221
    if (hasAlpha()) ret |= getAlpha(inData) << 24;
222
    return ret;
223
  }
224
 
225
  public Object getDataElements(int rgb, Object pixel)
226
  {
227
    // Convert rgb to [0.0, 1.0] sRGB values.
228
    float[] rgbFloats = {
229
      ((rgb >> 16)&0xff)/255.0F,
230
      ((rgb >>  8)&0xff)/255.0F,
231
      ((rgb >>  0)&0xff)/255.0F
232
    };
233
 
234
    // Convert from rgb to color space components.
235
    float[] data = cspace.fromRGB(rgbFloats);
236
    DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
237
                                             getNumComponents());
238
    int numColors = getNumColorComponents();
239
 
240
    if (hasAlpha())
241
      {
242
        float alpha = ((rgb >> 24)&0xff)/255.0F;
243
 
244
        /* If color model has alpha and should be premultiplied, multiply
245
           color space components with alpha value. */
246
        if (isAlphaPremultiplied()) {
247
          for (int i=0; i<numColors; i++)
248
            data[i] *= alpha;
249
        }
250
        // Scale the alpha sample to the correct number of bits.
251
        alpha *= (1<<(bits[numColors]-1));
252
        // Arrange the alpha sample in the output array.
253
        buffer.setElemFloat(numColors, alpha);
254
      }
255
    for (int i=0; i<numColors; i++)
256
      {
257
        // Scale the color samples to the correct number of bits.
258
        float value = data[i]*(1<<(bits[i]-1));
259
        // Arrange the color samples in the output array.
260
        buffer.setElemFloat(i, value);
261
      }
262
    return Buffers.getData(buffer);
263
  }
264
 
265
  public int[] getComponents(int pixel, int[] components, int offset)
266
  {
267
    if (getNumComponents()>1) throw new IllegalArgumentException();
268
    if (components == null)
269
    components = new int[getNumComponents() + offset];
270
    components[offset] = pixel;
271
    return components;
272
  }
273
 
274
  public int[] getComponents(Object pixel, int[] components, int offset)
275
  {
276
    DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
277
                                             getNumComponents());
278
    int numComponents = getNumComponents();
279
 
280
    if (components == null)
281
      components = new int[numComponents + offset];
282
 
283
    for (int i=0; i<numComponents; i++)
284
      components[offset++] = buffer.getElem(i);
285
 
286
    return components;
287
  }
288
 
289
  public int getDataElement(int[] components, int offset)
290
  {
291
    if (getNumComponents()>1) throw new IllegalArgumentException();
292
    return components[offset];
293
  }
294
 
295
  public Object getDataElements(int[] components, int offset, Object obj)
296
  {
297
    DataBuffer buffer = Buffers.createBuffer(transferType, obj,
298
                                             getNumComponents());
299
    int numComponents = getNumComponents();
300
 
301
    for (int i=0; i<numComponents; i++)
302
      buffer.setElem(i, components[offset++]);
303
 
304
    return Buffers.getData(buffer);
305
  }
306
 
307
  public ColorModel coerceData(WritableRaster raster,
308
                               boolean isAlphaPremultiplied) {
309
    if (this.isAlphaPremultiplied == isAlphaPremultiplied || !hasAlpha())
310
      return this;
311
 
312
    /* TODO: provide better implementation based on the
313
       assumptions we can make due to the specific type of the
314
       color model. */
315
    coerceDataWorker(raster, isAlphaPremultiplied);
316
 
317
    return new ComponentColorModel(cspace, hasAlpha, isAlphaPremultiplied,
318
                                   transparency, transferType);
319
  }
320
 
321
  public boolean isCompatibleRaster(Raster raster)
322
  {
323
    return super.isCompatibleRaster(raster);
324
    // FIXME: Should we test something more here? (Why override?)
325
  }
326
 
327
  public WritableRaster createCompatibleWritableRaster(int w, int h)
328
  {
329
    SampleModel sm = createCompatibleSampleModel(w, h);
330
    Point origin = new Point(0, 0);
331
    return Raster.createWritableRaster(sm, origin);
332
  }
333
 
334
 
335
  /**
336
   * Creates a <code>SampleModel</code> whose arrangement of pixel
337
   * data is compatible to this <code>ColorModel</code>.
338
   *
339
   * @param w the number of pixels in the horizontal direction.
340
   * @param h the number of pixels in the vertical direction.
341
   */
342
  public SampleModel createCompatibleSampleModel(int w, int h)
343
  {
344
    int pixelStride, scanlineStride;
345
    int[] bandOffsets;
346
 
347
    pixelStride = getNumComponents();
348
    scanlineStride = pixelStride * w;
349
 
350
    /* We might be able to re-use the same bandOffsets array among
351
     * multiple calls to this method. However, this optimization does
352
     * not seem worthwile because setting up descriptive data
353
     * structures (such as SampleModels) is neglectible in comparision
354
     * to shuffling around masses of pixel data.
355
     */
356
    bandOffsets = new int[pixelStride];
357
    for (int i = 0; i < pixelStride; i++)
358
      bandOffsets[i] = i;
359
 
360
    /* FIXME: Think about whether it would make sense to return the
361
     * possibly more efficient PixelInterleavedSampleModel for other
362
     * transferTypes as well. It seems unlikely that this would break
363
     * any user applications, so the Mauve tests on this method
364
     * might be too restrictive.
365
     */
366
    switch (transferType)
367
      {
368
      case DataBuffer.TYPE_BYTE:
369
      case DataBuffer.TYPE_USHORT:
370
        return new PixelInterleavedSampleModel(transferType, w, h,
371
                                               pixelStride,
372
                                               scanlineStride,
373
                                               bandOffsets);
374
 
375
      default:
376
        return new ComponentSampleModel(transferType, w, h,
377
                                        pixelStride,
378
                                        scanlineStride,
379
                                        bandOffsets);
380
      }
381
  }
382
 
383
 
384
  public boolean isCompatibleSampleModel(SampleModel sm)
385
  {
386
    return
387
      (sm instanceof ComponentSampleModel) &&
388
      super.isCompatibleSampleModel(sm);
389
  }
390
 
391
  public WritableRaster getAlphaRaster(WritableRaster raster)
392
  {
393
    if (!hasAlpha()) return null;
394
 
395
    SampleModel sm = raster.getSampleModel();
396
    int[] alphaBand = { sm.getNumBands() - 1 };
397
    SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
398
    DataBuffer buffer = raster.getDataBuffer();
399
    Point origin = new Point(0, 0);
400
    return Raster.createWritableRaster(alphaModel, buffer, origin);
401
  }
402
 
403
  public boolean equals(Object obj)
404
  {
405
    if (!(obj instanceof ComponentColorModel)) return false;
406
    return super.equals(obj);
407
  }
408
}

powered by: WebSVN 2.1.0

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