comparison dwt/graphics/PaletteData.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 1a8b3cb347e0
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.graphics.PaletteData;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17
18 /**
19 * Instances of this class describe the color data used by an image.
20 * <p>
21 * Depending on the depth of the image, the PaletteData can take one
22 * of two forms, indicated by the isDirect field:
23 * </p>
24 * <dl>
25 * <dt>
26 * <em>isDirect is false</em>
27 * </dt>
28 * <dd>
29 * If isDirect is <code>false</code>, this palette is an indexed
30 * palette which maps pixel values to RGBs. The actual RGB values
31 * may be retrieved by using the getRGBs() method.
32 * </dd>
33 * <dt>
34 * <em>isDirect is true</em>
35 * </dt>
36 * <dd>
37 * If isDirect is <code>true</code>, this palette is a direct color
38 * palette. Instead of containing RGB values, it contains red,
39 * green and blue mask and shift information which indicates how
40 * the color components may be extracted from a given pixel.
41 * This means that the RGB value is actually encoded in the pixel value.
42 * <p>
43 * In this case, the shift data is the number of bits required to shift
44 * the RGB value to the left in order to align the high bit of the
45 * corresponding mask with the high bit of the first byte. This number
46 * may be negative, so care must be taken when shifting. For example,
47 * with a red mask of 0xFF0000, the red shift would be -16. With a red
48 * mask of 0x1F, the red shift would be 3.
49 * </p>
50 * </dd>
51 * </dl>
52 *
53 * @see Image
54 * @see RGB
55 */
56
57 public final class PaletteData {
58
59 /**
60 * true if the receiver is a direct palette,
61 * and false otherwise
62 */
63 public bool isDirect;
64
65 /**
66 * the RGB values for an indexed palette, where the
67 * indices of the array correspond to pixel values
68 */
69 public RGB[] colors;
70
71 /**
72 * the red mask for a direct palette
73 */
74 public int redMask;
75
76 /**
77 * the green mask for a direct palette
78 */
79 public int greenMask;
80
81 /**
82 * the blue mask for a direct palette
83 */
84 public int blueMask;
85
86 /**
87 * the red shift for a direct palette
88 */
89 public int redShift;
90
91 /**
92 * the green shift for a direct palette
93 */
94 public int greenShift;
95
96 /**
97 * the blue shift for a direct palette
98 */
99 public int blueShift;
100
101 /**
102 * Constructs a new indexed palette given an array of RGB values.
103 *
104 * @param colors the array of <code>RGB</code>s for the palette
105 *
106 * @exception IllegalArgumentException <ul>
107 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
108 * </ul>
109 */
110 public PaletteData(RGB[] colors) {
111 if (colors is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
112 this.colors = colors;
113 this.isDirect = false;
114 }
115
116 /**
117 * Constructs a new direct palette given the red, green and blue masks.
118 *
119 * @param redMask the red mask
120 * @param greenMask the green mask
121 * @param blueMask the blue mask
122 */
123 public PaletteData(int redMask, int greenMask, int blueMask) {
124 this.redMask = redMask;
125 this.greenMask = greenMask;
126 this.blueMask = blueMask;
127 this.isDirect = true;
128 this.redShift = shiftForMask(redMask);
129 this.greenShift = shiftForMask(greenMask);
130 this.blueShift = shiftForMask(blueMask);
131 }
132
133 /**
134 * Returns the pixel value corresponding to the given <code>RGB</code>.
135 *
136 * @param rgb the RGB to get the pixel value for
137 * @return the pixel value for the given RGB
138 *
139 * @exception IllegalArgumentException <ul>
140 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
141 * <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li>
142 * </ul>
143 */
144 public int getPixel(RGB rgb) {
145 if (rgb is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
146 if (isDirect) {
147 int pixel = 0;
148 pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask;
149 pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask;
150 pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask;
151 return pixel;
152 } else {
153 for (int i = 0; i < colors.length; i++) {
154 if (colors[i].equals(rgb)) return i;
155 }
156 /* The RGB did not exist in the palette */
157 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
158 return 0;
159 }
160 }
161
162 /**
163 * Returns an <code>RGB</code> corresponding to the given pixel value.
164 *
165 * @param pixel the pixel to get the RGB value for
166 * @return the RGB value for the given pixel
167 *
168 * @exception IllegalArgumentException <ul>
169 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
170 * <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li>
171 * </ul>
172 */
173 public RGB getRGB(int pixel) {
174 if (isDirect) {
175 int r = pixel & redMask;
176 r = (redShift < 0) ? r >>> -redShift : r << redShift;
177 int g = pixel & greenMask;
178 g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
179 int b = pixel & blueMask;
180 b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
181 return new RGB(r, g, b);
182 } else {
183 if (pixel < 0 || pixel >= colors.length) {
184 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
185 }
186 return colors[pixel];
187 }
188 }
189
190 /**
191 * Returns all the RGB values in the receiver if it is an
192 * indexed palette, or null if it is a direct palette.
193 *
194 * @return the <code>RGB</code>s for the receiver or null
195 */
196 public RGB[] getRGBs() {
197 return colors;
198 }
199
200 /**
201 * Computes the shift value for a given mask.
202 *
203 * @param mask the mask to compute the shift for
204 * @return the shift amount
205 *
206 * @see PaletteData
207 */
208 int shiftForMask(int mask) {
209 for (int i = 31; i >= 0; i--) {
210 if (((mask >> i) & 0x1) !is 0) return 7 - i;
211 }
212 return 32;
213 }
214
215 }