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