xref: /haiku/src/build/libbe/interface/Bitmap.cpp (revision 579f1dbca962a2a03df54f69fdc6e9423f91f20e)
1 /*
2  * Copyright 2001-2008, Haiku Inc.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ingo Weinhold (bonefish@users.sf.net)
7  *		DarkWyrm <bpmagic@columbus.rr.com>
8  *		Stephan Aßmus <superstippi@gmx.de>
9  */
10 
11 /*!	BBitmap objects represent off-screen windows that contain bitmap data. */
12 
13 #include <algorithm>
14 #include <limits.h>
15 #include <new>
16 #include <stdio.h>
17 #include <stdlib.h>
18 
19 #include <Bitmap.h>
20 #include <GraphicsDefs.h>
21 #include <Locker.h>
22 #include <Message.h>
23 
24 
25 // structures defining the pixel layout
26 
27 struct rgb32_pixel {
28 	uint8 blue;
29 	uint8 green;
30 	uint8 red;
31 	uint8 alpha;
32 };
33 
34 struct rgb32_big_pixel {
35 	uint8 red;
36 	uint8 green;
37 	uint8 blue;
38 	uint8 alpha;
39 };
40 
41 struct rgb24_pixel {
42 	uint8 blue;
43 	uint8 green;
44 	uint8 red;
45 };
46 
47 struct rgb24_big_pixel {
48 	uint8 red;
49 	uint8 green;
50 	uint8 blue;
51 };
52 
53 struct rgb16_pixel {
54 	uint8 gb;	// G[2:0],B[4:0]
55 	uint8 rg;	// 16: R[4:0],G[5:3]
56 				// 15: -[0],R[4:0],G[4:3]
57 };
58 
59 struct rgb16_big_pixel {
60 	uint8 rg;	// 16: R[4:0],G[5:3]
61 				// 15: -[0],R[4:0],G[4:3]
62 	uint8 gb;	// G[2:0],B[4:0]
63 };
64 
65 // types defining what is needed to store a color value
66 
67 struct rgb_color_value {
68 	uint8 red;
69 	uint8 green;
70 	uint8 blue;
71 	uint8 alpha;
72 };
73 
74 typedef uint8 gray_color_value;
75 
76 // TODO: system palette -- hard-coded for now, when the app server is ready
77 // we should use system_colors() or BScreen::ColorMap().
78 const rgb_color kSystemPalette[] = {
79 	{   0,   0,   0, 255 }, {   8,   8,   8, 255 }, {  16,  16,  16, 255 },
80 	{  24,  24,  24, 255 }, {  32,  32,  32, 255 }, {  40,  40,  40, 255 },
81 	{  48,  48,  48, 255 }, {  56,  56,  56, 255 }, {  64,  64,  64, 255 },
82 	{  72,  72,  72, 255 }, {  80,  80,  80, 255 }, {  88,  88,  88, 255 },
83 	{  96,  96,  96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 },
84 	{ 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 },
85 	{ 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 },
86 	{ 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 },
87 	{ 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 },
88 	{ 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 },
89 	{ 240, 240, 240, 255 }, { 248, 248, 248, 255 }, {   0,   0, 255, 255 },
90 	{   0,   0, 229, 255 }, {   0,   0, 204, 255 }, {   0,   0, 179, 255 },
91 	{   0,   0, 154, 255 }, {   0,   0, 129, 255 }, {   0,   0, 105, 255 },
92 	{   0,   0,  80, 255 }, {   0,   0,  55, 255 }, {   0,   0,  30, 255 },
93 	{ 255,   0,   0, 255 }, { 228,   0,   0, 255 }, { 203,   0,   0, 255 },
94 	{ 178,   0,   0, 255 }, { 153,   0,   0, 255 }, { 128,   0,   0, 255 },
95 	{ 105,   0,   0, 255 }, {  80,   0,   0, 255 }, {  55,   0,   0, 255 },
96 	{  30,   0,   0, 255 }, {   0, 255,   0, 255 }, {   0, 228,   0, 255 },
97 	{   0, 203,   0, 255 }, {   0, 178,   0, 255 }, {   0, 153,   0, 255 },
98 	{   0, 128,   0, 255 }, {   0, 105,   0, 255 }, {   0,  80,   0, 255 },
99 	{   0,  55,   0, 255 }, {   0,  30,   0, 255 }, {   0, 152,  51, 255 },
100 	{ 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 },
101 	{ 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255,  51, 255 },
102 	{ 203, 255,   0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 },
103 	{ 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255,  51, 255 },
104 	{ 152, 255,   0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 },
105 	{ 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255,  51, 255 },
106 	{ 102, 255,   0, 255 }, {  51, 255, 255, 255 }, {  51, 255, 203, 255 },
107 	{  51, 255, 152, 255 }, {  51, 255, 102, 255 }, {  51, 255,  51, 255 },
108 	{  51, 255,   0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 },
109 	{ 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152,  51, 255 },
110 	{ 255, 152,   0, 255 }, {   0, 102, 255, 255 }, {   0, 102, 203, 255 },
111 	{ 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 },
112 	{ 203, 203, 102, 255 }, { 203, 203,  51, 255 }, { 203, 203,   0, 255 },
113 	{ 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 },
114 	{ 152, 203, 102, 255 }, { 152, 203,  51, 255 }, { 152, 203,   0, 255 },
115 	{ 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 },
116 	{ 102, 203, 102, 255 }, { 102, 203,  51, 255 }, { 102, 203,   0, 255 },
117 	{  51, 203, 255, 255 }, {  51, 203, 203, 255 }, {  51, 203, 152, 255 },
118 	{  51, 203, 102, 255 }, {  51, 203,  51, 255 }, {  51, 203,   0, 255 },
119 	{ 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 },
120 	{ 255, 102, 102, 255 }, { 255, 102,  51, 255 }, { 255, 102,   0, 255 },
121 	{   0, 102, 152, 255 }, {   0, 102, 102, 255 }, { 203, 152, 255, 255 },
122 	{ 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 },
123 	{ 203, 152,  51, 255 }, { 203, 152,   0, 255 }, { 152, 152, 255, 255 },
124 	{ 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 },
125 	{ 152, 152,  51, 255 }, { 152, 152,   0, 255 }, { 102, 152, 255, 255 },
126 	{ 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 },
127 	{ 102, 152,  51, 255 }, { 102, 152,   0, 255 }, {  51, 152, 255, 255 },
128 	{  51, 152, 203, 255 }, {  51, 152, 152, 255 }, {  51, 152, 102, 255 },
129 	{  51, 152,  51, 255 }, {  51, 152,   0, 255 }, { 230, 134,   0, 255 },
130 	{ 255,  51, 203, 255 }, { 255,  51, 152, 255 }, { 255,  51, 102, 255 },
131 	{ 255,  51,  51, 255 }, { 255,  51,   0, 255 }, {   0, 102,  51, 255 },
132 	{   0, 102,   0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 },
133 	{ 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102,  51, 255 },
134 	{ 203, 102,   0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 },
135 	{ 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102,  51, 255 },
136 	{ 152, 102,   0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 },
137 	{ 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102,  51, 255 },
138 	{ 102, 102,   0, 255 }, {  51, 102, 255, 255 }, {  51, 102, 203, 255 },
139 	{  51, 102, 152, 255 }, {  51, 102, 102, 255 }, {  51, 102,  51, 255 },
140 	{  51, 102,   0, 255 }, { 255,   0, 255, 255 }, { 255,   0, 203, 255 },
141 	{ 255,   0, 152, 255 }, { 255,   0, 102, 255 }, { 255,   0,  51, 255 },
142 	{ 255, 175,  19, 255 }, {   0,  51, 255, 255 }, {   0,  51, 203, 255 },
143 	{ 203,  51, 255, 255 }, { 203,  51, 203, 255 }, { 203,  51, 152, 255 },
144 	{ 203,  51, 102, 255 }, { 203,  51,  51, 255 }, { 203,  51,   0, 255 },
145 	{ 152,  51, 255, 255 }, { 152,  51, 203, 255 }, { 152,  51, 152, 255 },
146 	{ 152,  51, 102, 255 }, { 152,  51,  51, 255 }, { 152,  51,   0, 255 },
147 	{ 102,  51, 255, 255 }, { 102,  51, 203, 255 }, { 102,  51, 152, 255 },
148 	{ 102,  51, 102, 255 }, { 102,  51,  51, 255 }, { 102,  51,   0, 255 },
149 	{  51,  51, 255, 255 }, {  51,  51, 203, 255 }, {  51,  51, 152, 255 },
150 	{  51,  51, 102, 255 }, {  51,  51,  51, 255 }, {  51,  51,   0, 255 },
151 	{ 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 },
152 	{ 255, 203, 255, 255 }, {   0,  51, 152, 255 }, {   0,  51, 102, 255 },
153 	{   0,  51,  51, 255 }, {   0,  51,   0, 255 }, { 203,   0, 255, 255 },
154 	{ 203,   0, 203, 255 }, { 203,   0, 152, 255 }, { 203,   0, 102, 255 },
155 	{ 203,   0,  51, 255 }, { 255, 227,  70, 255 }, { 152,   0, 255, 255 },
156 	{ 152,   0, 203, 255 }, { 152,   0, 152, 255 }, { 152,   0, 102, 255 },
157 	{ 152,   0,  51, 255 }, { 152,   0,   0, 255 }, { 102,   0, 255, 255 },
158 	{ 102,   0, 203, 255 }, { 102,   0, 152, 255 }, { 102,   0, 102, 255 },
159 	{ 102,   0,  51, 255 }, { 102,   0,   0, 255 }, {  51,   0, 255, 255 },
160 	{  51,   0, 203, 255 }, {  51,   0, 152, 255 }, {  51,   0, 102, 255 },
161 	{  51,   0,  51, 255 }, {  51,   0,   0, 255 }, { 255, 203,  51, 255 },
162 	{ 255, 203,   0, 255 }, { 255, 255,   0, 255 }, { 255, 255,  51, 255 },
163 	{ 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 },
164 	{ 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8
165 };
166 
167 
168 /*!	\brief Returns the number of bytes per row needed to store the actual
169 		   bitmap data (not including any padding) given a color space and a
170 		   row width.
171 	\param colorSpace The color space.
172 	\param width The width.
173 	\return The number of bytes per row needed to store data for a row, or
174 			0, if the color space is not supported.
175 */
176 static inline int32
177 get_raw_bytes_per_row(color_space colorSpace, int32 width)
178 {
179 	int32 bpr = 0;
180 	switch (colorSpace) {
181 		// supported
182 		case B_RGB32: case B_RGBA32:
183 		case B_RGB32_BIG: case B_RGBA32_BIG:
184 		case B_UVL32: case B_UVLA32:
185 		case B_LAB32: case B_LABA32:
186 		case B_HSI32: case B_HSIA32:
187 		case B_HSV32: case B_HSVA32:
188 		case B_HLS32: case B_HLSA32:
189 		case B_CMY32: case B_CMYA32: case B_CMYK32:
190 			bpr = 4 * width;
191 			break;
192 		case B_RGB24: case B_RGB24_BIG:
193 		case B_UVL24: case B_LAB24: case B_HSI24:
194 		case B_HSV24: case B_HLS24: case B_CMY24:
195 			bpr = 3 * width;
196 			break;
197 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
198 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
199 			bpr = 2 * width;
200 			break;
201 		case B_CMAP8: case B_GRAY8:
202 			bpr = width;
203 			break;
204 		case B_GRAY1:
205 			bpr = (width + 7) / 8;
206 			break;
207 		case B_YCbCr422: case B_YUV422:
208 			bpr = (width + 3) / 4 * 8;
209 			break;
210 		case B_YCbCr411: case B_YUV411:
211 			bpr = (width + 3) / 4 * 6;
212 			break;
213 		case B_YCbCr444: case B_YUV444:
214 			bpr = (width + 3) / 4 * 12;
215 			break;
216 		case B_YCbCr420: case B_YUV420:
217 			bpr = (width + 3) / 4 * 6;
218 			break;
219 		// unsupported
220 		case B_NO_COLOR_SPACE:
221 		case B_YUV9: case B_YUV12:
222 			break;
223 	}
224 	return bpr;
225 }
226 
227 
228 /*!	\brief Returns the number of bytes per row needed to store the bitmap
229 		   data (including any padding) given a color space and a row width.
230 	\param colorSpace The color space.
231 	\param width The width.
232 	\return The number of bytes per row needed to store data for a row, or
233 			0, if the color space is not supported.
234 */
235 static inline int32
236 get_bytes_per_row(color_space colorSpace, int32 width)
237 {
238 	int32 bpr = get_raw_bytes_per_row(colorSpace, width);
239 	// align to int32
240 	bpr = (bpr + 3) & 0x7ffffffc;
241 	return bpr;
242 }
243 
244 
245 /*!	\brief Returns the brightness of an RGB 24 color.
246 	\param red Value of the red component.
247 	\param green Value of the green component.
248 	\param blue Value of the blue component.
249 	\return The brightness for the supplied RGB color as a value between 0
250 			and 255.
251 */
252 static inline uint8
253 brightness_for(uint8 red, uint8 green, uint8 blue)
254 {
255 	// brightness = 0.301 * red + 0.586 * green + 0.113 * blue
256 	// we use for performance reasons:
257 	// brightness = (308 * red + 600 * green + 116 * blue) / 1024
258 	return uint8((308 * red + 600 * green + 116 * blue) / 1024);
259 }
260 
261 
262 /*!	\brief Returns the "distance" between two RGB colors.
263 
264 	This functions defines an metric on the RGB color space. The distance
265 	between two colors is 0, if and only if the colors are equal.
266 
267 	\param red1 Red component of the first color.
268 	\param green1 Green component of the first color.
269 	\param blue1 Blue component of the first color.
270 	\param red2 Red component of the second color.
271 	\param green2 Green component of the second color.
272 	\param blue2 Blue component of the second color.
273 	\return The distance between the given colors.
274 */
275 static inline unsigned
276 color_distance(uint8 red1, uint8 green1, uint8 blue1, uint8 red2, uint8 green2,
277 	uint8 blue2)
278 {
279 	// euklidian distance (its square actually)
280 	int rd = (int)red1 - (int)red2;
281 	int gd = (int)green1 - (int)green2;
282 	int bd = (int)blue1 - (int)blue2;
283 //	return rd * rd + gd * gd + bd * bd;
284 
285 	// distance according to psycho-visual tests
286 	int rmean = ((int)red1 + (int)red2) / 2;
287 	return (((512 + rmean) * rd * rd) >> 8) + 4 * gd * gd
288 		+ (((767 - rmean) * bd * bd) >> 8);
289 }
290 
291 
292 static inline int32
293 bit_mask(int32 bit)
294 {
295 	return 1 << bit;
296 }
297 
298 
299 static inline int32
300 inverse_bit_mask(int32 bit)
301 {
302 	return ~bit_mask(bit);
303 }
304 
305 
306 //	#pragma mark - PaletteConverter
307 
308 
309 namespace BPrivate {
310 
311 /*!	\brief Helper class for conversion between RGB and palette colors.
312 */
313 class PaletteConverter {
314 public:
315 	PaletteConverter();
316 	PaletteConverter(const rgb_color *palette);
317 	PaletteConverter(const color_map *colorMap);
318 	~PaletteConverter();
319 
320 	status_t SetTo(const rgb_color *palette);
321 	status_t SetTo(const color_map *colorMap);
322 	status_t InitCheck() const;
323 
324 	inline uint8 IndexForRGB15(uint16 rgb) const;
325 	inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const;
326 	inline uint8 IndexForRGB16(uint16 rgb) const;
327 	inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const;
328 	inline uint8 IndexForRGB24(uint32 rgb) const;
329 	inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const;
330 	inline uint8 IndexForGray(uint8 gray) const;
331 
332 	inline const rgb_color &RGBColorForIndex(uint8 index) const;
333 	inline uint16 RGB15ColorForIndex(uint8 index) const;
334 	inline uint16 RGB16ColorForIndex(uint8 index) const;
335 	inline uint32 RGB24ColorForIndex(uint8 index) const;
336 	inline void RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
337 		uint8 &blue, uint8 &alpha) const;
338 	inline uint8 GrayColorForIndex(uint8 index) const;
339 
340 private:
341 	const color_map	*fColorMap;
342 	color_map		*fOwnColorMap;
343 	status_t		fCStatus;
344 };
345 
346 }	// namespace BPrivate
347 
348 using BPrivate::PaletteConverter;
349 using namespace std;
350 
351 
352 /*!	\brief Creates an uninitialized PaletteConverter.
353 */
354 PaletteConverter::PaletteConverter()
355 	: fColorMap(NULL),
356 	  fOwnColorMap(NULL),
357 	  fCStatus(B_NO_INIT)
358 {
359 }
360 
361 
362 /*!	\brief Creates a PaletteConverter and initializes it to the supplied
363 		   palette.
364 	\param palette The palette being a 256 entry rgb_color array.
365 */
366 PaletteConverter::PaletteConverter(const rgb_color *palette)
367 	: fColorMap(NULL),
368 	  fOwnColorMap(NULL),
369 	  fCStatus(B_NO_INIT)
370 {
371 	SetTo(palette);
372 }
373 
374 
375 /*!	\brief Creates a PaletteConverter and initializes it to the supplied
376 		   color map.
377 	\param colorMap The completely initialized color map.
378 */
379 PaletteConverter::PaletteConverter(const color_map *colorMap)
380 	: fColorMap(NULL),
381 	  fOwnColorMap(NULL),
382 	  fCStatus(B_NO_INIT)
383 {
384 	SetTo(colorMap);
385 }
386 
387 
388 /*!	\brief Frees all resources associated with this object.
389 */
390 PaletteConverter::~PaletteConverter()
391 {
392 	delete fOwnColorMap;
393 }
394 
395 
396 /*!	\brief Initializes the converter to the supplied palette.
397 	\param palette The palette being a 256 entry rgb_color array.
398 	\return \c B_OK, if everything went fine, an error code otherwise.
399 */
400 status_t
401 PaletteConverter::SetTo(const rgb_color *palette)
402 {
403 	// cleanup
404 	SetTo((const color_map*)NULL);
405 	status_t error = (palette ? B_OK : B_BAD_VALUE);
406 	// alloc color map
407 	if (error == B_OK) {
408 		fOwnColorMap = new(nothrow) color_map;
409 		if (fOwnColorMap == NULL)
410 			error = B_NO_MEMORY;
411 	}
412 	// init color map
413 	if (error == B_OK) {
414 		fColorMap = fOwnColorMap;
415 		// init color list
416 		memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256);
417 		// init index map
418 		for (int32 color = 0; color < 32768; color++) {
419 			// get components
420 			uint8 red = (color & 0x7c00) >> 7;
421 			uint8 green = (color & 0x3e0) >> 2;
422 			uint8 blue = (color & 0x1f) << 3;
423 			red |= red >> 5;
424 			green |= green >> 5;
425 			blue |= blue >> 5;
426 			// find closest color
427 			uint8 closestIndex = 0;
428 			unsigned closestDistance = UINT_MAX;
429 			for (int32 i = 0; i < 256; i++) {
430 				const rgb_color &c = fOwnColorMap->color_list[i];
431 				unsigned distance = color_distance(red, green, blue,
432 												   c.red, c.green, c.blue);
433 				if (distance < closestDistance) {
434 					closestIndex = i;
435 					closestDistance = distance;
436 				}
437 			}
438 			fOwnColorMap->index_map[color] = closestIndex;
439 		}
440 		// no need to init inversion map
441 	}
442 	fCStatus = error;
443 	return error;
444 }
445 
446 
447 /*!	\brief Initializes the converter to the supplied color map.
448 	\param colorMap The completely initialized color map.
449 	\return \c B_OK, if everything went fine, an error code otherwise.
450 */
451 status_t
452 PaletteConverter::SetTo(const color_map *colorMap)
453 {
454 	// cleanup
455 	if (fOwnColorMap) {
456 		delete fOwnColorMap;
457 		fOwnColorMap = NULL;
458 	}
459 	// set
460 	fColorMap = colorMap;
461 	fCStatus = fColorMap ? B_OK : B_BAD_VALUE;
462 	return fCStatus;
463 }
464 
465 
466 /*!	\brief Returns the result of the last initialization via constructor or
467 		   SetTo().
468 	\return \c B_OK, if the converter is properly initialized, an error code
469 			otherwise.
470 */
471 status_t
472 PaletteConverter::InitCheck() const
473 {
474 	return fCStatus;
475 }
476 
477 
478 /*!	\brief Returns the palette color index closest to a given RGB 15 color.
479 
480 	The object must be properly initialized.
481 
482 	\param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]).
483 	\return The palette color index for the supplied color.
484 */
485 inline uint8
486 PaletteConverter::IndexForRGB15(uint16 rgb) const
487 {
488 	return fColorMap->index_map[rgb];
489 }
490 
491 
492 /*!	\brief Returns the palette color index closest to a given RGB 15 color.
493 
494 	The object must be properly initialized.
495 
496 	\param red Red component of the color (R[4:0]).
497 	\param green Green component of the color (G[4:0]).
498 	\param blue Blue component of the color (B[4:0]).
499 	\return The palette color index for the supplied color.
500 */
501 inline uint8
502 PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const
503 {
504 	// the 5 least significant bits are used
505 	return fColorMap->index_map[(red << 10) | (green << 5) | blue];
506 }
507 
508 
509 /*!	\brief Returns the palette color index closest to a given RGB 16 color.
510 
511 	The object must be properly initialized.
512 
513 	\param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]).
514 	\return The palette color index for the supplied color.
515 */
516 inline uint8
517 PaletteConverter::IndexForRGB16(uint16 rgb) const
518 {
519 	return fColorMap->index_map[((rgb >> 1) & 0x7fe0) | (rgb & 0x1f)];
520 }
521 
522 
523 /*!	\brief Returns the palette color index closest to a given RGB 16 color.
524 
525 	The object must be properly initialized.
526 
527 	\param red Red component of the color (R[4:0]).
528 	\param green Green component of the color (G[5:0]).
529 	\param blue Blue component of the color (B[4:0]).
530 	\return The palette color index for the supplied color.
531 */
532 inline uint8
533 PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const
534 {
535 	// the 5 (for red, blue) / 6 (for green) least significant bits are used
536 	return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue];
537 }
538 
539 
540 /*!	\brief Returns the palette color index closest to a given RGB 32 color.
541 
542 	The object must be properly initialized.
543 
544 	\param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]).
545 	\return The palette color index for the supplied color.
546 */
547 inline uint8
548 PaletteConverter::IndexForRGB24(uint32 rgb) const
549 {
550 	return fColorMap->index_map[((rgb & 0xf8000000) >> 17)
551 		| ((rgb & 0xf80000) >> 14) | ((rgb & 0xf800) >> 11)];
552 }
553 
554 
555 /*!	\brief Returns the palette color index closest to a given RGB 24 color.
556 
557 	The object must be properly initialized.
558 
559 	\param red Red component of the color.
560 	\param green Green component of the color.
561 	\param blue Blue component of the color.
562 	\return The palette color index for the supplied color.
563 */
564 inline uint8
565 PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const
566 {
567 	return fColorMap->index_map[((red & 0xf8) << 7) | ((green & 0xf8) << 2)
568 		| (blue >> 3)];
569 }
570 
571 
572 /*!	\brief Returns the palette color index closest to a given Gray 8 color.
573 
574 	The object must be properly initialized.
575 
576 	\param gray The Gray 8 color value.
577 	\return The palette color index for the supplied color.
578 */
579 inline uint8
580 PaletteConverter::IndexForGray(uint8 gray) const
581 {
582 	return IndexForRGB24(gray, gray, gray);
583 }
584 
585 
586 /*!	\brief Returns the RGB color for a given palette color index.
587 
588 	The object must be properly initialized.
589 
590 	\param index The palette color index.
591 	\return The color for the supplied palette color index.
592 */
593 inline const rgb_color &
594 PaletteConverter::RGBColorForIndex(uint8 index) const
595 {
596 	return fColorMap->color_list[index];
597 }
598 
599 
600 /*!	\brief Returns the RGB 15 color for a given palette color index.
601 
602 	The object must be properly initialized.
603 
604 	\param index The palette color index.
605 	\return The color for the supplied palette color index
606 			(R[14:10]G[9:5]B[4:0]).
607 */
608 inline uint16
609 PaletteConverter::RGB15ColorForIndex(uint8 index) const
610 {
611 	const rgb_color &color = fColorMap->color_list[index];
612 	return ((color.red & 0xf8) << 7) | ((color.green & 0xf8) << 2)
613 		| (color.blue >> 3);
614 }
615 
616 
617 /*!	\brief Returns the RGB 16 color for a given palette color index.
618 
619 	The object must be properly initialized.
620 
621 	\param index The palette color index.
622 	\return The color for the supplied palette color index
623 			(R[15:11]G[10:5]B[4:0]).
624 */
625 inline uint16
626 PaletteConverter::RGB16ColorForIndex(uint8 index) const
627 {
628 	const rgb_color &color = fColorMap->color_list[index];
629 	return ((color.red & 0xf8) << 8) | ((color.green & 0xfc) << 3)
630 		| (color.blue >> 3);
631 }
632 
633 
634 /*!	\brief Returns the RGB 24 color for a given palette color index.
635 
636 	The object must be properly initialized.
637 
638 	\param index The palette color index.
639 	\return The color for the supplied palette color index
640 			(R[31:24]G[23:16]B[15:8]).
641 */
642 inline uint32
643 PaletteConverter::RGB24ColorForIndex(uint8 index) const
644 {
645 	const rgb_color &color = fColorMap->color_list[index];
646 	return (color.blue << 24) | (color.red << 8) | (color.green << 16)
647 		| color.alpha;
648 }
649 
650 
651 /*!	\brief Returns the RGB 24 color for a given palette color index.
652 
653 	The object must be properly initialized.
654 
655 	\param index The palette color index.
656 	\param red Reference to the variable the red component shall be stored
657 		   into.
658 	\param green Reference to the variable the green component shall be stored
659 		   into.
660 	\param blue Reference to the variable the blue component shall be stored
661 		   into.
662 */
663 inline void
664 PaletteConverter::RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
665 	uint8 &blue, uint8 &alpha) const
666 {
667 	const rgb_color &color = fColorMap->color_list[index];
668 	red = color.red;
669 	green = color.green;
670 	blue = color.blue;
671 	alpha = color.alpha;
672 }
673 
674 
675 /*!	\brief Returns the Gray 8 color for a given palette color index.
676 
677 	The object must be properly initialized.
678 
679 	\param index The palette color index.
680 	\return The color for the supplied palette color index.
681 */
682 inline uint8
683 PaletteConverter::GrayColorForIndex(uint8 index) const
684 {
685 	const rgb_color &color = fColorMap->color_list[index];
686 	return brightness_for(color.red, color.green, color.blue);
687 }
688 
689 // TODO: Remove these and palette_converter() when BScreen is available.
690 static BLocker gPaletteConverterLock;
691 static PaletteConverter	gPaletteConverter;
692 
693 
694 /*!	\brief Returns a PaletteConverter using the system color palette.
695 	\return A PaletteConverter.
696 */
697 static const PaletteConverter*
698 palette_converter()
699 {
700 	if (gPaletteConverterLock.Lock()) {
701 		if (gPaletteConverter.InitCheck() != B_OK)
702 			gPaletteConverter.SetTo(kSystemPalette);
703 		gPaletteConverterLock.Unlock();
704 	}
705 	return &gPaletteConverter;
706 }
707 
708 
709 //	#pragma mark - Reader classes
710 
711 
712 // BaseReader
713 template<typename _PixelType>
714 struct BaseReader {
715 	typedef _PixelType		pixel_t;
716 
717 	BaseReader(const void *data) : pixels((const pixel_t*)data) {}
718 
719 	inline void SetTo(const void *data) { pixels = (const pixel_t*)data; }
720 
721 	inline void NextRow(int32 skip)
722 	{
723 		pixels = (const pixel_t*)((const char*)pixels + skip);
724 	}
725 
726 	const pixel_t *pixels;
727 };
728 
729 // RGB24Reader
730 template<typename _PixelType>
731 struct RGB24Reader : public BaseReader<_PixelType> {
732 	typedef rgb_color_value	preferred_color_value_t;
733 	typedef _PixelType		pixel_t;
734 
735 	RGB24Reader(const void *data) : BaseReader<_PixelType>(data) {}
736 
737 	inline void Read(rgb_color_value &color)
738 	{
739 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
740 		color.red = pixel.red;
741 		color.green = pixel.green;
742 		color.blue = pixel.blue;
743 		color.alpha = 255;
744 		BaseReader<_PixelType>::pixels++;
745 	}
746 
747 	inline void Read(gray_color_value &gray)
748 	{
749 		rgb_color_value color;
750 		Read(color);
751 		gray = brightness_for(color.red, color.green, color.blue);
752 	}
753 };
754 
755 // RGB16Reader
756 template<typename _PixelType>
757 struct RGB16Reader : public BaseReader<_PixelType> {
758 	typedef rgb_color_value	preferred_color_value_t;
759 	typedef _PixelType		pixel_t;
760 
761 	RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {}
762 
763 	inline void Read(rgb_color_value &color)
764 	{
765 		// rg: R[4:0],G[5:3]
766 		// gb: G[2:0],B[4:0]
767 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
768 		color.red = pixel.rg & 0xf8;
769 		color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3);
770 		color.blue = (pixel.gb & 0x1f) << 3;
771 		color.red |= color.red >> 5;
772 		color.green |= color.green >> 6;
773 		color.blue |= color.blue >> 5;
774 		color.alpha = 255;
775 		BaseReader<_PixelType>::pixels++;
776 	}
777 
778 	inline void Read(gray_color_value &gray)
779 	{
780 		rgb_color_value color;
781 		Read(color);
782 		gray = brightness_for(color.red, color.green, color.blue);
783 	}
784 };
785 
786 // RGB15Reader
787 template<typename _PixelType>
788 struct RGB15Reader : public BaseReader<_PixelType> {
789 	typedef rgb_color_value	preferred_color_value_t;
790 	typedef _PixelType		pixel_t;
791 
792 	RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {}
793 
794 	inline void Read(rgb_color_value &color)
795 	{
796 		// rg: -[0],R[4:0],G[4:3]
797 		// gb: G[2:0],B[4:0]
798 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
799 		color.red = (pixel.rg & 0x7c) << 1;
800 		color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2);
801 		color.blue = (pixel.gb & 0x1f) << 3;
802 		color.red |= color.red >> 5;
803 		color.green |= color.green >> 5;
804 		color.blue |= color.blue >> 5;
805 		color.alpha = 255;
806 		BaseReader<_PixelType>::pixels++;
807 	}
808 
809 	inline void Read(gray_color_value &gray)
810 	{
811 		rgb_color_value color;
812 		Read(color);
813 		gray = brightness_for(color.red, color.green, color.blue);
814 	}
815 };
816 
817 // CMAP8Reader
818 struct CMAP8Reader : public BaseReader<uint8> {
819 	typedef rgb_color_value	preferred_color_value_t;
820 
821 	CMAP8Reader(const void *data, const PaletteConverter &converter)
822 		: BaseReader<uint8>(data), converter(converter) {}
823 
824 	inline void Read(rgb_color_value &color)
825 	{
826 		converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green,
827 									 color.blue, color.alpha);
828 		BaseReader<uint8>::pixels++;
829 	}
830 
831 	inline void Read(gray_color_value &gray)
832 	{
833 		gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels);
834 		BaseReader<uint8>::pixels++;
835 	}
836 
837 	const PaletteConverter &converter;
838 };
839 
840 // Gray8Reader
841 struct Gray8Reader : public BaseReader<uint8> {
842 	typedef gray_color_value	preferred_color_value_t;
843 
844 	Gray8Reader(const void *data) : BaseReader<uint8>(data) {}
845 
846 	inline void Read(rgb_color_value &color)
847 	{
848 		color.red = color.green = color.blue = *BaseReader<uint8>::pixels;
849 		color.alpha = 255;
850 		BaseReader<uint8>::pixels++;
851 	}
852 
853 	inline void Read(gray_color_value &gray)
854 	{
855 		gray = *BaseReader<uint8>::pixels;
856 		BaseReader<uint8>::pixels++;
857 	}
858 };
859 
860 // Gray1Reader
861 struct Gray1Reader : public BaseReader<uint8> {
862 	typedef gray_color_value	preferred_color_value_t;
863 
864 	Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {}
865 
866 	inline void SetTo(const void *data)
867 	{
868 		pixels = (const pixel_t*)data;
869 		bit = 7;
870 	}
871 
872 	inline void NextRow(int32 skip)
873 	{
874 		if (bit == 7)
875 			pixels = (const pixel_t*)((const char*)pixels + skip);
876 		else {
877 			pixels = (const pixel_t*)((const char*)pixels + skip + 1);
878 			bit = 7;
879 		}
880 	}
881 
882 	inline void Read(rgb_color_value &color)
883 	{
884 		if (*pixels & bit_mask(bit))
885 			color.red = color.green = color.blue = 255;
886 		else
887 			color.red = color.green = color.blue = 0;
888 		color.alpha = 255;
889 		bit--;
890 		if (bit == -1) {
891 			pixels++;
892 			bit = 7;
893 		}
894 	}
895 
896 	inline void Read(gray_color_value &gray)
897 	{
898 		if (*pixels & bit_mask(bit))
899 			gray = 255;
900 		else
901 			gray = 0;
902 		bit--;
903 		if (bit == -1) {
904 			pixels++;
905 			bit = 7;
906 		}
907 	}
908 
909 	int32 bit;
910 };
911 
912 
913 //	#pragma mark - Writer classes
914 
915 
916 // BaseWriter
917 template<typename _PixelType>
918 struct BaseWriter {
919 	typedef _PixelType		pixel_t;
920 
921 	BaseWriter(void *data) : pixels((pixel_t*)data) {}
922 
923 	inline void SetTo(void *data) { pixels = (pixel_t*)data; }
924 
925 	pixel_t *pixels;
926 };
927 
928 
929 // RGB32Writer
930 template<typename _PixelType>
931 struct RGB32Writer : public BaseWriter<_PixelType> {
932 	typedef rgb_color_value	preferred_color_value_t;
933 	typedef _PixelType		pixel_t;
934 
935 	RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {}
936 
937 	inline void Write(const rgb_color_value &color)
938 	{
939 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
940 		pixel.red = color.red;
941 		pixel.green = color.green;
942 		pixel.blue = color.blue;
943 		pixel.alpha = color.alpha;
944 		BaseWriter<_PixelType>::pixels++;
945 	}
946 
947 	inline void Write(const gray_color_value &gray)
948 	{
949 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
950 		pixel.red = gray;
951 		pixel.green = gray;
952 		pixel.blue = gray;
953 		pixel.alpha = 255;
954 		BaseWriter<_PixelType>::pixels++;
955 	}
956 };
957 
958 // RGB24Writer
959 template<typename _PixelType>
960 struct RGB24Writer : public BaseWriter<_PixelType> {
961 	typedef rgb_color_value	preferred_color_value_t;
962 	typedef _PixelType		pixel_t;
963 
964 	RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {}
965 
966 	inline void Write(const rgb_color_value &color)
967 	{
968 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
969 		pixel.red = color.red;
970 		pixel.green = color.green;
971 		pixel.blue = color.blue;
972 		BaseWriter<_PixelType>::pixels++;
973 	}
974 
975 	inline void Write(const gray_color_value &gray)
976 	{
977 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
978 		pixel.red = gray;
979 		pixel.green = gray;
980 		pixel.blue = gray;
981 		BaseWriter<_PixelType>::pixels++;
982 	}
983 };
984 
985 // RGB16Writer
986 template<typename _PixelType>
987 struct RGB16Writer : public BaseWriter<_PixelType> {
988 	typedef rgb_color_value	preferred_color_value_t;
989 	typedef _PixelType		pixel_t;
990 
991 	RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {}
992 
993 	inline void Write(const rgb_color_value &color)
994 	{
995 		// rg: R[4:0],G[5:3]
996 		// gb: G[2:0],B[4:0]
997 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
998 		pixel.rg = (color.red & 0xf8) | (color.green >> 5);
999 		pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3);
1000 		BaseWriter<_PixelType>::pixels++;
1001 	}
1002 
1003 	inline void Write(const gray_color_value &gray)
1004 	{
1005 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1006 		pixel.rg = (gray & 0xf8) | (gray >> 5);
1007 		pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3);
1008 		BaseWriter<_PixelType>::pixels++;
1009 	}
1010 };
1011 
1012 // RGB15Writer
1013 template<typename _PixelType>
1014 struct RGB15Writer : public BaseWriter<_PixelType> {
1015 	typedef rgb_color_value	preferred_color_value_t;
1016 	typedef _PixelType		pixel_t;
1017 
1018 	RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {}
1019 
1020 	inline void Write(const rgb_color_value &color)
1021 	{
1022 		// rg: -[0],R[4:0],G[4:3]
1023 		// gb: G[2:0],B[4:0]
1024 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1025 		pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6);
1026 		pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3);
1027 		BaseWriter<_PixelType>::pixels++;
1028 	}
1029 
1030 	inline void Write(const gray_color_value &gray)
1031 	{
1032 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1033 		pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6);
1034 		pixel.gb = ((gray & 0x38) << 2) | (gray >> 3);
1035 		BaseWriter<_PixelType>::pixels++;
1036 	}
1037 };
1038 
1039 // CMAP8Writer
1040 struct CMAP8Writer : public BaseWriter<uint8> {
1041 	typedef rgb_color_value	preferred_color_value_t;
1042 
1043 	CMAP8Writer(void *data, const PaletteConverter &converter)
1044 		: BaseWriter<uint8>(data), converter(converter) {}
1045 
1046 	inline void Write(const rgb_color_value &color)
1047 	{
1048 		*pixels = converter.IndexForRGB24(color.red, color.green, color.blue);
1049 		pixels++;
1050 	}
1051 
1052 	inline void Write(const gray_color_value &gray)
1053 	{
1054 		*pixels = converter.IndexForGray(gray);
1055 		pixels++;
1056 	}
1057 
1058 	const PaletteConverter &converter;
1059 };
1060 
1061 // Gray8Writer
1062 struct Gray8Writer : public BaseWriter<uint8> {
1063 	typedef gray_color_value	preferred_color_value_t;
1064 
1065 	Gray8Writer(void *data) : BaseWriter<uint8>(data) {}
1066 
1067 	inline void Write(const rgb_color_value &color)
1068 	{
1069 		*pixels = brightness_for(color.red, color.green, color.blue);
1070 		pixels++;
1071 	}
1072 
1073 	inline void Write(const gray_color_value &gray)
1074 	{
1075 		*pixels = gray;
1076 		pixels++;
1077 	}
1078 };
1079 
1080 // Gray1Writer
1081 struct Gray1Writer : public BaseWriter<uint8> {
1082 	typedef gray_color_value	preferred_color_value_t;
1083 
1084 	Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {}
1085 
1086 	inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; }
1087 
1088 	inline void Write(const gray_color_value &gray)
1089 	{
1090 		*pixels = (*pixels & inverse_bit_mask(bit))
1091 				  | (gray & 0x80) >> (7 - bit);
1092 		bit--;
1093 		if (bit == -1) {
1094 			pixels++;
1095 			bit = 7;
1096 		}
1097 	}
1098 
1099 	inline void Write(const rgb_color_value &color)
1100 	{
1101 		Write(brightness_for(color.red, color.green, color.blue));
1102 	}
1103 
1104 	int32 bit;
1105 };
1106 
1107 
1108 // set_bits_worker
1109 /*!	\brief Worker function that reads bitmap data from one buffer and writes
1110 		   it (converted) to another one.
1111 	\param Reader The pixel reader class.
1112 	\param Writer The pixel writer class.
1113 	\param color_value_t The color value type used to transport a pixel from
1114 		   the reader to the writer.
1115 	\param inData A pointer to the buffer to be read.
1116 	\param inLength The length (in bytes) of the "in" buffer.
1117 	\param inBPR The number of bytes per row in the "in" buffer.
1118 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1119 		   padding.
1120 	\param outData A pointer to the buffer to be written to.
1121 	\param outLength The length (in bytes) of the "out" buffer.
1122 	\param outOffset The offset (in bytes) relative to \a outData from which
1123 		   the function shall start writing.
1124 	\param outBPR The number of bytes per row in the "out" buffer.
1125 	\param rawOutBPR The number of bytes per row in the "out" buffer actually
1126 		   containing bitmap data (i.e. not including the padding).
1127 	\param _reader A reader object. The pointer to the data doesn't need to
1128 		   be initialized.
1129 	\param _writer A writer object. The pointer to the data doesn't need to
1130 		   be initialized.
1131 	\return \c B_OK, if everything went fine, an error code otherwise.
1132 */
1133 template<typename Reader, typename Writer, typename color_value_t>
1134 static
1135 status_t
1136 set_bits_worker(const void *inData, int32 inLength, int32 inBPR,
1137 				int32 inRowSkip, void *outData, int32 outLength,
1138 				int32 outOffset, int32 outBPR, int32 rawOutBPR,
1139 				Reader _reader, Writer _writer)
1140 {
1141 	status_t error = B_OK;
1142 	Reader reader(_reader);
1143 	Writer writer(_writer);
1144 	reader.SetTo(inData);
1145 	writer.SetTo((char*)outData + outOffset);
1146 	const char *inEnd = (const char*)inData + inLength
1147 						- sizeof(typename Reader::pixel_t);
1148 	const char *inLastRow = (const char*)inData + inLength
1149 							- (inBPR - inRowSkip);
1150 	const char *outEnd = (const char*)outData + outLength
1151 						 - sizeof(typename Writer::pixel_t);
1152 	char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1153 	const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t);
1154 	while ((const char*)reader.pixels <= inEnd
1155 		   && (const char*)writer.pixels <= outEnd) {
1156 		// process one row
1157 		if ((const char*)reader.pixels <= inLastRow) {
1158 			// at least a complete row left
1159 			while ((const char*)writer.pixels <= outRowEnd) {
1160 				color_value_t color;
1161 				reader.Read(color);
1162 				writer.Write(color);
1163 			}
1164 		} else {
1165 			// no complete row left
1166 			// but maybe the complete end of the first row
1167 			while ((const char*)reader.pixels <= inEnd
1168 				   && (const char*)writer.pixels <= outRowEnd) {
1169 				color_value_t color;
1170 				reader.Read(color);
1171 				writer.Write(color);
1172 			}
1173 		}
1174 		// must be here, not in the if-branch (end of first row)
1175 		outRow += outBPR;
1176 		outRowEnd += outBPR;
1177 		reader.NextRow(inRowSkip);
1178 		writer.SetTo(outRow);
1179 	}
1180 	return error;
1181 }
1182 
1183 // set_bits_worker_gray1
1184 /*!	\brief Worker function that reads bitmap data from one buffer and writes
1185 		   it (converted) to another one, which uses color space \c B_GRAY1.
1186 	\param Reader The pixel reader class.
1187 	\param Writer The pixel writer class.
1188 	\param color_value_t The color value type used to transport a pixel from
1189 		   the reader to the writer.
1190 	\param inData A pointer to the buffer to be read.
1191 	\param inLength The length (in bytes) of the "in" buffer.
1192 	\param inBPR The number of bytes per row in the "in" buffer.
1193 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1194 		   padding.
1195 	\param outData A pointer to the buffer to be written to.
1196 	\param outLength The length (in bytes) of the "out" buffer.
1197 	\param outOffset The offset (in bytes) relative to \a outData from which
1198 		   the function shall start writing.
1199 	\param outBPR The number of bytes per row in the "out" buffer.
1200 	\param width The number of pixels per row in "in" and "out" data.
1201 	\param _reader A reader object. The pointer to the data doesn't need to
1202 		   be initialized.
1203 	\param _writer A writer object. The pointer to the data doesn't need to
1204 		   be initialized.
1205 	\return \c B_OK, if everything went fine, an error code otherwise.
1206 */
1207 template<typename Reader, typename Writer, typename color_value_t>
1208 static
1209 status_t
1210 set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR,
1211 					  int32 inRowSkip, void *outData, int32 outLength,
1212 					  int32 outOffset, int32 outBPR, int32 width,
1213 					  Reader _reader, Writer _writer)
1214 {
1215 	status_t error = B_OK;
1216 	Reader reader(_reader);
1217 	Writer writer(_writer);
1218 	reader.SetTo(inData);
1219 	writer.SetTo((char*)outData + outOffset);
1220 	const char *inEnd = (const char*)inData + inLength
1221 						- sizeof(typename Reader::pixel_t);
1222 	const char *inLastRow = (const char*)inData + inLength
1223 							- (inBPR - inRowSkip);
1224 	const char *outEnd = (const char*)outData + outLength - outBPR;
1225 	char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1226 	int32 x = max((int32)0,
1227 		width - (int32)((char*)outData + outOffset - outRow) * 8) - 1;
1228 	while ((const char*)reader.pixels <= inEnd
1229 		   && (const char*)writer.pixels <= outEnd) {
1230 		// process one row
1231 		if ((const char*)reader.pixels <= inLastRow) {
1232 			// at least a complete row left
1233 			while (x >= 0) {
1234 				color_value_t color;
1235 				reader.Read(color);
1236 				writer.Write(color);
1237 				x--;
1238 			}
1239 		} else {
1240 			// no complete row left
1241 			// but maybe the complete end of the first row
1242 			while ((const char*)reader.pixels <= inEnd && x >= 0) {
1243 				color_value_t color;
1244 				reader.Read(color);
1245 				writer.Write(color);
1246 				x--;
1247 			}
1248 		}
1249 		// must be here, not in the if-branch (end of first row)
1250 		x = width - 1;
1251 		outRow += outBPR;
1252 		reader.NextRow(inRowSkip);
1253 		writer.SetTo(outRow);
1254 	}
1255 	return error;
1256 }
1257 
1258 // set_bits
1259 /*!	\brief Helper function that reads bitmap data from one buffer and writes
1260 		   it (converted) to another one.
1261 	\param Reader The pixel reader class.
1262 	\param inData A pointer to the buffer to be read.
1263 	\param inLength The length (in bytes) of the "in" buffer.
1264 	\param inBPR The number of bytes per row in the "in" buffer.
1265 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1266 		   padding.
1267 	\param outData A pointer to the buffer to be written to.
1268 	\param outLength The length (in bytes) of the "out" buffer.
1269 	\param outOffset The offset (in bytes) relative to \a outData from which
1270 		   the function shall start writing.
1271 	\param outBPR The number of bytes per row in the "out" buffer.
1272 	\param rawOutBPR The number of bytes per row in the "out" buffer actually
1273 		   containing bitmap data (i.e. not including the padding).
1274 	\param outColorSpace Color space of the target buffer.
1275 	\param width The number of pixels per row in "in" and "out" data.
1276 	\param reader A reader object. The pointer to the data doesn't need to
1277 		   be initialized.
1278 	\param paletteConverter Reference to a PaletteConverter to be used, if
1279 		   a conversion from or to \c B_CMAP8 has to be done.
1280 	\return \c B_OK, if everything went fine, an error code otherwise.
1281 */
1282 template<typename Reader>
1283 static
1284 status_t
1285 set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip,
1286 		 void *outData, int32 outLength, int32 outOffset, int32 outBPR,
1287 		 int32 rawOutBPR, color_space outColorSpace, int32 width,
1288 		 Reader reader, const PaletteConverter &paletteConverter)
1289 {
1290 	status_t error = B_OK;
1291 	switch (outColorSpace) {
1292 		// supported
1293 		case B_RGB32: case B_RGBA32:
1294 		{
1295 			typedef RGB32Writer<rgb32_pixel> Writer;
1296 			typedef typename Reader::preferred_color_value_t color_value_t;
1297 			error = set_bits_worker<Reader, Writer, color_value_t>(
1298 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1299 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1300 			break;
1301 		}
1302 		case B_RGB32_BIG: case B_RGBA32_BIG:
1303 		{
1304 			typedef RGB32Writer<rgb32_big_pixel> Writer;
1305 			typedef typename Reader::preferred_color_value_t color_value_t;
1306 			error = set_bits_worker<Reader, Writer, color_value_t>(
1307 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1308 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1309 			break;
1310 		}
1311 		case B_RGB24:
1312 		{
1313 			typedef RGB24Writer<rgb24_pixel> Writer;
1314 			typedef typename Reader::preferred_color_value_t color_value_t;
1315 			error = set_bits_worker<Reader, Writer, color_value_t>(
1316 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1317 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1318 			break;
1319 		}
1320 		case B_RGB24_BIG:
1321 		{
1322 			typedef RGB24Writer<rgb24_big_pixel> Writer;
1323 			typedef typename Reader::preferred_color_value_t color_value_t;
1324 			error = set_bits_worker<Reader, Writer, color_value_t>(
1325 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1326 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1327 			break;
1328 		}
1329 		case B_RGB16:
1330 		{
1331 			typedef RGB16Writer<rgb16_pixel> Writer;
1332 			typedef typename Reader::preferred_color_value_t color_value_t;
1333 			error = set_bits_worker<Reader, Writer, color_value_t>(
1334 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1335 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1336 			break;
1337 		}
1338 		case B_RGB16_BIG:
1339 		{
1340 			typedef RGB16Writer<rgb16_big_pixel> Writer;
1341 			typedef typename Reader::preferred_color_value_t color_value_t;
1342 			error = set_bits_worker<Reader, Writer, color_value_t>(
1343 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1344 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1345 			break;
1346 		}
1347 		case B_RGB15: case B_RGBA15:
1348 		{
1349 			typedef RGB15Writer<rgb16_pixel> Writer;
1350 			typedef typename Reader::preferred_color_value_t color_value_t;
1351 			error = set_bits_worker<Reader, Writer, color_value_t>(
1352 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1353 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1354 			break;
1355 		}
1356 		case B_RGB15_BIG: case B_RGBA15_BIG:
1357 		{
1358 			typedef RGB15Writer<rgb16_big_pixel> Writer;
1359 			typedef typename Reader::preferred_color_value_t color_value_t;
1360 			error = set_bits_worker<Reader, Writer, color_value_t>(
1361 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1362 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1363 			break;
1364 		}
1365 		case B_CMAP8:
1366 		{
1367 			typedef CMAP8Writer Writer;
1368 			typedef typename Reader::preferred_color_value_t color_value_t;
1369 			error = set_bits_worker<Reader, Writer, color_value_t>(
1370 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1371 				outOffset, outBPR, rawOutBPR, reader,
1372 				Writer(outData, paletteConverter));
1373 			break;
1374 		}
1375 		case B_GRAY8:
1376 		{
1377 			typedef Gray8Writer Writer;
1378 			typedef gray_color_value color_value_t;
1379 			error = set_bits_worker<Reader, Writer, color_value_t>(
1380 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1381 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1382 			break;
1383 		}
1384 		case B_GRAY1:
1385 		{
1386 			typedef Gray1Writer Writer;
1387 			typedef gray_color_value color_value_t;
1388 			error = set_bits_worker_gray1<Reader, Writer, color_value_t>(
1389 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1390 				outOffset, outBPR, width, reader, Writer(outData));
1391 			break;
1392 		}
1393 		// unsupported
1394 		case B_NO_COLOR_SPACE:
1395 		case B_YUV9: case B_YUV12:
1396 		case B_UVL32: case B_UVLA32:
1397 		case B_LAB32: case B_LABA32:
1398 		case B_HSI32: case B_HSIA32:
1399 		case B_HSV32: case B_HSVA32:
1400 		case B_HLS32: case B_HLSA32:
1401 		case B_CMY32: case B_CMYA32: case B_CMYK32:
1402 		case B_UVL24: case B_LAB24: case B_HSI24:
1403 		case B_HSV24: case B_HLS24: case B_CMY24:
1404 		case B_YCbCr422: case B_YUV422:
1405 		case B_YCbCr411: case B_YUV411:
1406 		case B_YCbCr444: case B_YUV444:
1407 		case B_YCbCr420: case B_YUV420:
1408 		default:
1409 			error = B_BAD_VALUE;
1410 			break;
1411 	}
1412 	return error;
1413 }
1414 
1415 
1416 //	#pragma mark - Bitmap
1417 
1418 
1419 /*!	\brief Creates and initializes a BBitmap.
1420 	\param bounds The bitmap dimensions.
1421 	\param flags Creation flags.
1422 	\param colorSpace The bitmap's color space.
1423 	\param bytesPerRow The number of bytes per row the bitmap should use.
1424 		   \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
1425 		   value.
1426 	\param screenID ???
1427 */
1428 BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace,
1429 		int32 bytesPerRow, screen_id screenID)
1430 	: fBasePtr(NULL),
1431 	  fSize(0),
1432 	  fColorSpace(B_NO_COLOR_SPACE),
1433 	  fBounds(0, 0, -1, -1),
1434 	  fBytesPerRow(0),
1435 	  fServerToken(-1),
1436 	  fToken(-1),
1437 	  fArea(-1),
1438 	  fOrigArea(-1),
1439 	  fFlags(0),
1440 	  fInitError(B_NO_INIT)
1441 {
1442 	InitObject(bounds, colorSpace, flags, bytesPerRow, screenID);
1443 }
1444 
1445 
1446 /*!	\brief Creates and initializes a BBitmap.
1447 	\param bounds The bitmap dimensions.
1448 	\param colorSpace The bitmap's color space.
1449 	\param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
1450 		   it shall be possible to attach BView to the bitmap and draw into
1451 		   it.
1452 	\param needsContiguous If \c true a physically contiguous chunk of memory
1453 		   will be allocated.
1454 */
1455 BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews,
1456 		bool needsContiguous)
1457 	: fBasePtr(NULL),
1458 	  fSize(0),
1459 	  fColorSpace(B_NO_COLOR_SPACE),
1460 	  fBounds(0, 0, -1, -1),
1461 	  fBytesPerRow(0),
1462 	  fServerToken(-1),
1463 	  fToken(-1),
1464 	  fArea(-1),
1465 	  fOrigArea(-1),
1466 	  fFlags(0),
1467 	  fInitError(B_NO_INIT)
1468 {
1469 	int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
1470 				| (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
1471 	InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW,
1472 			   B_MAIN_SCREEN_ID);
1473 
1474 }
1475 
1476 
1477 /*!	\brief Creates a BBitmap as a clone of another bitmap.
1478 	\param source The source bitmap.
1479 	\param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
1480 		   it shall be possible to attach BView to the bitmap and draw into
1481 		   it.
1482 	\param needsContiguous If \c true a physically contiguous chunk of memory
1483 		   will be allocated.
1484 */
1485 BBitmap::BBitmap(const BBitmap *source, bool acceptsViews,
1486 		bool needsContiguous)
1487 	: fBasePtr(NULL),
1488 	  fSize(0),
1489 	  fColorSpace(B_NO_COLOR_SPACE),
1490 	  fBounds(0, 0, -1, -1),
1491 	  fBytesPerRow(0),
1492 	  fServerToken(-1),
1493 	  fToken(-1),
1494 	  fArea(-1),
1495 	  fOrigArea(-1),
1496 	  fFlags(0),
1497 	  fInitError(B_NO_INIT)
1498 {
1499 	if (source && source->IsValid()) {
1500 		int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
1501 			| (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
1502 		InitObject(source->Bounds(), source->ColorSpace(), flags,
1503 			source->BytesPerRow(), B_MAIN_SCREEN_ID);
1504 		if (InitCheck() == B_OK)
1505 			memcpy(Bits(), source->Bits(), BytesPerRow());
1506 	}
1507 }
1508 
1509 
1510 /*!	\brief Frees all resources associated with this object. */
1511 BBitmap::~BBitmap()
1512 {
1513 	CleanUp();
1514 }
1515 
1516 
1517 /*!	\brief Unarchives a bitmap from a BMessage.
1518 	\param data The archive.
1519 */
1520 BBitmap::BBitmap(BMessage *data)
1521 	: BArchivable(data),
1522 	  fBasePtr(NULL),
1523 	  fSize(0),
1524 	  fColorSpace(B_NO_COLOR_SPACE),
1525 	  fBounds(0, 0, -1, -1),
1526 	  fBytesPerRow(0),
1527 	  fServerToken(-1),
1528 	  fToken(-1),
1529 	  fArea(-1),
1530 	  fOrigArea(-1),
1531 	  fFlags(0),
1532 	  fInitError(B_NO_INIT)
1533 {
1534 	BRect bounds;
1535 	data->FindRect("_frame", &bounds);
1536 
1537 	color_space cspace;
1538 	data->FindInt32("_cspace", (int32 *)&cspace);
1539 
1540 	int32 flags = 0;
1541 	data->FindInt32("_bmflags", &flags);
1542 
1543 	int32 rowbytes = 0;
1544 	data->FindInt32("_rowbytes", &rowbytes);
1545 
1546 flags |= B_BITMAP_NO_SERVER_LINK;
1547 flags &= ~B_BITMAP_ACCEPTS_VIEWS;
1548 	InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID);
1549 
1550 	if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) {
1551 			ssize_t size = 0;
1552 			const void *buffer;
1553 			if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK)
1554 				memcpy(fBasePtr, buffer, size);
1555 	}
1556 
1557 	if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
1558 // 		BArchivable *obj;
1559 // 		BMessage message;
1560 // 		int i = 0;
1561 //
1562 // 		while (data->FindMessage("_view", i++, &message) == B_OK) {
1563 // 			obj = instantiate_object(&message);
1564 // 			BView *view = dynamic_cast<BView *>(obj);
1565 //
1566 // 			if (view)
1567 // 				AddChild(view);
1568 // 		}
1569 	}
1570 }
1571 
1572 
1573 /*!	\brief Instantiates a BBitmap from an archive.
1574 	\param data The archive.
1575 	\return A bitmap reconstructed from the archive or \c NULL, if an error
1576 			occured.
1577 */
1578 BArchivable *
1579 BBitmap::Instantiate(BMessage *data)
1580 {
1581 	if (validate_instantiation(data, "BBitmap"))
1582 		return new BBitmap(data);
1583 
1584 	return NULL;
1585 }
1586 
1587 
1588 /*!	\brief Archives the BBitmap object.
1589 	\param data The archive.
1590 	\param deep \c true, if child object shall be archived as well, \c false
1591 		   otherwise.
1592 	\return \c B_OK, if everything went fine, an error code otherwise.
1593 */
1594 status_t
1595 BBitmap::Archive(BMessage *data, bool deep) const
1596 {
1597 	BArchivable::Archive(data, deep);
1598 
1599 	data->AddRect("_frame", fBounds);
1600 	data->AddInt32("_cspace", (int32)fColorSpace);
1601 	data->AddInt32("_bmflags", fFlags);
1602 	data->AddInt32("_rowbytes", fBytesPerRow);
1603 
1604 	if (deep) {
1605 		if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
1606 //			BMessage views;
1607 // 			for (int32 i = 0; i < CountChildren(); i++) {
1608 // 				if (ChildAt(i)->Archive(&views, deep))
1609 // 					data->AddMessage("_views", &views);
1610 // 			}
1611 		}
1612 		// Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is
1613 		// true and it does save all formats as B_RAW_TYPE and it does save
1614 		// the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to
1615 		// the BeBook)
1616 
1617 		data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize);
1618 	}
1619 
1620 	return B_OK;
1621 }
1622 
1623 
1624 /*!	\brief Returns the result from the construction.
1625 	\return \c B_OK, if the object is properly initialized, an error code
1626 			otherwise.
1627 */
1628 status_t
1629 BBitmap::InitCheck() const
1630 {
1631 	return fInitError;
1632 }
1633 
1634 
1635 /*!	\brief Returns whether or not the BBitmap object is valid.
1636 	\return \c true, if the object is properly initialized, \c false otherwise.
1637 */
1638 bool
1639 BBitmap::IsValid() const
1640 {
1641 	return (InitCheck() == B_OK);
1642 }
1643 
1644 
1645 status_t
1646 BBitmap::LockBits(uint32 *state)
1647 {
1648 	return B_ERROR;
1649 }
1650 
1651 
1652 void
1653 BBitmap::UnlockBits()
1654 {
1655 }
1656 
1657 
1658 /*! \brief Returns the ID of the area the bitmap data reside in.
1659 	\return The ID of the area the bitmap data reside in.
1660 */
1661 area_id
1662 BBitmap::Area() const
1663 {
1664 	return fArea;
1665 }
1666 
1667 
1668 /*!	\brief Returns the pointer to the bitmap data.
1669 	\return The pointer to the bitmap data.
1670 */
1671 void *
1672 BBitmap::Bits() const
1673 {
1674 	return fBasePtr;
1675 }
1676 
1677 
1678 /*!	\brief Returns the size of the bitmap data.
1679 	\return The size of the bitmap data.
1680 */
1681 int32
1682 BBitmap::BitsLength() const
1683 {
1684 	return fSize;
1685 }
1686 
1687 
1688 /*!	\brief Returns the number of bytes used to store a row of bitmap data.
1689 	\return The number of bytes used to store a row of bitmap data.
1690 */
1691 int32
1692 BBitmap::BytesPerRow() const
1693 {
1694 	return fBytesPerRow;
1695 }
1696 
1697 
1698 /*!	\brief Returns the bitmap's color space.
1699 	\return The bitmap's color space.
1700 */
1701 color_space
1702 BBitmap::ColorSpace() const
1703 {
1704 	return fColorSpace;
1705 }
1706 
1707 
1708 /*!	\brief Returns the bitmap's dimensions.
1709 	\return The bitmap's dimensions.
1710 */
1711 BRect
1712 BBitmap::Bounds() const
1713 {
1714 	return fBounds;
1715 }
1716 
1717 
1718 /*!	\brief Assigns data to the bitmap.
1719 
1720 	Data are directly written into the bitmap's data buffer, being converted
1721 	beforehand, if necessary. Some conversions work rather unintuitively:
1722 	- \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG
1723 	  data without padding at the end of the rows.
1724 	- \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8
1725 	  data without padding at the end of the rows.
1726 	- other color spaces: The source buffer is supposed to contain data
1727 	  according to the specified color space being rowwise padded to int32.
1728 
1729 	The currently supported source/target color spaces are
1730 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1731 
1732 	\note As this methods is apparently a bit strange to use, OBOS introduces
1733 		  ImportBits() methods, which are recommended to be used instead.
1734 
1735 	\param data The data to be copied.
1736 	\param length The length in bytes of the data to be copied.
1737 	\param offset The offset (in bytes) relative to beginning of the bitmap
1738 		   data specifying the position at which the source data shall be
1739 		   written.
1740 	\param colorSpace Color space of the source data.
1741 */
1742 void
1743 BBitmap::SetBits(const void *data, int32 length, int32 offset,
1744 	color_space colorSpace)
1745 {
1746 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1747 	// check params
1748 	if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1749 		error = B_BAD_VALUE;
1750 	int32 width = 0;
1751 	if (error == B_OK)
1752 		width = fBounds.IntegerWidth() + 1;
1753 	int32 inBPR = -1;
1754 	// tweaks to mimic R5 behavior
1755 	if (error == B_OK) {
1756 		// B_RGB32 means actually unpadded B_RGB24_BIG
1757 		if (colorSpace == B_RGB32) {
1758 			colorSpace = B_RGB24_BIG;
1759 			inBPR = width * 3;
1760 		// If in color space is B_CMAP8, but the bitmap's is another one,
1761 		// ignore source data row padding.
1762 		} else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8)
1763 			inBPR = width;
1764 	}
1765 	// call the sane method, which does the actual work
1766 	if (error == B_OK)
1767 		error = ImportBits(data, length, inBPR, offset, colorSpace);
1768 }
1769 
1770 
1771 /*!	\brief Assigns data to the bitmap.
1772 
1773 	Data are directly written into the bitmap's data buffer, being converted
1774 	beforehand, if necessary. Unlike for SetBits(), the meaning of
1775 	\a colorSpace is exactly the expected one here, i.e. the source buffer
1776 	is supposed to contain data of that color space. \a bpr specifies how
1777 	many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be
1778 	supplied, if standard padding to int32 is used.
1779 
1780 	The currently supported source/target color spaces are
1781 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1782 
1783 	\param data The data to be copied.
1784 	\param length The length in bytes of the data to be copied.
1785 	\param bpr The number of bytes per row in the source data.
1786 	\param offset The offset (in bytes) relative to beginning of the bitmap
1787 		   data specifying the position at which the source data shall be
1788 		   written.
1789 	\param colorSpace Color space of the source data.
1790 	\return
1791 	- \c B_OK: Everything went fine.
1792 	- \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or
1793 	  unsupported \a colorSpace.
1794 */
1795 status_t
1796 BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset,
1797 	color_space colorSpace)
1798 {
1799 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1800 	// check params
1801 	if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1802 		error = B_BAD_VALUE;
1803 	// get BPR
1804 	int32 width = 0;
1805 	int32 inRowSkip = 0;
1806 	if (error == B_OK) {
1807 		width = fBounds.IntegerWidth() + 1;
1808 		if (bpr < 0)
1809 			bpr = get_bytes_per_row(colorSpace, width);
1810 		inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width);
1811 		if (inRowSkip < 0)
1812 			error = B_BAD_VALUE;
1813 	}
1814 	if (error != B_OK) {
1815 		// catch error case
1816 	} else if (colorSpace == fColorSpace && bpr == fBytesPerRow) {
1817 		length = min(length, fSize - offset);
1818 		memcpy((char*)fBasePtr + offset, data, length);
1819 	} else {
1820 		// TODO: Retrieve color map from BScreen, when available:
1821 		// PaletteConverter paletteConverter(BScreen().ColorMap());
1822 		const PaletteConverter &paletteConverter = *palette_converter();
1823 		int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width);
1824 		switch (colorSpace) {
1825 			// supported
1826 			case B_RGB32: case B_RGBA32:
1827 			{
1828 				typedef RGB24Reader<rgb32_pixel> Reader;
1829 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1830 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1831 					fColorSpace, width, Reader(data), paletteConverter);
1832 				break;
1833 			}
1834 			case B_RGB32_BIG: case B_RGBA32_BIG:
1835 			{
1836 				typedef RGB24Reader<rgb32_big_pixel> Reader;
1837 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1838 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1839 					fColorSpace, width, Reader(data), paletteConverter);
1840 				break;
1841 			}
1842 			case B_RGB24:
1843 			{
1844 				typedef RGB24Reader<rgb24_pixel> Reader;
1845 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1846 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1847 					fColorSpace, width, Reader(data), paletteConverter);
1848 				break;
1849 			}
1850 			case B_RGB24_BIG:
1851 			{
1852 				typedef RGB24Reader<rgb24_big_pixel> Reader;
1853 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1854 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1855 					fColorSpace, width, Reader(data), paletteConverter);
1856 				break;
1857 			}
1858 			case B_RGB16:
1859 			{
1860 				typedef RGB16Reader<rgb16_pixel> Reader;
1861 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1862 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1863 					fColorSpace, width, Reader(data), paletteConverter);
1864 				break;
1865 			}
1866 			case B_RGB16_BIG:
1867 			{
1868 				typedef RGB16Reader<rgb16_big_pixel> Reader;
1869 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1870 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1871 					fColorSpace, width, Reader(data), paletteConverter);
1872 				break;
1873 			}
1874 			case B_RGB15: case B_RGBA15:
1875 			{
1876 				typedef RGB15Reader<rgb16_pixel> Reader;
1877 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1878 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1879 					fColorSpace, width, Reader(data), paletteConverter);
1880 				break;
1881 			}
1882 			case B_RGB15_BIG: case B_RGBA15_BIG:
1883 			{
1884 				typedef RGB15Reader<rgb16_big_pixel> Reader;
1885 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1886 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1887 					fColorSpace, width, Reader(data), paletteConverter);
1888 				break;
1889 			}
1890 			case B_CMAP8:
1891 			{
1892 				typedef CMAP8Reader Reader;
1893 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1894 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1895 					fColorSpace, width, Reader(data, paletteConverter),
1896 					paletteConverter);
1897 				break;
1898 			}
1899 			case B_GRAY8:
1900 			{
1901 				typedef Gray8Reader Reader;
1902 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1903 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1904 					fColorSpace, width, Reader(data), paletteConverter);
1905 				break;
1906 			}
1907 			case B_GRAY1:
1908 			{
1909 				typedef Gray1Reader Reader;
1910 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1911 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1912 					fColorSpace, width, Reader(data), paletteConverter);
1913 				break;
1914 			}
1915 			// unsupported
1916 			case B_NO_COLOR_SPACE:
1917 			case B_YUV9: case B_YUV12:
1918 			case B_UVL32: case B_UVLA32:
1919 			case B_LAB32: case B_LABA32:
1920 			case B_HSI32: case B_HSIA32:
1921 			case B_HSV32: case B_HSVA32:
1922 			case B_HLS32: case B_HLSA32:
1923 			case B_CMY32: case B_CMYA32: case B_CMYK32:
1924 			case B_UVL24: case B_LAB24: case B_HSI24:
1925 			case B_HSV24: case B_HLS24: case B_CMY24:
1926 			case B_YCbCr422: case B_YUV422:
1927 			case B_YCbCr411: case B_YUV411:
1928 			case B_YCbCr444: case B_YUV444:
1929 			case B_YCbCr420: case B_YUV420:
1930 			default:
1931 				error = B_BAD_VALUE;
1932 				break;
1933 		}
1934 	}
1935 	return error;
1936 }
1937 
1938 
1939 /*!	\briefly Assigns another bitmap's data to this bitmap.
1940 
1941 	The supplied bitmap must have the exactly same dimensions as this bitmap.
1942 	Its data are converted to the color space of this bitmap.
1943 
1944 	The currently supported source/target color spaces are
1945 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1946 
1947 	\param bitmap The source bitmap.
1948 	\return
1949 	- \c B_OK: Everything went fine.
1950 	- \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions,
1951 	  or the conversion from or to one of the color spaces is not supported.
1952 */
1953 status_t
1954 BBitmap::ImportBits(const BBitmap *bitmap)
1955 {
1956 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1957 	// check param
1958 	if (error == B_OK && bitmap == NULL)
1959 		error = B_BAD_VALUE;
1960 	if (error == B_OK && bitmap->InitCheck() != B_OK)
1961 		error = B_BAD_VALUE;
1962 	if (error == B_OK && bitmap->Bounds() != fBounds)
1963 		error = B_BAD_VALUE;
1964 	// set bits
1965 	if (error == B_OK) {
1966 		error = ImportBits(bitmap->Bits(), bitmap->BitsLength(),
1967 			bitmap->BytesPerRow(), 0, bitmap->ColorSpace());
1968 	}
1969 	return error;
1970 }
1971 
1972 
1973 status_t
1974 BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const
1975 {
1976 	// TODO: Implement
1977 	return B_ERROR;
1978 }
1979 
1980 
1981 status_t
1982 BBitmap::Perform(perform_code d, void *arg)
1983 {
1984 	return BArchivable::Perform(d, arg);
1985 }
1986 
1987 
1988 // FBC
1989 void BBitmap::_ReservedBitmap1() {}
1990 void BBitmap::_ReservedBitmap2() {}
1991 void BBitmap::_ReservedBitmap3() {}
1992 
1993 
1994 /*!	\brief Privatized copy constructor to prevent usage.
1995 */
1996 BBitmap::BBitmap(const BBitmap &)
1997 {
1998 }
1999 
2000 
2001 /*!	\brief Privatized assignment operator to prevent usage.
2002 */
2003 BBitmap &
2004 BBitmap::operator=(const BBitmap &)
2005 {
2006 	return *this;
2007 }
2008 
2009 
2010 char *
2011 BBitmap::get_shared_pointer() const
2012 {
2013 	return NULL;	// not implemented
2014 }
2015 
2016 
2017 int32
2018 BBitmap::get_server_token() const
2019 {
2020 	return fServerToken;
2021 }
2022 
2023 
2024 /*!	\brief Initializes the bitmap.
2025 	\param bounds The bitmap dimensions.
2026 	\param colorSpace The bitmap's color space.
2027 	\param flags Creation flags.
2028 	\param bytesPerRow The number of bytes per row the bitmap should use.
2029 		   \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
2030 		   value.
2031 	\param screenID ???
2032 */
2033 void
2034 BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
2035 	int32 bytesPerRow, screen_id screenID)
2036 {
2037 //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n",
2038 //	   bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow);
2039 
2040 	// TODO: Hanlde setting up the offscreen window if we're such a bitmap!
2041 
2042 	// TODO: Should we handle rounding of the "bounds" here? How does R5 behave?
2043 
2044 	status_t error = B_OK;
2045 
2046 //#ifdef RUN_WITHOUT_APP_SERVER
2047 	flags |= B_BITMAP_NO_SERVER_LINK;
2048 //#endif	// RUN_WITHOUT_APP_SERVER
2049 flags &= ~B_BITMAP_ACCEPTS_VIEWS;
2050 
2051 	CleanUp();
2052 
2053 	// check params
2054 	if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL))
2055 		error = B_BAD_VALUE;
2056 	if (error == B_OK) {
2057 		int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1);
2058 		if (bytesPerRow < 0)
2059 			bytesPerRow = bpr;
2060 		else if (bytesPerRow < bpr)
2061 // NOTE: How does R5 behave?
2062 			error = B_BAD_VALUE;
2063 	}
2064 	// allocate the bitmap buffer
2065 	if (error == B_OK) {
2066 		// NOTE: Maybe the code would look more robust if the
2067 		// "size" was not calculated here when we ask the server
2068 		// to allocate the bitmap. -Stephan
2069 		int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
2070 
2071 		if (flags & B_BITMAP_NO_SERVER_LINK) {
2072 			fBasePtr = malloc(size);
2073 			if (fBasePtr) {
2074 				fSize = size;
2075 				fColorSpace = colorSpace;
2076 				fBounds = bounds;
2077 				fBytesPerRow = bytesPerRow;
2078 				fFlags = flags;
2079 			} else
2080 				error = B_NO_MEMORY;
2081 		} else {
2082 // 			// Ask the server (via our owning application) to create a bitmap.
2083 // 			BPrivate::AppServerLink link;
2084 //
2085 // 			// Attach Data:
2086 // 			// 1) BRect bounds
2087 // 			// 2) color_space space
2088 // 			// 3) int32 bitmap_flags
2089 // 			// 4) int32 bytes_per_row
2090 // 			// 5) int32 screen_id::id
2091 // 			link.StartMessage(AS_CREATE_BITMAP);
2092 // 			link.Attach<BRect>(bounds);
2093 // 			link.Attach<color_space>(colorSpace);
2094 // 			link.Attach<int32>((int32)flags);
2095 // 			link.Attach<int32>(bytesPerRow);
2096 // 			link.Attach<int32>(screenID.id);
2097 //
2098 // 			// Reply Code: SERVER_TRUE
2099 // 			// Reply Data:
2100 // 			//	1) int32 server token
2101 // 			//	2) area_id id of the area in which the bitmap data resides
2102 // 			//	3) int32 area pointer offset used to calculate fBasePtr
2103 //
2104 // 			// alternatively, if something went wrong
2105 // 			// Reply Code: SERVER_FALSE
2106 // 			// Reply Data:
2107 // 			//		None
2108 // 			int32 code = SERVER_FALSE;
2109 // 			error = link.FlushWithReply(code);
2110 //
2111 // 			if (error >= B_OK) {
2112 // 				// *communication* with server successful
2113 // 				if (code == SERVER_TRUE) {
2114 // 					// server side success
2115 // 					// Get token
2116 // 					area_id bmparea;
2117 // 					int32 areaoffset;
2118 //
2119 // 					link.Read<int32>(&fServerToken);
2120 // 					link.Read<area_id>(&bmparea);
2121 // 					link.Read<int32>(&areaoffset);
2122 //
2123 // 					// Get the area in which the data resides
2124 // 					fArea = clone_area("shared bitmap area",
2125 // 									   (void**)&fBasePtr,
2126 // 									   B_ANY_ADDRESS,
2127 // 									   B_READ_AREA | B_WRITE_AREA,
2128 // 									   bmparea);
2129 //
2130 // 					// Jump to the location in the area
2131 // 					fBasePtr = (int8*)fBasePtr + areaoffset;
2132 //
2133 // 					fSize = size;
2134 // 					fColorSpace = colorSpace;
2135 // 					fBounds = bounds;
2136 // 					fBytesPerRow = bytesPerRow;
2137 // 					fFlags = flags;
2138 // 				} else {
2139 // 					// server side error, we assume:
2140 // 					error = B_NO_MEMORY;
2141 // 				}
2142 // 			}
2143 // 			// NOTE: not "else" to handle B_NO_MEMORY on server side!
2144 // 			if (error < B_OK) {
2145 // 				fBasePtr = NULL;
2146 // 				fServerToken = -1;
2147 // 				fArea = -1;
2148 // 				// NOTE: why not "0" in case of error?
2149 // 				fFlags = flags;
2150 // 			}
2151 		}
2152 //		fWindow = NULL;
2153 		fToken = -1;
2154 		fOrigArea = -1;
2155 	}
2156 
2157 	fInitError = error;
2158 	// TODO: on success, handle clearing to white if the flags say so. Needs to be
2159 	// dependent on color space.
2160 
2161 	if (fInitError == B_OK) {
2162 		if (flags & B_BITMAP_ACCEPTS_VIEWS) {
2163 // 			fWindow = new BWindow(Bounds(), fServerToken);
2164 // 			// A BWindow starts life locked and is unlocked
2165 // 			// in Show(), but this window is never shown and
2166 // 			// it's message loop is never started.
2167 // 			fWindow->Unlock();
2168 		}
2169 	}
2170 }
2171 
2172 
2173 /*!	\brief Cleans up any memory allocated by the bitmap or
2174 		   informs the server to do so.
2175 */
2176 void
2177 BBitmap::CleanUp()
2178 {
2179 	if (fBasePtr) {
2180 		if (fFlags & B_BITMAP_NO_SERVER_LINK) {
2181 			free(fBasePtr);
2182 		} else {
2183 // 			BPrivate::AppServerLink link;
2184 // 			// AS_DELETE_BITMAP:
2185 // 			// Attached Data:
2186 // 			//	1) int32 server token
2187 //
2188 // 			// Reply Code: SERVER_TRUE if successful,
2189 // 			//			   SERVER_FALSE if the buffer was already deleted
2190 // 			// Reply Data: none
2191 // //			status_t freestat;
2192 // 			int32 code = SERVER_FALSE;
2193 // 			link.StartMessage(AS_DELETE_BITMAP);
2194 // 			link.Attach<int32>(fServerToken);
2195 // 			link.FlushWithReply(code);
2196 // 			if (code == SERVER_FALSE) {
2197 // 				// TODO: Find out if "SERVER_FALSE if the buffer
2198 // 				// was already deleted" is true. If not, maybe we
2199 // 				// need to take additional action.
2200 // 			}
2201 // 			fArea = -1;
2202 // 			fServerToken = -1;
2203 		}
2204 		fBasePtr = NULL;
2205 	}
2206 }
2207 
2208 
2209 void
2210 BBitmap::AssertPtr()
2211 {
2212 }
2213 
2214