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