Mercurial > projects > dwt-mac
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 } |