Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / java / awt / image / DirectColorModel.java
blob4f3715178181058abff7a89059cd1e043f52f09e
1 /* DirectColorModel.java --
2 Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package java.awt.image;
41 import gnu.java.awt.Buffers;
43 import java.awt.Point;
44 import java.awt.Transparency;
45 import java.awt.color.ColorSpace;
47 /**
48 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
49 * @author C. Brian Jones (cbj@gnu.org)
50 * @author Mark Benvenuto (mcb54@columbia.edu)
52 public class DirectColorModel extends PackedColorModel
54 /**
55 * For the color model created with this constructor the pixels
56 * will have fully opaque alpha components with a value of 255.
57 * Each mask should describe a fully contiguous set of bits in the
58 * most likely order of alpha, red, green, blue from the most significant
59 * byte to the least significant byte.
61 * @param pixelBits the number of bits wide used for bit size of pixel values
62 * @param rmask the bits describing the red component of a pixel
63 * @param gmask the bits describing the green component of a pixel
64 * @param bmask the bits describing the blue component of a pixel
66 public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
68 this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
69 rmask, gmask, bmask, 0,
70 false, // not alpha premultiplied
71 Buffers.smallestAppropriateTransferType(pixelBits) // find type
75 /**
76 * For the color model created with this constructor the pixels
77 * will have fully opaque alpha components with a value of 255.
78 * Each mask should describe a fully contiguous set of bits in the
79 * most likely order of red, green, blue from the most significant
80 * byte to the least significant byte.
82 * @param pixelBits the number of bits wide used for bit size of pixel values
83 * @param rmask the bits describing the red component of a pixel
84 * @param gmask the bits describing the green component of a pixel
85 * @param bmask the bits describing the blue component of a pixel
86 * @param amask the bits describing the alpha component of a pixel
88 public DirectColorModel(int pixelBits,
89 int rmask, int gmask, int bmask, int amask)
91 this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
92 rmask, gmask, bmask, amask,
93 false, // not alpha premultiplied
94 Buffers.smallestAppropriateTransferType(pixelBits) // find type
98 public DirectColorModel(ColorSpace cspace, int pixelBits,
99 int rmask, int gmask, int bmask, int amask,
100 boolean isAlphaPremultiplied,
101 int transferType)
103 super(cspace, pixelBits,
104 rmask, gmask, bmask, amask, isAlphaPremultiplied,
105 ((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
106 transferType);
109 public final int getRedMask()
111 return getMask(0);
114 public final int getGreenMask()
116 return getMask(1);
119 public final int getBlueMask()
121 return getMask(2);
124 public final int getAlphaMask()
126 return hasAlpha() ? getMask(3) : 0;
130 * Get the red component of the given pixel.
131 * <br>
133 public final int getRed(int pixel)
135 return extractAndNormalizeSample(pixel, 0);
139 * Get the green component of the given pixel.
140 * <br>
142 public final int getGreen(int pixel)
144 return extractAndNormalizeSample(pixel, 1);
148 * Get the blue component of the given pixel.
149 * <br>
151 public final int getBlue(int pixel)
153 return extractAndNormalizeSample(pixel, 2);
157 * Get the alpha component of the given pixel.
158 * <br>
160 public final int getAlpha(int pixel)
162 if (!hasAlpha())
163 return 255;
164 return extractAndScaleSample(pixel, 3);
167 private int extractAndNormalizeSample(int pixel, int component)
169 int value = extractAndScaleSample(pixel, component);
170 if (hasAlpha() && isAlphaPremultiplied())
171 value = value*255/getAlpha(pixel);
172 return value;
175 private int extractAndScaleSample(int pixel, int component)
177 int field = pixel & getMask(component);
178 int to8BitShift =
179 8 - shifts[component] - getComponentSize(component);
180 return (to8BitShift>0) ?
181 (field << to8BitShift) :
182 (field >>> (-to8BitShift));
186 * Get the RGB color value of the given pixel using the default
187 * RGB color model.
188 * <br>
190 * @param pixel a pixel value
192 public final int getRGB(int pixel)
194 /* FIXME: The Sun docs show that this method is overridden, but I
195 don't see any way to improve on the superclass
196 implementation. */
197 return super.getRGB(pixel);
200 public int getRed(Object inData)
202 return getRed(getPixelFromArray(inData));
205 public int getGreen(Object inData)
207 return getGreen(getPixelFromArray(inData));
210 public int getBlue(Object inData)
212 return getBlue(getPixelFromArray(inData));
215 public int getAlpha(Object inData)
217 return getAlpha(getPixelFromArray(inData));
220 public int getRGB(Object inData)
222 return getRGB(getPixelFromArray(inData));
226 * Converts a normalized pixel int value in the sRGB color
227 * space to an array containing a single pixel of the color space
228 * of the color model.
230 * <p>This method performs the inverse function of
231 * <code>getRGB(Object inData)</code>.
233 * @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
235 * @param pixel to avoid needless creation of arrays, an array to
236 * use to return the pixel can be given. If null, a suitable array
237 * will be created.
239 * @return array of transferType containing a single pixel. The
240 * pixel should be encoded in the natural way of the color model.
242 * @see #getRGB(Object)
244 public Object getDataElements(int rgb, Object pixel)
246 // FIXME: handle alpha multiply
248 int pixelValue = 0;
249 int a = 0;
250 if (hasAlpha()) {
251 a = (rgb >>> 24) & 0xff;
252 pixelValue = valueToField(a, 3, 8);
255 if (hasAlpha() && isAlphaPremultiplied())
257 int r, g, b;
258 /* if r=0xff and a=0xff, then resulting
259 value will be (r*a)>>>8 == 0xfe... This seems wrong.
260 We should divide by 255 rather than shifting >>>8 after
261 multiplying.
263 Too bad, shifting is probably less expensive.
264 r = ((rgb >>> 16) & 0xff)*a;
265 g = ((rgb >>> 8) & 0xff)*a;
266 b = ((rgb >>> 0) & 0xff)*a; */
267 /* The r, g, b values we calculate are 16 bit. This allows
268 us to avoid discarding the lower 8 bits obtained if
269 multiplying with the alpha band. */
271 // using 16 bit values
272 r = ((rgb >>> 8) & 0xff00)*a/255;
273 g = ((rgb >>> 0) & 0xff00)*a/255;
274 b = ((rgb << 8) & 0xff00)*a/255;
275 pixelValue |=
276 valueToField(r, 0, 16) | // Red
277 valueToField(g, 1, 16) | // Green
278 valueToField(b, 2, 16); // Blue
280 else
282 int r, g, b;
283 // using 8 bit values
284 r = (rgb >>> 16) & 0xff;
285 g = (rgb >>> 8) & 0xff;
286 b = (rgb >>> 0) & 0xff;
288 pixelValue |=
289 valueToField(r, 0, 8) | // Red
290 valueToField(g, 1, 8) | // Green
291 valueToField(b, 2, 8); // Blue
294 /* In this color model, the whole pixel fits in the first element
295 of the array. */
296 DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1);
297 buffer.setElem(0, pixelValue);
298 return Buffers.getData(buffer);
302 * Converts a value to the correct field bits based on the
303 * information derived from the field masks.
305 * @param highBit the position of the most significant bit in the
306 * val parameter.
308 private int valueToField(int val, int component, int highBit)
310 int toFieldShift =
311 getComponentSize(component) + shifts[component] - highBit;
312 int ret = (toFieldShift>0) ?
313 (val << toFieldShift) :
314 (val >>> (-toFieldShift));
315 return ret & getMask(component);
319 * Converts a 16 bit value to the correct field bits based on the
320 * information derived from the field masks.
322 private int value16ToField(int val, int component)
324 int toFieldShift = getComponentSize(component) + shifts[component] - 16;
325 return (toFieldShift>0) ?
326 (val << toFieldShift) :
327 (val >>> (-toFieldShift));
331 * Fills an array with the unnormalized component samples from a
332 * pixel value. I.e. decompose the pixel, but not perform any
333 * color conversion.
335 public final int[] getComponents(int pixel, int[] components, int offset)
337 int numComponents = getNumComponents();
338 if (components == null) components = new int[offset + numComponents];
340 for (int b=0; b<numComponents; b++)
341 components[offset++] = (pixel&getMask(b)) >>> shifts[b];
343 return components;
346 public final int[] getComponents(Object pixel, int[] components,
347 int offset)
349 return getComponents(getPixelFromArray(pixel), components, offset);
353 * Creates a <code>WriteableRaster</code> that has a <code>SampleModel</code>
354 * that is compatible with this <code>ColorModel</code>.
356 * @param w the width of the writeable raster to create
357 * @param h the height of the writeable raster to create
359 * @throws IllegalArgumentException if <code>w</code> or <code>h</code>
360 * is less than or equal to zero
362 public final WritableRaster createCompatibleWritableRaster(int w, int h)
364 // Sun also makes this check here.
365 if(w <= 0 || h <= 0)
366 throw new IllegalArgumentException("width (=" + w + ") and height (="
367 + h + ") must be > 0");
369 SampleModel sm = createCompatibleSampleModel(w, h);
370 Point origin = new Point(0, 0);
371 return Raster.createWritableRaster(sm, origin);
374 public int getDataElement(int[] components, int offset)
376 int numComponents = getNumComponents();
377 int pixelValue = 0;
379 for (int c=0; c<numComponents; c++)
380 pixelValue |= (components[offset++] << shifts[c]) & getMask(c);
382 return pixelValue;
385 public Object getDataElements(int[] components, int offset, Object obj)
387 /* In this color model, the whole pixel fits in the first element
388 of the array. */
389 int pixelValue = getDataElement(components, offset);
391 DataBuffer buffer = Buffers.createBuffer(transferType, obj, 1);
392 buffer.setElem(0, pixelValue);
393 return Buffers.getData(buffer);
396 public final ColorModel coerceData (WritableRaster raster,
397 boolean isAlphaPremultiplied)
399 if (this.isAlphaPremultiplied == isAlphaPremultiplied)
400 return this;
402 /* TODO: provide better implementation based on the
403 assumptions we can make due to the specific type of the
404 color model. */
405 super.coerceData(raster, isAlphaPremultiplied);
407 return new ComponentColorModel(cspace, bits, hasAlpha(),
408 isAlphaPremultiplied, // argument
409 transparency, transferType);
412 public boolean isCompatibleRaster(Raster raster)
414 /* FIXME: the Sun docs say this method is overridden here,
415 but I don't see any way to improve upon the implementation
416 in ColorModel. */
417 return super.isCompatibleRaster(raster);
420 String stringParam()
422 return super.stringParam() +
423 ", redMask=" + Integer.toHexString(getRedMask()) +
424 ", greenMask=" + Integer.toHexString(getGreenMask()) +
425 ", blueMask=" + Integer.toHexString(getBlueMask()) +
426 ", alphaMask=" + Integer.toHexString(getAlphaMask());
429 public String toString()
431 /* FIXME: Again, docs say override, but how do we improve upon the
432 superclass implementation? */
433 return super.toString();