xref: /haiku/src/build/libbe/interface/Bitmap.cpp (revision a8a03488b178618297ebb9bb958e3a41f800c7a5)
1338b8dc3SIngo Weinhold /*
264b2d169SAxel Dörfler  * Copyright 2001-2008, Haiku Inc.
3338b8dc3SIngo Weinhold  * Distributed under the terms of the MIT License.
4338b8dc3SIngo Weinhold  *
5338b8dc3SIngo Weinhold  * Authors:
6338b8dc3SIngo Weinhold  *		Ingo Weinhold (bonefish@users.sf.net)
7338b8dc3SIngo Weinhold  *		DarkWyrm <bpmagic@columbus.rr.com>
8338b8dc3SIngo Weinhold  *		Stephan Aßmus <superstippi@gmx.de>
9338b8dc3SIngo Weinhold  */
10338b8dc3SIngo Weinhold 
1164b2d169SAxel Dörfler /*!	BBitmap objects represent off-screen windows that contain bitmap data. */
12338b8dc3SIngo Weinhold 
13338b8dc3SIngo Weinhold #include <algorithm>
14338b8dc3SIngo Weinhold #include <limits.h>
15338b8dc3SIngo Weinhold #include <new>
16338b8dc3SIngo Weinhold #include <stdio.h>
17338b8dc3SIngo Weinhold #include <stdlib.h>
18338b8dc3SIngo Weinhold 
19338b8dc3SIngo Weinhold #include <Bitmap.h>
20338b8dc3SIngo Weinhold #include <GraphicsDefs.h>
21338b8dc3SIngo Weinhold #include <Locker.h>
22338b8dc3SIngo Weinhold #include <Message.h>
23338b8dc3SIngo Weinhold 
24338b8dc3SIngo Weinhold 
2564b2d169SAxel Dörfler // structures defining the pixel layout
2664b2d169SAxel Dörfler 
2764b2d169SAxel Dörfler struct rgb32_pixel {
2864b2d169SAxel Dörfler 	uint8 blue;
2964b2d169SAxel Dörfler 	uint8 green;
3064b2d169SAxel Dörfler 	uint8 red;
3164b2d169SAxel Dörfler 	uint8 alpha;
3264b2d169SAxel Dörfler };
3364b2d169SAxel Dörfler 
3464b2d169SAxel Dörfler struct rgb32_big_pixel {
3564b2d169SAxel Dörfler 	uint8 red;
3664b2d169SAxel Dörfler 	uint8 green;
3764b2d169SAxel Dörfler 	uint8 blue;
3864b2d169SAxel Dörfler 	uint8 alpha;
3964b2d169SAxel Dörfler };
4064b2d169SAxel Dörfler 
4164b2d169SAxel Dörfler struct rgb24_pixel {
4264b2d169SAxel Dörfler 	uint8 blue;
4364b2d169SAxel Dörfler 	uint8 green;
4464b2d169SAxel Dörfler 	uint8 red;
4564b2d169SAxel Dörfler };
4664b2d169SAxel Dörfler 
4764b2d169SAxel Dörfler struct rgb24_big_pixel {
4864b2d169SAxel Dörfler 	uint8 red;
4964b2d169SAxel Dörfler 	uint8 green;
5064b2d169SAxel Dörfler 	uint8 blue;
5164b2d169SAxel Dörfler };
5264b2d169SAxel Dörfler 
5364b2d169SAxel Dörfler struct rgb16_pixel {
5464b2d169SAxel Dörfler 	uint8 gb;	// G[2:0],B[4:0]
5564b2d169SAxel Dörfler 	uint8 rg;	// 16: R[4:0],G[5:3]
5664b2d169SAxel Dörfler 				// 15: -[0],R[4:0],G[4:3]
5764b2d169SAxel Dörfler };
5864b2d169SAxel Dörfler 
5964b2d169SAxel Dörfler struct rgb16_big_pixel {
6064b2d169SAxel Dörfler 	uint8 rg;	// 16: R[4:0],G[5:3]
6164b2d169SAxel Dörfler 				// 15: -[0],R[4:0],G[4:3]
6264b2d169SAxel Dörfler 	uint8 gb;	// G[2:0],B[4:0]
6364b2d169SAxel Dörfler };
6464b2d169SAxel Dörfler 
6564b2d169SAxel Dörfler // types defining what is needed to store a color value
6664b2d169SAxel Dörfler 
6764b2d169SAxel Dörfler struct rgb_color_value {
6864b2d169SAxel Dörfler 	uint8 red;
6964b2d169SAxel Dörfler 	uint8 green;
7064b2d169SAxel Dörfler 	uint8 blue;
7164b2d169SAxel Dörfler 	uint8 alpha;
7264b2d169SAxel Dörfler };
7364b2d169SAxel Dörfler 
7464b2d169SAxel Dörfler typedef uint8 gray_color_value;
7564b2d169SAxel Dörfler 
76338b8dc3SIngo Weinhold // TODO: system palette -- hard-coded for now, when the app server is ready
77338b8dc3SIngo Weinhold // we should use system_colors() or BScreen::ColorMap().
78338b8dc3SIngo Weinhold const rgb_color kSystemPalette[] = {
79338b8dc3SIngo Weinhold 	{   0,   0,   0, 255 }, {   8,   8,   8, 255 }, {  16,  16,  16, 255 },
80338b8dc3SIngo Weinhold 	{  24,  24,  24, 255 }, {  32,  32,  32, 255 }, {  40,  40,  40, 255 },
81338b8dc3SIngo Weinhold 	{  48,  48,  48, 255 }, {  56,  56,  56, 255 }, {  64,  64,  64, 255 },
82338b8dc3SIngo Weinhold 	{  72,  72,  72, 255 }, {  80,  80,  80, 255 }, {  88,  88,  88, 255 },
83338b8dc3SIngo Weinhold 	{  96,  96,  96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 },
84338b8dc3SIngo Weinhold 	{ 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 },
85338b8dc3SIngo Weinhold 	{ 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 },
86338b8dc3SIngo Weinhold 	{ 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 },
87338b8dc3SIngo Weinhold 	{ 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 },
88338b8dc3SIngo Weinhold 	{ 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 },
89338b8dc3SIngo Weinhold 	{ 240, 240, 240, 255 }, { 248, 248, 248, 255 }, {   0,   0, 255, 255 },
90338b8dc3SIngo Weinhold 	{   0,   0, 229, 255 }, {   0,   0, 204, 255 }, {   0,   0, 179, 255 },
91338b8dc3SIngo Weinhold 	{   0,   0, 154, 255 }, {   0,   0, 129, 255 }, {   0,   0, 105, 255 },
92338b8dc3SIngo Weinhold 	{   0,   0,  80, 255 }, {   0,   0,  55, 255 }, {   0,   0,  30, 255 },
93338b8dc3SIngo Weinhold 	{ 255,   0,   0, 255 }, { 228,   0,   0, 255 }, { 203,   0,   0, 255 },
94338b8dc3SIngo Weinhold 	{ 178,   0,   0, 255 }, { 153,   0,   0, 255 }, { 128,   0,   0, 255 },
95338b8dc3SIngo Weinhold 	{ 105,   0,   0, 255 }, {  80,   0,   0, 255 }, {  55,   0,   0, 255 },
96338b8dc3SIngo Weinhold 	{  30,   0,   0, 255 }, {   0, 255,   0, 255 }, {   0, 228,   0, 255 },
97338b8dc3SIngo Weinhold 	{   0, 203,   0, 255 }, {   0, 178,   0, 255 }, {   0, 153,   0, 255 },
98338b8dc3SIngo Weinhold 	{   0, 128,   0, 255 }, {   0, 105,   0, 255 }, {   0,  80,   0, 255 },
99338b8dc3SIngo Weinhold 	{   0,  55,   0, 255 }, {   0,  30,   0, 255 }, {   0, 152,  51, 255 },
100338b8dc3SIngo Weinhold 	{ 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 },
101338b8dc3SIngo Weinhold 	{ 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255,  51, 255 },
102338b8dc3SIngo Weinhold 	{ 203, 255,   0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 },
103338b8dc3SIngo Weinhold 	{ 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255,  51, 255 },
104338b8dc3SIngo Weinhold 	{ 152, 255,   0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 },
105338b8dc3SIngo Weinhold 	{ 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255,  51, 255 },
106338b8dc3SIngo Weinhold 	{ 102, 255,   0, 255 }, {  51, 255, 255, 255 }, {  51, 255, 203, 255 },
107338b8dc3SIngo Weinhold 	{  51, 255, 152, 255 }, {  51, 255, 102, 255 }, {  51, 255,  51, 255 },
108338b8dc3SIngo Weinhold 	{  51, 255,   0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 },
109338b8dc3SIngo Weinhold 	{ 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152,  51, 255 },
110338b8dc3SIngo Weinhold 	{ 255, 152,   0, 255 }, {   0, 102, 255, 255 }, {   0, 102, 203, 255 },
111338b8dc3SIngo Weinhold 	{ 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 },
112338b8dc3SIngo Weinhold 	{ 203, 203, 102, 255 }, { 203, 203,  51, 255 }, { 203, 203,   0, 255 },
113338b8dc3SIngo Weinhold 	{ 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 },
114338b8dc3SIngo Weinhold 	{ 152, 203, 102, 255 }, { 152, 203,  51, 255 }, { 152, 203,   0, 255 },
115338b8dc3SIngo Weinhold 	{ 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 },
116338b8dc3SIngo Weinhold 	{ 102, 203, 102, 255 }, { 102, 203,  51, 255 }, { 102, 203,   0, 255 },
117338b8dc3SIngo Weinhold 	{  51, 203, 255, 255 }, {  51, 203, 203, 255 }, {  51, 203, 152, 255 },
118338b8dc3SIngo Weinhold 	{  51, 203, 102, 255 }, {  51, 203,  51, 255 }, {  51, 203,   0, 255 },
119338b8dc3SIngo Weinhold 	{ 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 },
120338b8dc3SIngo Weinhold 	{ 255, 102, 102, 255 }, { 255, 102,  51, 255 }, { 255, 102,   0, 255 },
121338b8dc3SIngo Weinhold 	{   0, 102, 152, 255 }, {   0, 102, 102, 255 }, { 203, 152, 255, 255 },
122338b8dc3SIngo Weinhold 	{ 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 },
123338b8dc3SIngo Weinhold 	{ 203, 152,  51, 255 }, { 203, 152,   0, 255 }, { 152, 152, 255, 255 },
124338b8dc3SIngo Weinhold 	{ 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 },
125338b8dc3SIngo Weinhold 	{ 152, 152,  51, 255 }, { 152, 152,   0, 255 }, { 102, 152, 255, 255 },
126338b8dc3SIngo Weinhold 	{ 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 },
127338b8dc3SIngo Weinhold 	{ 102, 152,  51, 255 }, { 102, 152,   0, 255 }, {  51, 152, 255, 255 },
128338b8dc3SIngo Weinhold 	{  51, 152, 203, 255 }, {  51, 152, 152, 255 }, {  51, 152, 102, 255 },
129338b8dc3SIngo Weinhold 	{  51, 152,  51, 255 }, {  51, 152,   0, 255 }, { 230, 134,   0, 255 },
130338b8dc3SIngo Weinhold 	{ 255,  51, 203, 255 }, { 255,  51, 152, 255 }, { 255,  51, 102, 255 },
131338b8dc3SIngo Weinhold 	{ 255,  51,  51, 255 }, { 255,  51,   0, 255 }, {   0, 102,  51, 255 },
132338b8dc3SIngo Weinhold 	{   0, 102,   0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 },
133338b8dc3SIngo Weinhold 	{ 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102,  51, 255 },
134338b8dc3SIngo Weinhold 	{ 203, 102,   0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 },
135338b8dc3SIngo Weinhold 	{ 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102,  51, 255 },
136338b8dc3SIngo Weinhold 	{ 152, 102,   0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 },
137338b8dc3SIngo Weinhold 	{ 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102,  51, 255 },
138338b8dc3SIngo Weinhold 	{ 102, 102,   0, 255 }, {  51, 102, 255, 255 }, {  51, 102, 203, 255 },
139338b8dc3SIngo Weinhold 	{  51, 102, 152, 255 }, {  51, 102, 102, 255 }, {  51, 102,  51, 255 },
140338b8dc3SIngo Weinhold 	{  51, 102,   0, 255 }, { 255,   0, 255, 255 }, { 255,   0, 203, 255 },
141338b8dc3SIngo Weinhold 	{ 255,   0, 152, 255 }, { 255,   0, 102, 255 }, { 255,   0,  51, 255 },
142338b8dc3SIngo Weinhold 	{ 255, 175,  19, 255 }, {   0,  51, 255, 255 }, {   0,  51, 203, 255 },
143338b8dc3SIngo Weinhold 	{ 203,  51, 255, 255 }, { 203,  51, 203, 255 }, { 203,  51, 152, 255 },
144338b8dc3SIngo Weinhold 	{ 203,  51, 102, 255 }, { 203,  51,  51, 255 }, { 203,  51,   0, 255 },
145338b8dc3SIngo Weinhold 	{ 152,  51, 255, 255 }, { 152,  51, 203, 255 }, { 152,  51, 152, 255 },
146338b8dc3SIngo Weinhold 	{ 152,  51, 102, 255 }, { 152,  51,  51, 255 }, { 152,  51,   0, 255 },
147338b8dc3SIngo Weinhold 	{ 102,  51, 255, 255 }, { 102,  51, 203, 255 }, { 102,  51, 152, 255 },
148338b8dc3SIngo Weinhold 	{ 102,  51, 102, 255 }, { 102,  51,  51, 255 }, { 102,  51,   0, 255 },
149338b8dc3SIngo Weinhold 	{  51,  51, 255, 255 }, {  51,  51, 203, 255 }, {  51,  51, 152, 255 },
150338b8dc3SIngo Weinhold 	{  51,  51, 102, 255 }, {  51,  51,  51, 255 }, {  51,  51,   0, 255 },
151338b8dc3SIngo Weinhold 	{ 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 },
152338b8dc3SIngo Weinhold 	{ 255, 203, 255, 255 }, {   0,  51, 152, 255 }, {   0,  51, 102, 255 },
153338b8dc3SIngo Weinhold 	{   0,  51,  51, 255 }, {   0,  51,   0, 255 }, { 203,   0, 255, 255 },
154338b8dc3SIngo Weinhold 	{ 203,   0, 203, 255 }, { 203,   0, 152, 255 }, { 203,   0, 102, 255 },
155338b8dc3SIngo Weinhold 	{ 203,   0,  51, 255 }, { 255, 227,  70, 255 }, { 152,   0, 255, 255 },
156338b8dc3SIngo Weinhold 	{ 152,   0, 203, 255 }, { 152,   0, 152, 255 }, { 152,   0, 102, 255 },
157338b8dc3SIngo Weinhold 	{ 152,   0,  51, 255 }, { 152,   0,   0, 255 }, { 102,   0, 255, 255 },
158338b8dc3SIngo Weinhold 	{ 102,   0, 203, 255 }, { 102,   0, 152, 255 }, { 102,   0, 102, 255 },
159338b8dc3SIngo Weinhold 	{ 102,   0,  51, 255 }, { 102,   0,   0, 255 }, {  51,   0, 255, 255 },
160338b8dc3SIngo Weinhold 	{  51,   0, 203, 255 }, {  51,   0, 152, 255 }, {  51,   0, 102, 255 },
161338b8dc3SIngo Weinhold 	{  51,   0,  51, 255 }, {  51,   0,   0, 255 }, { 255, 203,  51, 255 },
162338b8dc3SIngo Weinhold 	{ 255, 203,   0, 255 }, { 255, 255,   0, 255 }, { 255, 255,  51, 255 },
163338b8dc3SIngo Weinhold 	{ 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 },
164338b8dc3SIngo Weinhold 	{ 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8
165338b8dc3SIngo Weinhold };
166338b8dc3SIngo Weinhold 
167338b8dc3SIngo Weinhold 
168338b8dc3SIngo Weinhold /*!	\brief Returns the number of bytes per row needed to store the actual
169338b8dc3SIngo Weinhold 		   bitmap data (not including any padding) given a color space and a
170338b8dc3SIngo Weinhold 		   row width.
171338b8dc3SIngo Weinhold 	\param colorSpace The color space.
172338b8dc3SIngo Weinhold 	\param width The width.
173338b8dc3SIngo Weinhold 	\return The number of bytes per row needed to store data for a row, or
174338b8dc3SIngo Weinhold 			0, if the color space is not supported.
175338b8dc3SIngo Weinhold */
17664b2d169SAxel Dörfler static inline int32
177338b8dc3SIngo Weinhold get_raw_bytes_per_row(color_space colorSpace, int32 width)
178338b8dc3SIngo Weinhold {
179338b8dc3SIngo Weinhold 	int32 bpr = 0;
180338b8dc3SIngo Weinhold 	switch (colorSpace) {
181338b8dc3SIngo Weinhold 		// supported
182338b8dc3SIngo Weinhold 		case B_RGB32: case B_RGBA32:
183338b8dc3SIngo Weinhold 		case B_RGB32_BIG: case B_RGBA32_BIG:
184338b8dc3SIngo Weinhold 		case B_UVL32: case B_UVLA32:
185338b8dc3SIngo Weinhold 		case B_LAB32: case B_LABA32:
186338b8dc3SIngo Weinhold 		case B_HSI32: case B_HSIA32:
187338b8dc3SIngo Weinhold 		case B_HSV32: case B_HSVA32:
188338b8dc3SIngo Weinhold 		case B_HLS32: case B_HLSA32:
189338b8dc3SIngo Weinhold 		case B_CMY32: case B_CMYA32: case B_CMYK32:
190338b8dc3SIngo Weinhold 			bpr = 4 * width;
191338b8dc3SIngo Weinhold 			break;
192338b8dc3SIngo Weinhold 		case B_RGB24: case B_RGB24_BIG:
193338b8dc3SIngo Weinhold 		case B_UVL24: case B_LAB24: case B_HSI24:
194338b8dc3SIngo Weinhold 		case B_HSV24: case B_HLS24: case B_CMY24:
195338b8dc3SIngo Weinhold 			bpr = 3 * width;
196338b8dc3SIngo Weinhold 			break;
197338b8dc3SIngo Weinhold 		case B_RGB16:		case B_RGB15:		case B_RGBA15:
198338b8dc3SIngo Weinhold 		case B_RGB16_BIG:	case B_RGB15_BIG:	case B_RGBA15_BIG:
199338b8dc3SIngo Weinhold 			bpr = 2 * width;
200338b8dc3SIngo Weinhold 			break;
201338b8dc3SIngo Weinhold 		case B_CMAP8: case B_GRAY8:
202338b8dc3SIngo Weinhold 			bpr = width;
203338b8dc3SIngo Weinhold 			break;
204338b8dc3SIngo Weinhold 		case B_GRAY1:
205338b8dc3SIngo Weinhold 			bpr = (width + 7) / 8;
206338b8dc3SIngo Weinhold 			break;
207338b8dc3SIngo Weinhold 		case B_YCbCr422: case B_YUV422:
208338b8dc3SIngo Weinhold 			bpr = (width + 3) / 4 * 8;
209338b8dc3SIngo Weinhold 			break;
210338b8dc3SIngo Weinhold 		case B_YCbCr411: case B_YUV411:
211338b8dc3SIngo Weinhold 			bpr = (width + 3) / 4 * 6;
212338b8dc3SIngo Weinhold 			break;
213338b8dc3SIngo Weinhold 		case B_YCbCr444: case B_YUV444:
214338b8dc3SIngo Weinhold 			bpr = (width + 3) / 4 * 12;
215338b8dc3SIngo Weinhold 			break;
216338b8dc3SIngo Weinhold 		case B_YCbCr420: case B_YUV420:
217338b8dc3SIngo Weinhold 			bpr = (width + 3) / 4 * 6;
218338b8dc3SIngo Weinhold 			break;
219338b8dc3SIngo Weinhold 		// unsupported
220338b8dc3SIngo Weinhold 		case B_NO_COLOR_SPACE:
221338b8dc3SIngo Weinhold 		case B_YUV9: case B_YUV12:
222338b8dc3SIngo Weinhold 			break;
223338b8dc3SIngo Weinhold 	}
224338b8dc3SIngo Weinhold 	return bpr;
225338b8dc3SIngo Weinhold }
226338b8dc3SIngo Weinhold 
22764b2d169SAxel Dörfler 
228338b8dc3SIngo Weinhold /*!	\brief Returns the number of bytes per row needed to store the bitmap
229338b8dc3SIngo Weinhold 		   data (including any padding) given a color space and a row width.
230338b8dc3SIngo Weinhold 	\param colorSpace The color space.
231338b8dc3SIngo Weinhold 	\param width The width.
232338b8dc3SIngo Weinhold 	\return The number of bytes per row needed to store data for a row, or
233338b8dc3SIngo Weinhold 			0, if the color space is not supported.
234338b8dc3SIngo Weinhold */
23564b2d169SAxel Dörfler static inline int32
236338b8dc3SIngo Weinhold get_bytes_per_row(color_space colorSpace, int32 width)
237338b8dc3SIngo Weinhold {
238338b8dc3SIngo Weinhold 	int32 bpr = get_raw_bytes_per_row(colorSpace, width);
239338b8dc3SIngo Weinhold 	// align to int32
240338b8dc3SIngo Weinhold 	bpr = (bpr + 3) & 0x7ffffffc;
241338b8dc3SIngo Weinhold 	return bpr;
242338b8dc3SIngo Weinhold }
243338b8dc3SIngo Weinhold 
24464b2d169SAxel Dörfler 
245338b8dc3SIngo Weinhold /*!	\brief Returns the brightness of an RGB 24 color.
246338b8dc3SIngo Weinhold 	\param red Value of the red component.
247338b8dc3SIngo Weinhold 	\param green Value of the green component.
248338b8dc3SIngo Weinhold 	\param blue Value of the blue component.
249338b8dc3SIngo Weinhold 	\return The brightness for the supplied RGB color as a value between 0
250338b8dc3SIngo Weinhold 			and 255.
251338b8dc3SIngo Weinhold */
25264b2d169SAxel Dörfler static inline uint8
253338b8dc3SIngo Weinhold brightness_for(uint8 red, uint8 green, uint8 blue)
254338b8dc3SIngo Weinhold {
255338b8dc3SIngo Weinhold 	// brightness = 0.301 * red + 0.586 * green + 0.113 * blue
256338b8dc3SIngo Weinhold 	// we use for performance reasons:
257338b8dc3SIngo Weinhold 	// brightness = (308 * red + 600 * green + 116 * blue) / 1024
258338b8dc3SIngo Weinhold 	return uint8((308 * red + 600 * green + 116 * blue) / 1024);
259338b8dc3SIngo Weinhold }
260338b8dc3SIngo Weinhold 
26164b2d169SAxel Dörfler 
262338b8dc3SIngo Weinhold /*!	\brief Returns the "distance" between two RGB colors.
263338b8dc3SIngo Weinhold 
264338b8dc3SIngo Weinhold 	This functions defines an metric on the RGB color space. The distance
265338b8dc3SIngo Weinhold 	between two colors is 0, if and only if the colors are equal.
266338b8dc3SIngo Weinhold 
267338b8dc3SIngo Weinhold 	\param red1 Red component of the first color.
268338b8dc3SIngo Weinhold 	\param green1 Green component of the first color.
269338b8dc3SIngo Weinhold 	\param blue1 Blue component of the first color.
270338b8dc3SIngo Weinhold 	\param red2 Red component of the second color.
271338b8dc3SIngo Weinhold 	\param green2 Green component of the second color.
272338b8dc3SIngo Weinhold 	\param blue2 Blue component of the second color.
273338b8dc3SIngo Weinhold 	\return The distance between the given colors.
274338b8dc3SIngo Weinhold */
27564b2d169SAxel Dörfler static inline unsigned
27664b2d169SAxel Dörfler color_distance(uint8 red1, uint8 green1, uint8 blue1, uint8 red2, uint8 green2,
27764b2d169SAxel Dörfler 	uint8 blue2)
278338b8dc3SIngo Weinhold {
279338b8dc3SIngo Weinhold 	// euklidian distance (its square actually)
280338b8dc3SIngo Weinhold 	int rd = (int)red1 - (int)red2;
281338b8dc3SIngo Weinhold 	int gd = (int)green1 - (int)green2;
282338b8dc3SIngo Weinhold 	int bd = (int)blue1 - (int)blue2;
283338b8dc3SIngo Weinhold //	return rd * rd + gd * gd + bd * bd;
284338b8dc3SIngo Weinhold 
285338b8dc3SIngo Weinhold 	// distance according to psycho-visual tests
286338b8dc3SIngo Weinhold 	int rmean = ((int)red1 + (int)red2) / 2;
28764b2d169SAxel Dörfler 	return (((512 + rmean) * rd * rd) >> 8) + 4 * gd * gd
288338b8dc3SIngo Weinhold 		+ (((767 - rmean) * bd * bd) >> 8);
289338b8dc3SIngo Weinhold }
290338b8dc3SIngo Weinhold 
29164b2d169SAxel Dörfler 
29264b2d169SAxel Dörfler static inline int32
29364b2d169SAxel Dörfler bit_mask(int32 bit)
29464b2d169SAxel Dörfler {
29564b2d169SAxel Dörfler 	return 1 << bit;
29664b2d169SAxel Dörfler }
297338b8dc3SIngo Weinhold 
298338b8dc3SIngo Weinhold 
29964b2d169SAxel Dörfler static inline int32
30064b2d169SAxel Dörfler inverse_bit_mask(int32 bit)
30164b2d169SAxel Dörfler {
30264b2d169SAxel Dörfler 	return ~bit_mask(bit);
30364b2d169SAxel Dörfler }
30464b2d169SAxel Dörfler 
30564b2d169SAxel Dörfler 
30664b2d169SAxel Dörfler //	#pragma mark - PaletteConverter
30764b2d169SAxel Dörfler 
308338b8dc3SIngo Weinhold 
309338b8dc3SIngo Weinhold namespace BPrivate {
310338b8dc3SIngo Weinhold 
311338b8dc3SIngo Weinhold /*!	\brief Helper class for conversion between RGB and palette colors.
312338b8dc3SIngo Weinhold */
313338b8dc3SIngo Weinhold class PaletteConverter {
314338b8dc3SIngo Weinhold public:
315338b8dc3SIngo Weinhold 	PaletteConverter();
316338b8dc3SIngo Weinhold 	PaletteConverter(const rgb_color *palette);
317338b8dc3SIngo Weinhold 	PaletteConverter(const color_map *colorMap);
318338b8dc3SIngo Weinhold 	~PaletteConverter();
319338b8dc3SIngo Weinhold 
320338b8dc3SIngo Weinhold 	status_t SetTo(const rgb_color *palette);
321338b8dc3SIngo Weinhold 	status_t SetTo(const color_map *colorMap);
322338b8dc3SIngo Weinhold 	status_t InitCheck() const;
323338b8dc3SIngo Weinhold 
324338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB15(uint16 rgb) const;
325338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const;
326338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB16(uint16 rgb) const;
327338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const;
328338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB24(uint32 rgb) const;
329338b8dc3SIngo Weinhold 	inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const;
330338b8dc3SIngo Weinhold 	inline uint8 IndexForGray(uint8 gray) const;
331338b8dc3SIngo Weinhold 
332338b8dc3SIngo Weinhold 	inline const rgb_color &RGBColorForIndex(uint8 index) const;
333338b8dc3SIngo Weinhold 	inline uint16 RGB15ColorForIndex(uint8 index) const;
334338b8dc3SIngo Weinhold 	inline uint16 RGB16ColorForIndex(uint8 index) const;
335338b8dc3SIngo Weinhold 	inline uint32 RGB24ColorForIndex(uint8 index) const;
336338b8dc3SIngo Weinhold 	inline void RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
337338b8dc3SIngo Weinhold 		uint8 &blue, uint8 &alpha) const;
338338b8dc3SIngo Weinhold 	inline uint8 GrayColorForIndex(uint8 index) const;
339338b8dc3SIngo Weinhold 
340338b8dc3SIngo Weinhold private:
341338b8dc3SIngo Weinhold 	const color_map	*fColorMap;
342338b8dc3SIngo Weinhold 	color_map		*fOwnColorMap;
343338b8dc3SIngo Weinhold 	status_t		fCStatus;
344338b8dc3SIngo Weinhold };
345338b8dc3SIngo Weinhold 
346338b8dc3SIngo Weinhold }	// namespace BPrivate
347338b8dc3SIngo Weinhold 
348338b8dc3SIngo Weinhold using BPrivate::PaletteConverter;
349338b8dc3SIngo Weinhold using namespace std;
350338b8dc3SIngo Weinhold 
35164b2d169SAxel Dörfler 
352338b8dc3SIngo Weinhold /*!	\brief Creates an uninitialized PaletteConverter.
353338b8dc3SIngo Weinhold */
354338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter()
355338b8dc3SIngo Weinhold 	: fColorMap(NULL),
356338b8dc3SIngo Weinhold 	  fOwnColorMap(NULL),
357338b8dc3SIngo Weinhold 	  fCStatus(B_NO_INIT)
358338b8dc3SIngo Weinhold {
359338b8dc3SIngo Weinhold }
360338b8dc3SIngo Weinhold 
36164b2d169SAxel Dörfler 
362338b8dc3SIngo Weinhold /*!	\brief Creates a PaletteConverter and initializes it to the supplied
363338b8dc3SIngo Weinhold 		   palette.
364338b8dc3SIngo Weinhold 	\param palette The palette being a 256 entry rgb_color array.
365338b8dc3SIngo Weinhold */
366338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const rgb_color *palette)
367338b8dc3SIngo Weinhold 	: fColorMap(NULL),
368338b8dc3SIngo Weinhold 	  fOwnColorMap(NULL),
369338b8dc3SIngo Weinhold 	  fCStatus(B_NO_INIT)
370338b8dc3SIngo Weinhold {
371338b8dc3SIngo Weinhold 	SetTo(palette);
372338b8dc3SIngo Weinhold }
373338b8dc3SIngo Weinhold 
37464b2d169SAxel Dörfler 
375338b8dc3SIngo Weinhold /*!	\brief Creates a PaletteConverter and initializes it to the supplied
376338b8dc3SIngo Weinhold 		   color map.
377338b8dc3SIngo Weinhold 	\param colorMap The completely initialized color map.
378338b8dc3SIngo Weinhold */
379338b8dc3SIngo Weinhold PaletteConverter::PaletteConverter(const color_map *colorMap)
380338b8dc3SIngo Weinhold 	: fColorMap(NULL),
381338b8dc3SIngo Weinhold 	  fOwnColorMap(NULL),
382338b8dc3SIngo Weinhold 	  fCStatus(B_NO_INIT)
383338b8dc3SIngo Weinhold {
384338b8dc3SIngo Weinhold 	SetTo(colorMap);
385338b8dc3SIngo Weinhold }
386338b8dc3SIngo Weinhold 
38764b2d169SAxel Dörfler 
388338b8dc3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
389338b8dc3SIngo Weinhold */
390338b8dc3SIngo Weinhold PaletteConverter::~PaletteConverter()
391338b8dc3SIngo Weinhold {
392338b8dc3SIngo Weinhold 	delete fOwnColorMap;
393338b8dc3SIngo Weinhold }
394338b8dc3SIngo Weinhold 
39564b2d169SAxel Dörfler 
396338b8dc3SIngo Weinhold /*!	\brief Initializes the converter to the supplied palette.
397338b8dc3SIngo Weinhold 	\param palette The palette being a 256 entry rgb_color array.
398338b8dc3SIngo Weinhold 	\return \c B_OK, if everything went fine, an error code otherwise.
399338b8dc3SIngo Weinhold */
400338b8dc3SIngo Weinhold status_t
401338b8dc3SIngo Weinhold PaletteConverter::SetTo(const rgb_color *palette)
402338b8dc3SIngo Weinhold {
403338b8dc3SIngo Weinhold 	// cleanup
404338b8dc3SIngo Weinhold 	SetTo((const color_map*)NULL);
405338b8dc3SIngo Weinhold 	status_t error = (palette ? B_OK : B_BAD_VALUE);
406338b8dc3SIngo Weinhold 	// alloc color map
407338b8dc3SIngo Weinhold 	if (error == B_OK) {
408338b8dc3SIngo Weinhold 		fOwnColorMap = new(nothrow) color_map;
409338b8dc3SIngo Weinhold 		if (fOwnColorMap == NULL)
410338b8dc3SIngo Weinhold 			error = B_NO_MEMORY;
411338b8dc3SIngo Weinhold 	}
412338b8dc3SIngo Weinhold 	// init color map
413338b8dc3SIngo Weinhold 	if (error == B_OK) {
414338b8dc3SIngo Weinhold 		fColorMap = fOwnColorMap;
415338b8dc3SIngo Weinhold 		// init color list
416338b8dc3SIngo Weinhold 		memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256);
417338b8dc3SIngo Weinhold 		// init index map
418338b8dc3SIngo Weinhold 		for (int32 color = 0; color < 32768; color++) {
419338b8dc3SIngo Weinhold 			// get components
420338b8dc3SIngo Weinhold 			uint8 red = (color & 0x7c00) >> 7;
421338b8dc3SIngo Weinhold 			uint8 green = (color & 0x3e0) >> 2;
422338b8dc3SIngo Weinhold 			uint8 blue = (color & 0x1f) << 3;
423338b8dc3SIngo Weinhold 			red |= red >> 5;
424338b8dc3SIngo Weinhold 			green |= green >> 5;
425338b8dc3SIngo Weinhold 			blue |= blue >> 5;
426338b8dc3SIngo Weinhold 			// find closest color
427338b8dc3SIngo Weinhold 			uint8 closestIndex = 0;
428338b8dc3SIngo Weinhold 			unsigned closestDistance = UINT_MAX;
429338b8dc3SIngo Weinhold 			for (int32 i = 0; i < 256; i++) {
430338b8dc3SIngo Weinhold 				const rgb_color &c = fOwnColorMap->color_list[i];
431338b8dc3SIngo Weinhold 				unsigned distance = color_distance(red, green, blue,
432338b8dc3SIngo Weinhold 												   c.red, c.green, c.blue);
433338b8dc3SIngo Weinhold 				if (distance < closestDistance) {
434338b8dc3SIngo Weinhold 					closestIndex = i;
435338b8dc3SIngo Weinhold 					closestDistance = distance;
436338b8dc3SIngo Weinhold 				}
437338b8dc3SIngo Weinhold 			}
438338b8dc3SIngo Weinhold 			fOwnColorMap->index_map[color] = closestIndex;
439338b8dc3SIngo Weinhold 		}
440338b8dc3SIngo Weinhold 		// no need to init inversion map
441338b8dc3SIngo Weinhold 	}
442338b8dc3SIngo Weinhold 	fCStatus = error;
443338b8dc3SIngo Weinhold 	return error;
444338b8dc3SIngo Weinhold }
445338b8dc3SIngo Weinhold 
44664b2d169SAxel Dörfler 
447338b8dc3SIngo Weinhold /*!	\brief Initializes the converter to the supplied color map.
448338b8dc3SIngo Weinhold 	\param colorMap The completely initialized color map.
449338b8dc3SIngo Weinhold 	\return \c B_OK, if everything went fine, an error code otherwise.
450338b8dc3SIngo Weinhold */
451338b8dc3SIngo Weinhold status_t
452338b8dc3SIngo Weinhold PaletteConverter::SetTo(const color_map *colorMap)
453338b8dc3SIngo Weinhold {
454338b8dc3SIngo Weinhold 	// cleanup
455338b8dc3SIngo Weinhold 	if (fOwnColorMap) {
456338b8dc3SIngo Weinhold 		delete fOwnColorMap;
457338b8dc3SIngo Weinhold 		fOwnColorMap = NULL;
458338b8dc3SIngo Weinhold 	}
459338b8dc3SIngo Weinhold 	// set
460338b8dc3SIngo Weinhold 	fColorMap = colorMap;
46164b2d169SAxel Dörfler 	fCStatus = fColorMap ? B_OK : B_BAD_VALUE;
462338b8dc3SIngo Weinhold 	return fCStatus;
463338b8dc3SIngo Weinhold }
464338b8dc3SIngo Weinhold 
46564b2d169SAxel Dörfler 
466338b8dc3SIngo Weinhold /*!	\brief Returns the result of the last initialization via constructor or
467338b8dc3SIngo Weinhold 		   SetTo().
468338b8dc3SIngo Weinhold 	\return \c B_OK, if the converter is properly initialized, an error code
469338b8dc3SIngo Weinhold 			otherwise.
470338b8dc3SIngo Weinhold */
471338b8dc3SIngo Weinhold status_t
472338b8dc3SIngo Weinhold PaletteConverter::InitCheck() const
473338b8dc3SIngo Weinhold {
474338b8dc3SIngo Weinhold 	return fCStatus;
475338b8dc3SIngo Weinhold }
476338b8dc3SIngo Weinhold 
47764b2d169SAxel Dörfler 
478338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 15 color.
479338b8dc3SIngo Weinhold 
480338b8dc3SIngo Weinhold 	The object must be properly initialized.
481338b8dc3SIngo Weinhold 
482338b8dc3SIngo Weinhold 	\param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]).
483338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
484338b8dc3SIngo Weinhold */
48564b2d169SAxel Dörfler inline uint8
486338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint16 rgb) const
487338b8dc3SIngo Weinhold {
488338b8dc3SIngo Weinhold 	return fColorMap->index_map[rgb];
489338b8dc3SIngo Weinhold }
490338b8dc3SIngo Weinhold 
49164b2d169SAxel Dörfler 
492338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 15 color.
493338b8dc3SIngo Weinhold 
494338b8dc3SIngo Weinhold 	The object must be properly initialized.
495338b8dc3SIngo Weinhold 
496338b8dc3SIngo Weinhold 	\param red Red component of the color (R[4:0]).
497338b8dc3SIngo Weinhold 	\param green Green component of the color (G[4:0]).
498338b8dc3SIngo Weinhold 	\param blue Blue component of the color (B[4:0]).
499338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
500338b8dc3SIngo Weinhold */
50164b2d169SAxel Dörfler inline uint8
502338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const
503338b8dc3SIngo Weinhold {
504338b8dc3SIngo Weinhold 	// the 5 least significant bits are used
505338b8dc3SIngo Weinhold 	return fColorMap->index_map[(red << 10) | (green << 5) | blue];
506338b8dc3SIngo Weinhold }
507338b8dc3SIngo Weinhold 
50864b2d169SAxel Dörfler 
509338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 16 color.
510338b8dc3SIngo Weinhold 
511338b8dc3SIngo Weinhold 	The object must be properly initialized.
512338b8dc3SIngo Weinhold 
513338b8dc3SIngo Weinhold 	\param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]).
514338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
515338b8dc3SIngo Weinhold */
51664b2d169SAxel Dörfler inline uint8
517338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint16 rgb) const
518338b8dc3SIngo Weinhold {
51964b2d169SAxel Dörfler 	return fColorMap->index_map[((rgb >> 1) & 0x7fe0) | (rgb & 0x1f)];
520338b8dc3SIngo Weinhold }
521338b8dc3SIngo Weinhold 
52264b2d169SAxel Dörfler 
523338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 16 color.
524338b8dc3SIngo Weinhold 
525338b8dc3SIngo Weinhold 	The object must be properly initialized.
526338b8dc3SIngo Weinhold 
527338b8dc3SIngo Weinhold 	\param red Red component of the color (R[4:0]).
528338b8dc3SIngo Weinhold 	\param green Green component of the color (G[5:0]).
529338b8dc3SIngo Weinhold 	\param blue Blue component of the color (B[4:0]).
530338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
531338b8dc3SIngo Weinhold */
53264b2d169SAxel Dörfler inline uint8
533338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const
534338b8dc3SIngo Weinhold {
535338b8dc3SIngo Weinhold 	// the 5 (for red, blue) / 6 (for green) least significant bits are used
536338b8dc3SIngo Weinhold 	return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue];
537338b8dc3SIngo Weinhold }
538338b8dc3SIngo Weinhold 
53964b2d169SAxel Dörfler 
540338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 32 color.
541338b8dc3SIngo Weinhold 
542338b8dc3SIngo Weinhold 	The object must be properly initialized.
543338b8dc3SIngo Weinhold 
544338b8dc3SIngo Weinhold 	\param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]).
545338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
546338b8dc3SIngo Weinhold */
54764b2d169SAxel Dörfler inline uint8
548338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint32 rgb) const
549338b8dc3SIngo Weinhold {
550338b8dc3SIngo Weinhold 	return fColorMap->index_map[((rgb & 0xf8000000) >> 17)
55164b2d169SAxel Dörfler 		| ((rgb & 0xf80000) >> 14) | ((rgb & 0xf800) >> 11)];
552338b8dc3SIngo Weinhold }
553338b8dc3SIngo Weinhold 
55464b2d169SAxel Dörfler 
555338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given RGB 24 color.
556338b8dc3SIngo Weinhold 
557338b8dc3SIngo Weinhold 	The object must be properly initialized.
558338b8dc3SIngo Weinhold 
559338b8dc3SIngo Weinhold 	\param red Red component of the color.
560338b8dc3SIngo Weinhold 	\param green Green component of the color.
561338b8dc3SIngo Weinhold 	\param blue Blue component of the color.
562338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
563338b8dc3SIngo Weinhold */
56464b2d169SAxel Dörfler inline uint8
565338b8dc3SIngo Weinhold PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const
566338b8dc3SIngo Weinhold {
56764b2d169SAxel Dörfler 	return fColorMap->index_map[((red & 0xf8) << 7) | ((green & 0xf8) << 2)
568338b8dc3SIngo Weinhold 		| (blue >> 3)];
569338b8dc3SIngo Weinhold }
570338b8dc3SIngo Weinhold 
57164b2d169SAxel Dörfler 
572338b8dc3SIngo Weinhold /*!	\brief Returns the palette color index closest to a given Gray 8 color.
573338b8dc3SIngo Weinhold 
574338b8dc3SIngo Weinhold 	The object must be properly initialized.
575338b8dc3SIngo Weinhold 
576338b8dc3SIngo Weinhold 	\param gray The Gray 8 color value.
577338b8dc3SIngo Weinhold 	\return The palette color index for the supplied color.
578338b8dc3SIngo Weinhold */
57964b2d169SAxel Dörfler inline uint8
580338b8dc3SIngo Weinhold PaletteConverter::IndexForGray(uint8 gray) const
581338b8dc3SIngo Weinhold {
582338b8dc3SIngo Weinhold 	return IndexForRGB24(gray, gray, gray);
583338b8dc3SIngo Weinhold }
584338b8dc3SIngo Weinhold 
58564b2d169SAxel Dörfler 
586338b8dc3SIngo Weinhold /*!	\brief Returns the RGB color for a given palette color index.
587338b8dc3SIngo Weinhold 
588338b8dc3SIngo Weinhold 	The object must be properly initialized.
589338b8dc3SIngo Weinhold 
590338b8dc3SIngo Weinhold 	\param index The palette color index.
591338b8dc3SIngo Weinhold 	\return The color for the supplied palette color index.
592338b8dc3SIngo Weinhold */
59364b2d169SAxel Dörfler inline const rgb_color &
594338b8dc3SIngo Weinhold PaletteConverter::RGBColorForIndex(uint8 index) const
595338b8dc3SIngo Weinhold {
596338b8dc3SIngo Weinhold 	return fColorMap->color_list[index];
597338b8dc3SIngo Weinhold }
598338b8dc3SIngo Weinhold 
59964b2d169SAxel Dörfler 
600338b8dc3SIngo Weinhold /*!	\brief Returns the RGB 15 color for a given palette color index.
601338b8dc3SIngo Weinhold 
602338b8dc3SIngo Weinhold 	The object must be properly initialized.
603338b8dc3SIngo Weinhold 
604338b8dc3SIngo Weinhold 	\param index The palette color index.
605338b8dc3SIngo Weinhold 	\return The color for the supplied palette color index
606338b8dc3SIngo Weinhold 			(R[14:10]G[9:5]B[4:0]).
607338b8dc3SIngo Weinhold */
60864b2d169SAxel Dörfler inline uint16
609338b8dc3SIngo Weinhold PaletteConverter::RGB15ColorForIndex(uint8 index) const
610338b8dc3SIngo Weinhold {
611338b8dc3SIngo Weinhold 	const rgb_color &color = fColorMap->color_list[index];
61264b2d169SAxel Dörfler 	return ((color.red & 0xf8) << 7) | ((color.green & 0xf8) << 2)
613338b8dc3SIngo Weinhold 		| (color.blue >> 3);
614338b8dc3SIngo Weinhold }
615338b8dc3SIngo Weinhold 
61664b2d169SAxel Dörfler 
617338b8dc3SIngo Weinhold /*!	\brief Returns the RGB 16 color for a given palette color index.
618338b8dc3SIngo Weinhold 
619338b8dc3SIngo Weinhold 	The object must be properly initialized.
620338b8dc3SIngo Weinhold 
621338b8dc3SIngo Weinhold 	\param index The palette color index.
622338b8dc3SIngo Weinhold 	\return The color for the supplied palette color index
623338b8dc3SIngo Weinhold 			(R[15:11]G[10:5]B[4:0]).
624338b8dc3SIngo Weinhold */
62564b2d169SAxel Dörfler inline uint16
626338b8dc3SIngo Weinhold PaletteConverter::RGB16ColorForIndex(uint8 index) const
627338b8dc3SIngo Weinhold {
628338b8dc3SIngo Weinhold 	const rgb_color &color = fColorMap->color_list[index];
62964b2d169SAxel Dörfler 	return ((color.red & 0xf8) << 8) | ((color.green & 0xfc) << 3)
630338b8dc3SIngo Weinhold 		| (color.blue >> 3);
631338b8dc3SIngo Weinhold }
632338b8dc3SIngo Weinhold 
63364b2d169SAxel Dörfler 
634338b8dc3SIngo Weinhold /*!	\brief Returns the RGB 24 color for a given palette color index.
635338b8dc3SIngo Weinhold 
636338b8dc3SIngo Weinhold 	The object must be properly initialized.
637338b8dc3SIngo Weinhold 
638338b8dc3SIngo Weinhold 	\param index The palette color index.
639338b8dc3SIngo Weinhold 	\return The color for the supplied palette color index
640338b8dc3SIngo Weinhold 			(R[31:24]G[23:16]B[15:8]).
641338b8dc3SIngo Weinhold */
64264b2d169SAxel Dörfler inline uint32
643338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index) const
644338b8dc3SIngo Weinhold {
645338b8dc3SIngo Weinhold 	const rgb_color &color = fColorMap->color_list[index];
64664b2d169SAxel Dörfler 	return (color.blue << 24) | (color.red << 8) | (color.green << 16)
64764b2d169SAxel Dörfler 		| color.alpha;
648338b8dc3SIngo Weinhold }
649338b8dc3SIngo Weinhold 
65064b2d169SAxel Dörfler 
651338b8dc3SIngo Weinhold /*!	\brief Returns the RGB 24 color for a given palette color index.
652338b8dc3SIngo Weinhold 
653338b8dc3SIngo Weinhold 	The object must be properly initialized.
654338b8dc3SIngo Weinhold 
655338b8dc3SIngo Weinhold 	\param index The palette color index.
656338b8dc3SIngo Weinhold 	\param red Reference to the variable the red component shall be stored
657338b8dc3SIngo Weinhold 		   into.
658338b8dc3SIngo Weinhold 	\param green Reference to the variable the green component shall be stored
659338b8dc3SIngo Weinhold 		   into.
660338b8dc3SIngo Weinhold 	\param blue Reference to the variable the blue component shall be stored
661338b8dc3SIngo Weinhold 		   into.
662338b8dc3SIngo Weinhold */
66364b2d169SAxel Dörfler inline void
664338b8dc3SIngo Weinhold PaletteConverter::RGB24ColorForIndex(uint8 index, uint8 &red, uint8 &green,
665338b8dc3SIngo Weinhold 	uint8 &blue, uint8 &alpha) const
666338b8dc3SIngo Weinhold {
667338b8dc3SIngo Weinhold 	const rgb_color &color = fColorMap->color_list[index];
668338b8dc3SIngo Weinhold 	red = color.red;
669338b8dc3SIngo Weinhold 	green = color.green;
670338b8dc3SIngo Weinhold 	blue = color.blue;
671338b8dc3SIngo Weinhold 	alpha = color.alpha;
672338b8dc3SIngo Weinhold }
673338b8dc3SIngo Weinhold 
67464b2d169SAxel Dörfler 
675338b8dc3SIngo Weinhold /*!	\brief Returns the Gray 8 color for a given palette color index.
676338b8dc3SIngo Weinhold 
677338b8dc3SIngo Weinhold 	The object must be properly initialized.
678338b8dc3SIngo Weinhold 
679338b8dc3SIngo Weinhold 	\param index The palette color index.
680338b8dc3SIngo Weinhold 	\return The color for the supplied palette color index.
681338b8dc3SIngo Weinhold */
68264b2d169SAxel Dörfler inline uint8
683338b8dc3SIngo Weinhold PaletteConverter::GrayColorForIndex(uint8 index) const
684338b8dc3SIngo Weinhold {
685338b8dc3SIngo Weinhold 	const rgb_color &color = fColorMap->color_list[index];
686338b8dc3SIngo Weinhold 	return brightness_for(color.red, color.green, color.blue);
687338b8dc3SIngo Weinhold }
688338b8dc3SIngo Weinhold 
689338b8dc3SIngo Weinhold // TODO: Remove these and palette_converter() when BScreen is available.
690338b8dc3SIngo Weinhold static BLocker gPaletteConverterLock;
691338b8dc3SIngo Weinhold static PaletteConverter	gPaletteConverter;
692338b8dc3SIngo Weinhold 
69364b2d169SAxel Dörfler 
694338b8dc3SIngo Weinhold /*!	\brief Returns a PaletteConverter using the system color palette.
695338b8dc3SIngo Weinhold 	\return A PaletteConverter.
696338b8dc3SIngo Weinhold */
69764b2d169SAxel Dörfler static const PaletteConverter*
698338b8dc3SIngo Weinhold palette_converter()
699338b8dc3SIngo Weinhold {
700338b8dc3SIngo Weinhold 	if (gPaletteConverterLock.Lock()) {
701338b8dc3SIngo Weinhold 		if (gPaletteConverter.InitCheck() != B_OK)
702338b8dc3SIngo Weinhold 			gPaletteConverter.SetTo(kSystemPalette);
703338b8dc3SIngo Weinhold 		gPaletteConverterLock.Unlock();
704338b8dc3SIngo Weinhold 	}
705338b8dc3SIngo Weinhold 	return &gPaletteConverter;
706338b8dc3SIngo Weinhold }
707338b8dc3SIngo Weinhold 
708338b8dc3SIngo Weinhold 
70964b2d169SAxel Dörfler //	#pragma mark - Reader classes
710338b8dc3SIngo Weinhold 
711338b8dc3SIngo Weinhold 
712338b8dc3SIngo Weinhold // BaseReader
713338b8dc3SIngo Weinhold template<typename _PixelType>
714338b8dc3SIngo Weinhold struct BaseReader {
715338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
716338b8dc3SIngo Weinhold 
717338b8dc3SIngo Weinhold 	BaseReader(const void *data) : pixels((const pixel_t*)data) {}
718338b8dc3SIngo Weinhold 
719338b8dc3SIngo Weinhold 	inline void SetTo(const void *data) { pixels = (const pixel_t*)data; }
720338b8dc3SIngo Weinhold 
721338b8dc3SIngo Weinhold 	inline void NextRow(int32 skip)
722338b8dc3SIngo Weinhold 	{
723338b8dc3SIngo Weinhold 		pixels = (const pixel_t*)((const char*)pixels + skip);
724338b8dc3SIngo Weinhold 	}
725338b8dc3SIngo Weinhold 
726338b8dc3SIngo Weinhold 	const pixel_t *pixels;
727338b8dc3SIngo Weinhold };
728338b8dc3SIngo Weinhold 
729338b8dc3SIngo Weinhold // RGB24Reader
730338b8dc3SIngo Weinhold template<typename _PixelType>
731338b8dc3SIngo Weinhold struct RGB24Reader : public BaseReader<_PixelType> {
732338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
733338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
734338b8dc3SIngo Weinhold 
735338b8dc3SIngo Weinhold 	RGB24Reader(const void *data) : BaseReader<_PixelType>(data) {}
736338b8dc3SIngo Weinhold 
737338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
738338b8dc3SIngo Weinhold 	{
739338b8dc3SIngo Weinhold 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
740338b8dc3SIngo Weinhold 		color.red = pixel.red;
741338b8dc3SIngo Weinhold 		color.green = pixel.green;
742338b8dc3SIngo Weinhold 		color.blue = pixel.blue;
74363d557f0SMichael Lotz 		color.alpha = 255;
744338b8dc3SIngo Weinhold 		BaseReader<_PixelType>::pixels++;
745338b8dc3SIngo Weinhold 	}
746338b8dc3SIngo Weinhold 
747338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
748338b8dc3SIngo Weinhold 	{
749338b8dc3SIngo Weinhold 		rgb_color_value color;
750338b8dc3SIngo Weinhold 		Read(color);
751338b8dc3SIngo Weinhold 		gray = brightness_for(color.red, color.green, color.blue);
752338b8dc3SIngo Weinhold 	}
753338b8dc3SIngo Weinhold };
754338b8dc3SIngo Weinhold 
755338b8dc3SIngo Weinhold // RGB16Reader
756338b8dc3SIngo Weinhold template<typename _PixelType>
757338b8dc3SIngo Weinhold struct RGB16Reader : public BaseReader<_PixelType> {
758338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
759338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
760338b8dc3SIngo Weinhold 
761338b8dc3SIngo Weinhold 	RGB16Reader(const void *data) : BaseReader<_PixelType>(data) {}
762338b8dc3SIngo Weinhold 
763338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
764338b8dc3SIngo Weinhold 	{
765338b8dc3SIngo Weinhold 		// rg: R[4:0],G[5:3]
766338b8dc3SIngo Weinhold 		// gb: G[2:0],B[4:0]
767338b8dc3SIngo Weinhold 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
768338b8dc3SIngo Weinhold 		color.red = pixel.rg & 0xf8;
769338b8dc3SIngo Weinhold 		color.green = ((pixel.rg & 0x07) << 5) & ((pixel.gb & 0xe0) >> 3);
770338b8dc3SIngo Weinhold 		color.blue = (pixel.gb & 0x1f) << 3;
771338b8dc3SIngo Weinhold 		color.red |= color.red >> 5;
772338b8dc3SIngo Weinhold 		color.green |= color.green >> 6;
773338b8dc3SIngo Weinhold 		color.blue |= color.blue >> 5;
77463d557f0SMichael Lotz 		color.alpha = 255;
775338b8dc3SIngo Weinhold 		BaseReader<_PixelType>::pixels++;
776338b8dc3SIngo Weinhold 	}
777338b8dc3SIngo Weinhold 
778338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
779338b8dc3SIngo Weinhold 	{
780338b8dc3SIngo Weinhold 		rgb_color_value color;
781338b8dc3SIngo Weinhold 		Read(color);
782338b8dc3SIngo Weinhold 		gray = brightness_for(color.red, color.green, color.blue);
783338b8dc3SIngo Weinhold 	}
784338b8dc3SIngo Weinhold };
785338b8dc3SIngo Weinhold 
786338b8dc3SIngo Weinhold // RGB15Reader
787338b8dc3SIngo Weinhold template<typename _PixelType>
788338b8dc3SIngo Weinhold struct RGB15Reader : public BaseReader<_PixelType> {
789338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
790338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
791338b8dc3SIngo Weinhold 
792338b8dc3SIngo Weinhold 	RGB15Reader(const void *data) : BaseReader<_PixelType>(data) {}
793338b8dc3SIngo Weinhold 
794338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
795338b8dc3SIngo Weinhold 	{
796338b8dc3SIngo Weinhold 		// rg: -[0],R[4:0],G[4:3]
797338b8dc3SIngo Weinhold 		// gb: G[2:0],B[4:0]
798338b8dc3SIngo Weinhold 		const pixel_t &pixel = *BaseReader<_PixelType>::pixels;
799338b8dc3SIngo Weinhold 		color.red = (pixel.rg & 0x7c) << 1;
800338b8dc3SIngo Weinhold 		color.green = ((pixel.rg & 0x03) << 6) & ((pixel.gb & 0xe0) >> 2);
801338b8dc3SIngo Weinhold 		color.blue = (pixel.gb & 0x1f) << 3;
802338b8dc3SIngo Weinhold 		color.red |= color.red >> 5;
803338b8dc3SIngo Weinhold 		color.green |= color.green >> 5;
804338b8dc3SIngo Weinhold 		color.blue |= color.blue >> 5;
80563d557f0SMichael Lotz 		color.alpha = 255;
806338b8dc3SIngo Weinhold 		BaseReader<_PixelType>::pixels++;
807338b8dc3SIngo Weinhold 	}
808338b8dc3SIngo Weinhold 
809338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
810338b8dc3SIngo Weinhold 	{
811338b8dc3SIngo Weinhold 		rgb_color_value color;
812338b8dc3SIngo Weinhold 		Read(color);
813338b8dc3SIngo Weinhold 		gray = brightness_for(color.red, color.green, color.blue);
814338b8dc3SIngo Weinhold 	}
815338b8dc3SIngo Weinhold };
816338b8dc3SIngo Weinhold 
817338b8dc3SIngo Weinhold // CMAP8Reader
818338b8dc3SIngo Weinhold struct CMAP8Reader : public BaseReader<uint8> {
819338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
820338b8dc3SIngo Weinhold 
821338b8dc3SIngo Weinhold 	CMAP8Reader(const void *data, const PaletteConverter &converter)
822338b8dc3SIngo Weinhold 		: BaseReader<uint8>(data), converter(converter) {}
823338b8dc3SIngo Weinhold 
824338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
825338b8dc3SIngo Weinhold 	{
826338b8dc3SIngo Weinhold 		converter.RGB24ColorForIndex(*BaseReader<uint8>::pixels, color.red, color.green,
827338b8dc3SIngo Weinhold 									 color.blue, color.alpha);
828338b8dc3SIngo Weinhold 		BaseReader<uint8>::pixels++;
829338b8dc3SIngo Weinhold 	}
830338b8dc3SIngo Weinhold 
831338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
832338b8dc3SIngo Weinhold 	{
833338b8dc3SIngo Weinhold 		gray = converter.GrayColorForIndex(*BaseReader<uint8>::pixels);
834338b8dc3SIngo Weinhold 		BaseReader<uint8>::pixels++;
835338b8dc3SIngo Weinhold 	}
836338b8dc3SIngo Weinhold 
837338b8dc3SIngo Weinhold 	const PaletteConverter &converter;
838338b8dc3SIngo Weinhold };
839338b8dc3SIngo Weinhold 
840338b8dc3SIngo Weinhold // Gray8Reader
841338b8dc3SIngo Weinhold struct Gray8Reader : public BaseReader<uint8> {
842338b8dc3SIngo Weinhold 	typedef gray_color_value	preferred_color_value_t;
843338b8dc3SIngo Weinhold 
844338b8dc3SIngo Weinhold 	Gray8Reader(const void *data) : BaseReader<uint8>(data) {}
845338b8dc3SIngo Weinhold 
846338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
847338b8dc3SIngo Weinhold 	{
848338b8dc3SIngo Weinhold 		color.red = color.green = color.blue = *BaseReader<uint8>::pixels;
84963d557f0SMichael Lotz 		color.alpha = 255;
850338b8dc3SIngo Weinhold 		BaseReader<uint8>::pixels++;
851338b8dc3SIngo Weinhold 	}
852338b8dc3SIngo Weinhold 
853338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
854338b8dc3SIngo Weinhold 	{
855338b8dc3SIngo Weinhold 		gray = *BaseReader<uint8>::pixels;
856338b8dc3SIngo Weinhold 		BaseReader<uint8>::pixels++;
857338b8dc3SIngo Weinhold 	}
858338b8dc3SIngo Weinhold };
859338b8dc3SIngo Weinhold 
860338b8dc3SIngo Weinhold // Gray1Reader
861338b8dc3SIngo Weinhold struct Gray1Reader : public BaseReader<uint8> {
862338b8dc3SIngo Weinhold 	typedef gray_color_value	preferred_color_value_t;
863338b8dc3SIngo Weinhold 
864338b8dc3SIngo Weinhold 	Gray1Reader(const void *data) : BaseReader<uint8>(data), bit(7) {}
865338b8dc3SIngo Weinhold 
866338b8dc3SIngo Weinhold 	inline void SetTo(const void *data)
867338b8dc3SIngo Weinhold 	{
868338b8dc3SIngo Weinhold 		pixels = (const pixel_t*)data;
869338b8dc3SIngo Weinhold 		bit = 7;
870338b8dc3SIngo Weinhold 	}
871338b8dc3SIngo Weinhold 
872338b8dc3SIngo Weinhold 	inline void NextRow(int32 skip)
873338b8dc3SIngo Weinhold 	{
874338b8dc3SIngo Weinhold 		if (bit == 7)
875338b8dc3SIngo Weinhold 			pixels = (const pixel_t*)((const char*)pixels + skip);
876338b8dc3SIngo Weinhold 		else {
877338b8dc3SIngo Weinhold 			pixels = (const pixel_t*)((const char*)pixels + skip + 1);
878338b8dc3SIngo Weinhold 			bit = 7;
879338b8dc3SIngo Weinhold 		}
880338b8dc3SIngo Weinhold 	}
881338b8dc3SIngo Weinhold 
882338b8dc3SIngo Weinhold 	inline void Read(rgb_color_value &color)
883338b8dc3SIngo Weinhold 	{
884338b8dc3SIngo Weinhold 		if (*pixels & bit_mask(bit))
885338b8dc3SIngo Weinhold 			color.red = color.green = color.blue = 255;
886338b8dc3SIngo Weinhold 		else
887338b8dc3SIngo Weinhold 			color.red = color.green = color.blue = 0;
88863d557f0SMichael Lotz 		color.alpha = 255;
889338b8dc3SIngo Weinhold 		bit--;
890338b8dc3SIngo Weinhold 		if (bit == -1) {
891338b8dc3SIngo Weinhold 			pixels++;
892338b8dc3SIngo Weinhold 			bit = 7;
893338b8dc3SIngo Weinhold 		}
894338b8dc3SIngo Weinhold 	}
895338b8dc3SIngo Weinhold 
896338b8dc3SIngo Weinhold 	inline void Read(gray_color_value &gray)
897338b8dc3SIngo Weinhold 	{
898338b8dc3SIngo Weinhold 		if (*pixels & bit_mask(bit))
899338b8dc3SIngo Weinhold 			gray = 255;
900338b8dc3SIngo Weinhold 		else
901338b8dc3SIngo Weinhold 			gray = 0;
902338b8dc3SIngo Weinhold 		bit--;
903338b8dc3SIngo Weinhold 		if (bit == -1) {
904338b8dc3SIngo Weinhold 			pixels++;
905338b8dc3SIngo Weinhold 			bit = 7;
906338b8dc3SIngo Weinhold 		}
907338b8dc3SIngo Weinhold 	}
908338b8dc3SIngo Weinhold 
909338b8dc3SIngo Weinhold 	int32 bit;
910338b8dc3SIngo Weinhold };
911338b8dc3SIngo Weinhold 
912338b8dc3SIngo Weinhold 
91364b2d169SAxel Dörfler //	#pragma mark - Writer classes
91464b2d169SAxel Dörfler 
915338b8dc3SIngo Weinhold 
916338b8dc3SIngo Weinhold // BaseWriter
917338b8dc3SIngo Weinhold template<typename _PixelType>
918338b8dc3SIngo Weinhold struct BaseWriter {
919338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
920338b8dc3SIngo Weinhold 
921338b8dc3SIngo Weinhold 	BaseWriter(void *data) : pixels((pixel_t*)data) {}
922338b8dc3SIngo Weinhold 
923338b8dc3SIngo Weinhold 	inline void SetTo(void *data) { pixels = (pixel_t*)data; }
924338b8dc3SIngo Weinhold 
925338b8dc3SIngo Weinhold 	pixel_t *pixels;
926338b8dc3SIngo Weinhold };
927338b8dc3SIngo Weinhold 
928338b8dc3SIngo Weinhold 
929338b8dc3SIngo Weinhold // RGB32Writer
930338b8dc3SIngo Weinhold template<typename _PixelType>
931338b8dc3SIngo Weinhold struct RGB32Writer : public BaseWriter<_PixelType> {
932338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
933338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
934338b8dc3SIngo Weinhold 
935338b8dc3SIngo Weinhold 	RGB32Writer(void *data) : BaseWriter<_PixelType>(data) {}
936338b8dc3SIngo Weinhold 
937338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
938338b8dc3SIngo Weinhold 	{
939338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
940338b8dc3SIngo Weinhold 		pixel.red = color.red;
941338b8dc3SIngo Weinhold 		pixel.green = color.green;
942338b8dc3SIngo Weinhold 		pixel.blue = color.blue;
943338b8dc3SIngo Weinhold 		pixel.alpha = color.alpha;
944338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
945338b8dc3SIngo Weinhold 	}
946338b8dc3SIngo Weinhold 
947338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
948338b8dc3SIngo Weinhold 	{
949338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
950338b8dc3SIngo Weinhold 		pixel.red = gray;
951338b8dc3SIngo Weinhold 		pixel.green = gray;
952338b8dc3SIngo Weinhold 		pixel.blue = gray;
953338b8dc3SIngo Weinhold 		pixel.alpha = 255;
954338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
955338b8dc3SIngo Weinhold 	}
956338b8dc3SIngo Weinhold };
957338b8dc3SIngo Weinhold 
958338b8dc3SIngo Weinhold // RGB24Writer
959338b8dc3SIngo Weinhold template<typename _PixelType>
960338b8dc3SIngo Weinhold struct RGB24Writer : public BaseWriter<_PixelType> {
961338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
962338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
963338b8dc3SIngo Weinhold 
964338b8dc3SIngo Weinhold 	RGB24Writer(void *data) : BaseWriter<_PixelType>(data) {}
965338b8dc3SIngo Weinhold 
966338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
967338b8dc3SIngo Weinhold 	{
968338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
969338b8dc3SIngo Weinhold 		pixel.red = color.red;
970338b8dc3SIngo Weinhold 		pixel.green = color.green;
971338b8dc3SIngo Weinhold 		pixel.blue = color.blue;
972338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
973338b8dc3SIngo Weinhold 	}
974338b8dc3SIngo Weinhold 
975338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
976338b8dc3SIngo Weinhold 	{
977338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
978338b8dc3SIngo Weinhold 		pixel.red = gray;
979338b8dc3SIngo Weinhold 		pixel.green = gray;
980338b8dc3SIngo Weinhold 		pixel.blue = gray;
981338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
982338b8dc3SIngo Weinhold 	}
983338b8dc3SIngo Weinhold };
984338b8dc3SIngo Weinhold 
985338b8dc3SIngo Weinhold // RGB16Writer
986338b8dc3SIngo Weinhold template<typename _PixelType>
987338b8dc3SIngo Weinhold struct RGB16Writer : public BaseWriter<_PixelType> {
988338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
989338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
990338b8dc3SIngo Weinhold 
991338b8dc3SIngo Weinhold 	RGB16Writer(void *data) : BaseWriter<_PixelType>(data) {}
992338b8dc3SIngo Weinhold 
993338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
994338b8dc3SIngo Weinhold 	{
995338b8dc3SIngo Weinhold 		// rg: R[4:0],G[5:3]
996338b8dc3SIngo Weinhold 		// gb: G[2:0],B[4:0]
997338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
998338b8dc3SIngo Weinhold 		pixel.rg = (color.red & 0xf8) | (color.green >> 5);
999338b8dc3SIngo Weinhold 		pixel.gb = ((color.green & 0x1c) << 3) | (color.blue >> 3);
1000338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
1001338b8dc3SIngo Weinhold 	}
1002338b8dc3SIngo Weinhold 
1003338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
1004338b8dc3SIngo Weinhold 	{
1005338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1006338b8dc3SIngo Weinhold 		pixel.rg = (gray & 0xf8) | (gray >> 5);
1007338b8dc3SIngo Weinhold 		pixel.gb = ((gray & 0x1c) << 3) | (gray >> 3);
1008338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
1009338b8dc3SIngo Weinhold 	}
1010338b8dc3SIngo Weinhold };
1011338b8dc3SIngo Weinhold 
1012338b8dc3SIngo Weinhold // RGB15Writer
1013338b8dc3SIngo Weinhold template<typename _PixelType>
1014338b8dc3SIngo Weinhold struct RGB15Writer : public BaseWriter<_PixelType> {
1015338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
1016338b8dc3SIngo Weinhold 	typedef _PixelType		pixel_t;
1017338b8dc3SIngo Weinhold 
1018338b8dc3SIngo Weinhold 	RGB15Writer(void *data) : BaseWriter<_PixelType>(data) {}
1019338b8dc3SIngo Weinhold 
1020338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
1021338b8dc3SIngo Weinhold 	{
1022338b8dc3SIngo Weinhold 		// rg: -[0],R[4:0],G[4:3]
1023338b8dc3SIngo Weinhold 		// gb: G[2:0],B[4:0]
1024338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1025338b8dc3SIngo Weinhold 		pixel.rg = ((color.red & 0xf8) >> 1) | (color.green >> 6);
1026338b8dc3SIngo Weinhold 		pixel.gb = ((color.green & 0x38) << 2) | (color.blue >> 3);
1027338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
1028338b8dc3SIngo Weinhold 	}
1029338b8dc3SIngo Weinhold 
1030338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
1031338b8dc3SIngo Weinhold 	{
1032338b8dc3SIngo Weinhold 		pixel_t &pixel = *BaseWriter<_PixelType>::pixels;
1033338b8dc3SIngo Weinhold 		pixel.rg = ((gray & 0xf8) >> 1) | (gray >> 6);
1034338b8dc3SIngo Weinhold 		pixel.gb = ((gray & 0x38) << 2) | (gray >> 3);
1035338b8dc3SIngo Weinhold 		BaseWriter<_PixelType>::pixels++;
1036338b8dc3SIngo Weinhold 	}
1037338b8dc3SIngo Weinhold };
1038338b8dc3SIngo Weinhold 
1039338b8dc3SIngo Weinhold // CMAP8Writer
1040338b8dc3SIngo Weinhold struct CMAP8Writer : public BaseWriter<uint8> {
1041338b8dc3SIngo Weinhold 	typedef rgb_color_value	preferred_color_value_t;
1042338b8dc3SIngo Weinhold 
1043338b8dc3SIngo Weinhold 	CMAP8Writer(void *data, const PaletteConverter &converter)
1044338b8dc3SIngo Weinhold 		: BaseWriter<uint8>(data), converter(converter) {}
1045338b8dc3SIngo Weinhold 
1046338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
1047338b8dc3SIngo Weinhold 	{
1048338b8dc3SIngo Weinhold 		*pixels = converter.IndexForRGB24(color.red, color.green, color.blue);
1049338b8dc3SIngo Weinhold 		pixels++;
1050338b8dc3SIngo Weinhold 	}
1051338b8dc3SIngo Weinhold 
1052338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
1053338b8dc3SIngo Weinhold 	{
1054338b8dc3SIngo Weinhold 		*pixels = converter.IndexForGray(gray);
1055338b8dc3SIngo Weinhold 		pixels++;
1056338b8dc3SIngo Weinhold 	}
1057338b8dc3SIngo Weinhold 
1058338b8dc3SIngo Weinhold 	const PaletteConverter &converter;
1059338b8dc3SIngo Weinhold };
1060338b8dc3SIngo Weinhold 
1061338b8dc3SIngo Weinhold // Gray8Writer
1062338b8dc3SIngo Weinhold struct Gray8Writer : public BaseWriter<uint8> {
1063338b8dc3SIngo Weinhold 	typedef gray_color_value	preferred_color_value_t;
1064338b8dc3SIngo Weinhold 
1065338b8dc3SIngo Weinhold 	Gray8Writer(void *data) : BaseWriter<uint8>(data) {}
1066338b8dc3SIngo Weinhold 
1067338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
1068338b8dc3SIngo Weinhold 	{
1069338b8dc3SIngo Weinhold 		*pixels = brightness_for(color.red, color.green, color.blue);
1070338b8dc3SIngo Weinhold 		pixels++;
1071338b8dc3SIngo Weinhold 	}
1072338b8dc3SIngo Weinhold 
1073338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
1074338b8dc3SIngo Weinhold 	{
1075338b8dc3SIngo Weinhold 		*pixels = gray;
1076338b8dc3SIngo Weinhold 		pixels++;
1077338b8dc3SIngo Weinhold 	}
1078338b8dc3SIngo Weinhold };
1079338b8dc3SIngo Weinhold 
1080338b8dc3SIngo Weinhold // Gray1Writer
1081338b8dc3SIngo Weinhold struct Gray1Writer : public BaseWriter<uint8> {
1082338b8dc3SIngo Weinhold 	typedef gray_color_value	preferred_color_value_t;
1083338b8dc3SIngo Weinhold 
1084338b8dc3SIngo Weinhold 	Gray1Writer(void *data) : BaseWriter<uint8>(data), bit(7) {}
1085338b8dc3SIngo Weinhold 
1086338b8dc3SIngo Weinhold 	inline void SetTo(void *data) { pixels = (pixel_t*)data; bit = 7; }
1087338b8dc3SIngo Weinhold 
1088338b8dc3SIngo Weinhold 	inline void Write(const gray_color_value &gray)
1089338b8dc3SIngo Weinhold 	{
1090338b8dc3SIngo Weinhold 		*pixels = (*pixels & inverse_bit_mask(bit))
1091338b8dc3SIngo Weinhold 				  | (gray & 0x80) >> (7 - bit);
1092338b8dc3SIngo Weinhold 		bit--;
1093338b8dc3SIngo Weinhold 		if (bit == -1) {
1094338b8dc3SIngo Weinhold 			pixels++;
1095338b8dc3SIngo Weinhold 			bit = 7;
1096338b8dc3SIngo Weinhold 		}
1097338b8dc3SIngo Weinhold 	}
1098338b8dc3SIngo Weinhold 
1099338b8dc3SIngo Weinhold 	inline void Write(const rgb_color_value &color)
1100338b8dc3SIngo Weinhold 	{
1101338b8dc3SIngo Weinhold 		Write(brightness_for(color.red, color.green, color.blue));
1102338b8dc3SIngo Weinhold 	}
1103338b8dc3SIngo Weinhold 
1104338b8dc3SIngo Weinhold 	int32 bit;
1105338b8dc3SIngo Weinhold };
1106338b8dc3SIngo Weinhold 
1107338b8dc3SIngo Weinhold 
1108338b8dc3SIngo Weinhold // set_bits_worker
1109338b8dc3SIngo Weinhold /*!	\brief Worker function that reads bitmap data from one buffer and writes
1110338b8dc3SIngo Weinhold 		   it (converted) to another one.
1111338b8dc3SIngo Weinhold 	\param Reader The pixel reader class.
1112338b8dc3SIngo Weinhold 	\param Writer The pixel writer class.
1113338b8dc3SIngo Weinhold 	\param color_value_t The color value type used to transport a pixel from
1114338b8dc3SIngo Weinhold 		   the reader to the writer.
1115338b8dc3SIngo Weinhold 	\param inData A pointer to the buffer to be read.
1116338b8dc3SIngo Weinhold 	\param inLength The length (in bytes) of the "in" buffer.
1117338b8dc3SIngo Weinhold 	\param inBPR The number of bytes per row in the "in" buffer.
1118338b8dc3SIngo Weinhold 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1119338b8dc3SIngo Weinhold 		   padding.
1120338b8dc3SIngo Weinhold 	\param outData A pointer to the buffer to be written to.
1121338b8dc3SIngo Weinhold 	\param outLength The length (in bytes) of the "out" buffer.
1122338b8dc3SIngo Weinhold 	\param outOffset The offset (in bytes) relative to \a outData from which
1123338b8dc3SIngo Weinhold 		   the function shall start writing.
1124338b8dc3SIngo Weinhold 	\param outBPR The number of bytes per row in the "out" buffer.
1125338b8dc3SIngo Weinhold 	\param rawOutBPR The number of bytes per row in the "out" buffer actually
1126338b8dc3SIngo Weinhold 		   containing bitmap data (i.e. not including the padding).
1127338b8dc3SIngo Weinhold 	\param _reader A reader object. The pointer to the data doesn't need to
1128338b8dc3SIngo Weinhold 		   be initialized.
1129338b8dc3SIngo Weinhold 	\param _writer A writer object. The pointer to the data doesn't need to
1130338b8dc3SIngo Weinhold 		   be initialized.
1131338b8dc3SIngo Weinhold 	\return \c B_OK, if everything went fine, an error code otherwise.
1132338b8dc3SIngo Weinhold */
1133338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t>
1134338b8dc3SIngo Weinhold static
1135338b8dc3SIngo Weinhold status_t
1136338b8dc3SIngo Weinhold set_bits_worker(const void *inData, int32 inLength, int32 inBPR,
1137338b8dc3SIngo Weinhold 				int32 inRowSkip, void *outData, int32 outLength,
1138338b8dc3SIngo Weinhold 				int32 outOffset, int32 outBPR, int32 rawOutBPR,
1139338b8dc3SIngo Weinhold 				Reader _reader, Writer _writer)
1140338b8dc3SIngo Weinhold {
1141338b8dc3SIngo Weinhold 	status_t error = B_OK;
1142338b8dc3SIngo Weinhold 	Reader reader(_reader);
1143338b8dc3SIngo Weinhold 	Writer writer(_writer);
1144338b8dc3SIngo Weinhold 	reader.SetTo(inData);
1145338b8dc3SIngo Weinhold 	writer.SetTo((char*)outData + outOffset);
1146338b8dc3SIngo Weinhold 	const char *inEnd = (const char*)inData + inLength
1147338b8dc3SIngo Weinhold 						- sizeof(typename Reader::pixel_t);
1148338b8dc3SIngo Weinhold 	const char *inLastRow = (const char*)inData + inLength
1149338b8dc3SIngo Weinhold 							- (inBPR - inRowSkip);
1150338b8dc3SIngo Weinhold 	const char *outEnd = (const char*)outData + outLength
1151338b8dc3SIngo Weinhold 						 - sizeof(typename Writer::pixel_t);
1152338b8dc3SIngo Weinhold 	char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1153338b8dc3SIngo Weinhold 	const char *outRowEnd = outRow + rawOutBPR - sizeof(typename Writer::pixel_t);
1154338b8dc3SIngo Weinhold 	while ((const char*)reader.pixels <= inEnd
1155338b8dc3SIngo Weinhold 		   && (const char*)writer.pixels <= outEnd) {
1156338b8dc3SIngo Weinhold 		// process one row
1157338b8dc3SIngo Weinhold 		if ((const char*)reader.pixels <= inLastRow) {
1158338b8dc3SIngo Weinhold 			// at least a complete row left
1159338b8dc3SIngo Weinhold 			while ((const char*)writer.pixels <= outRowEnd) {
1160338b8dc3SIngo Weinhold 				color_value_t color;
1161338b8dc3SIngo Weinhold 				reader.Read(color);
1162338b8dc3SIngo Weinhold 				writer.Write(color);
1163338b8dc3SIngo Weinhold 			}
1164338b8dc3SIngo Weinhold 		} else {
1165338b8dc3SIngo Weinhold 			// no complete row left
1166338b8dc3SIngo Weinhold 			// but maybe the complete end of the first row
1167338b8dc3SIngo Weinhold 			while ((const char*)reader.pixels <= inEnd
1168338b8dc3SIngo Weinhold 				   && (const char*)writer.pixels <= outRowEnd) {
1169338b8dc3SIngo Weinhold 				color_value_t color;
1170338b8dc3SIngo Weinhold 				reader.Read(color);
1171338b8dc3SIngo Weinhold 				writer.Write(color);
1172338b8dc3SIngo Weinhold 			}
1173338b8dc3SIngo Weinhold 		}
1174338b8dc3SIngo Weinhold 		// must be here, not in the if-branch (end of first row)
1175338b8dc3SIngo Weinhold 		outRow += outBPR;
1176338b8dc3SIngo Weinhold 		outRowEnd += outBPR;
1177338b8dc3SIngo Weinhold 		reader.NextRow(inRowSkip);
1178338b8dc3SIngo Weinhold 		writer.SetTo(outRow);
1179338b8dc3SIngo Weinhold 	}
1180338b8dc3SIngo Weinhold 	return error;
1181338b8dc3SIngo Weinhold }
1182338b8dc3SIngo Weinhold 
1183338b8dc3SIngo Weinhold // set_bits_worker_gray1
1184338b8dc3SIngo Weinhold /*!	\brief Worker function that reads bitmap data from one buffer and writes
1185338b8dc3SIngo Weinhold 		   it (converted) to another one, which uses color space \c B_GRAY1.
1186338b8dc3SIngo Weinhold 	\param Reader The pixel reader class.
1187338b8dc3SIngo Weinhold 	\param Writer The pixel writer class.
1188338b8dc3SIngo Weinhold 	\param color_value_t The color value type used to transport a pixel from
1189338b8dc3SIngo Weinhold 		   the reader to the writer.
1190338b8dc3SIngo Weinhold 	\param inData A pointer to the buffer to be read.
1191338b8dc3SIngo Weinhold 	\param inLength The length (in bytes) of the "in" buffer.
1192338b8dc3SIngo Weinhold 	\param inBPR The number of bytes per row in the "in" buffer.
1193338b8dc3SIngo Weinhold 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1194338b8dc3SIngo Weinhold 		   padding.
1195338b8dc3SIngo Weinhold 	\param outData A pointer to the buffer to be written to.
1196338b8dc3SIngo Weinhold 	\param outLength The length (in bytes) of the "out" buffer.
1197338b8dc3SIngo Weinhold 	\param outOffset The offset (in bytes) relative to \a outData from which
1198338b8dc3SIngo Weinhold 		   the function shall start writing.
1199338b8dc3SIngo Weinhold 	\param outBPR The number of bytes per row in the "out" buffer.
1200338b8dc3SIngo Weinhold 	\param width The number of pixels per row in "in" and "out" data.
1201338b8dc3SIngo Weinhold 	\param _reader A reader object. The pointer to the data doesn't need to
1202338b8dc3SIngo Weinhold 		   be initialized.
1203338b8dc3SIngo Weinhold 	\param _writer A writer object. The pointer to the data doesn't need to
1204338b8dc3SIngo Weinhold 		   be initialized.
1205338b8dc3SIngo Weinhold 	\return \c B_OK, if everything went fine, an error code otherwise.
1206338b8dc3SIngo Weinhold */
1207338b8dc3SIngo Weinhold template<typename Reader, typename Writer, typename color_value_t>
1208338b8dc3SIngo Weinhold static
1209338b8dc3SIngo Weinhold status_t
1210338b8dc3SIngo Weinhold set_bits_worker_gray1(const void *inData, int32 inLength, int32 inBPR,
1211338b8dc3SIngo Weinhold 					  int32 inRowSkip, void *outData, int32 outLength,
1212338b8dc3SIngo Weinhold 					  int32 outOffset, int32 outBPR, int32 width,
1213338b8dc3SIngo Weinhold 					  Reader _reader, Writer _writer)
1214338b8dc3SIngo Weinhold {
1215338b8dc3SIngo Weinhold 	status_t error = B_OK;
1216338b8dc3SIngo Weinhold 	Reader reader(_reader);
1217338b8dc3SIngo Weinhold 	Writer writer(_writer);
1218338b8dc3SIngo Weinhold 	reader.SetTo(inData);
1219338b8dc3SIngo Weinhold 	writer.SetTo((char*)outData + outOffset);
1220338b8dc3SIngo Weinhold 	const char *inEnd = (const char*)inData + inLength
1221338b8dc3SIngo Weinhold 						- sizeof(typename Reader::pixel_t);
1222338b8dc3SIngo Weinhold 	const char *inLastRow = (const char*)inData + inLength
1223338b8dc3SIngo Weinhold 							- (inBPR - inRowSkip);
1224338b8dc3SIngo Weinhold 	const char *outEnd = (const char*)outData + outLength - outBPR;
1225338b8dc3SIngo Weinhold 	char *outRow = (char*)outData + outOffset - outOffset % outBPR;
1226*a8a03488SIngo Weinhold 	int32 x = max((int32)0,
1227*a8a03488SIngo Weinhold 		width - (int32)((char*)outData + outOffset - outRow) * 8) - 1;
1228338b8dc3SIngo Weinhold 	while ((const char*)reader.pixels <= inEnd
1229338b8dc3SIngo Weinhold 		   && (const char*)writer.pixels <= outEnd) {
1230338b8dc3SIngo Weinhold 		// process one row
1231338b8dc3SIngo Weinhold 		if ((const char*)reader.pixels <= inLastRow) {
1232338b8dc3SIngo Weinhold 			// at least a complete row left
1233338b8dc3SIngo Weinhold 			while (x >= 0) {
1234338b8dc3SIngo Weinhold 				color_value_t color;
1235338b8dc3SIngo Weinhold 				reader.Read(color);
1236338b8dc3SIngo Weinhold 				writer.Write(color);
1237338b8dc3SIngo Weinhold 				x--;
1238338b8dc3SIngo Weinhold 			}
1239338b8dc3SIngo Weinhold 		} else {
1240338b8dc3SIngo Weinhold 			// no complete row left
1241338b8dc3SIngo Weinhold 			// but maybe the complete end of the first row
1242338b8dc3SIngo Weinhold 			while ((const char*)reader.pixels <= inEnd && x >= 0) {
1243338b8dc3SIngo Weinhold 				color_value_t color;
1244338b8dc3SIngo Weinhold 				reader.Read(color);
1245338b8dc3SIngo Weinhold 				writer.Write(color);
1246338b8dc3SIngo Weinhold 				x--;
1247338b8dc3SIngo Weinhold 			}
1248338b8dc3SIngo Weinhold 		}
1249338b8dc3SIngo Weinhold 		// must be here, not in the if-branch (end of first row)
1250338b8dc3SIngo Weinhold 		x = width - 1;
1251338b8dc3SIngo Weinhold 		outRow += outBPR;
1252338b8dc3SIngo Weinhold 		reader.NextRow(inRowSkip);
1253338b8dc3SIngo Weinhold 		writer.SetTo(outRow);
1254338b8dc3SIngo Weinhold 	}
1255338b8dc3SIngo Weinhold 	return error;
1256338b8dc3SIngo Weinhold }
1257338b8dc3SIngo Weinhold 
1258338b8dc3SIngo Weinhold // set_bits
1259338b8dc3SIngo Weinhold /*!	\brief Helper function that reads bitmap data from one buffer and writes
1260338b8dc3SIngo Weinhold 		   it (converted) to another one.
1261338b8dc3SIngo Weinhold 	\param Reader The pixel reader class.
1262338b8dc3SIngo Weinhold 	\param inData A pointer to the buffer to be read.
1263338b8dc3SIngo Weinhold 	\param inLength The length (in bytes) of the "in" buffer.
1264338b8dc3SIngo Weinhold 	\param inBPR The number of bytes per row in the "in" buffer.
1265338b8dc3SIngo Weinhold 	\param inRowSkip The number of bytes per row in the "in" buffer serving as
1266338b8dc3SIngo Weinhold 		   padding.
1267338b8dc3SIngo Weinhold 	\param outData A pointer to the buffer to be written to.
1268338b8dc3SIngo Weinhold 	\param outLength The length (in bytes) of the "out" buffer.
1269338b8dc3SIngo Weinhold 	\param outOffset The offset (in bytes) relative to \a outData from which
1270338b8dc3SIngo Weinhold 		   the function shall start writing.
1271338b8dc3SIngo Weinhold 	\param outBPR The number of bytes per row in the "out" buffer.
1272338b8dc3SIngo Weinhold 	\param rawOutBPR The number of bytes per row in the "out" buffer actually
1273338b8dc3SIngo Weinhold 		   containing bitmap data (i.e. not including the padding).
1274338b8dc3SIngo Weinhold 	\param outColorSpace Color space of the target buffer.
1275338b8dc3SIngo Weinhold 	\param width The number of pixels per row in "in" and "out" data.
1276338b8dc3SIngo Weinhold 	\param reader A reader object. The pointer to the data doesn't need to
1277338b8dc3SIngo Weinhold 		   be initialized.
1278338b8dc3SIngo Weinhold 	\param paletteConverter Reference to a PaletteConverter to be used, if
1279338b8dc3SIngo Weinhold 		   a conversion from or to \c B_CMAP8 has to be done.
1280338b8dc3SIngo Weinhold 	\return \c B_OK, if everything went fine, an error code otherwise.
1281338b8dc3SIngo Weinhold */
1282338b8dc3SIngo Weinhold template<typename Reader>
1283338b8dc3SIngo Weinhold static
1284338b8dc3SIngo Weinhold status_t
1285338b8dc3SIngo Weinhold set_bits(const void *inData, int32 inLength, int32 inBPR, int32 inRowSkip,
1286338b8dc3SIngo Weinhold 		 void *outData, int32 outLength, int32 outOffset, int32 outBPR,
1287338b8dc3SIngo Weinhold 		 int32 rawOutBPR, color_space outColorSpace, int32 width,
1288338b8dc3SIngo Weinhold 		 Reader reader, const PaletteConverter &paletteConverter)
1289338b8dc3SIngo Weinhold {
1290338b8dc3SIngo Weinhold 	status_t error = B_OK;
1291338b8dc3SIngo Weinhold 	switch (outColorSpace) {
1292338b8dc3SIngo Weinhold 		// supported
1293338b8dc3SIngo Weinhold 		case B_RGB32: case B_RGBA32:
1294338b8dc3SIngo Weinhold 		{
1295338b8dc3SIngo Weinhold 			typedef RGB32Writer<rgb32_pixel> Writer;
1296338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1297338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1298338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1299338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1300338b8dc3SIngo Weinhold 			break;
1301338b8dc3SIngo Weinhold 		}
1302338b8dc3SIngo Weinhold 		case B_RGB32_BIG: case B_RGBA32_BIG:
1303338b8dc3SIngo Weinhold 		{
1304338b8dc3SIngo Weinhold 			typedef RGB32Writer<rgb32_big_pixel> Writer;
1305338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1306338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1307338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1308338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1309338b8dc3SIngo Weinhold 			break;
1310338b8dc3SIngo Weinhold 		}
1311338b8dc3SIngo Weinhold 		case B_RGB24:
1312338b8dc3SIngo Weinhold 		{
1313338b8dc3SIngo Weinhold 			typedef RGB24Writer<rgb24_pixel> Writer;
1314338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1315338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1316338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1317338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1318338b8dc3SIngo Weinhold 			break;
1319338b8dc3SIngo Weinhold 		}
1320338b8dc3SIngo Weinhold 		case B_RGB24_BIG:
1321338b8dc3SIngo Weinhold 		{
1322338b8dc3SIngo Weinhold 			typedef RGB24Writer<rgb24_big_pixel> Writer;
1323338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1324338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1325338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1326338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1327338b8dc3SIngo Weinhold 			break;
1328338b8dc3SIngo Weinhold 		}
1329338b8dc3SIngo Weinhold 		case B_RGB16:
1330338b8dc3SIngo Weinhold 		{
1331338b8dc3SIngo Weinhold 			typedef RGB16Writer<rgb16_pixel> Writer;
1332338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1333338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1334338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1335338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1336338b8dc3SIngo Weinhold 			break;
1337338b8dc3SIngo Weinhold 		}
1338338b8dc3SIngo Weinhold 		case B_RGB16_BIG:
1339338b8dc3SIngo Weinhold 		{
1340338b8dc3SIngo Weinhold 			typedef RGB16Writer<rgb16_big_pixel> Writer;
1341338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1342338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1343338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1344338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1345338b8dc3SIngo Weinhold 			break;
1346338b8dc3SIngo Weinhold 		}
1347338b8dc3SIngo Weinhold 		case B_RGB15: case B_RGBA15:
1348338b8dc3SIngo Weinhold 		{
1349338b8dc3SIngo Weinhold 			typedef RGB15Writer<rgb16_pixel> Writer;
1350338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1351338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1352338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1353338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1354338b8dc3SIngo Weinhold 			break;
1355338b8dc3SIngo Weinhold 		}
1356338b8dc3SIngo Weinhold 		case B_RGB15_BIG: case B_RGBA15_BIG:
1357338b8dc3SIngo Weinhold 		{
1358338b8dc3SIngo Weinhold 			typedef RGB15Writer<rgb16_big_pixel> Writer;
1359338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1360338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1361338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1362338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1363338b8dc3SIngo Weinhold 			break;
1364338b8dc3SIngo Weinhold 		}
1365338b8dc3SIngo Weinhold 		case B_CMAP8:
1366338b8dc3SIngo Weinhold 		{
1367338b8dc3SIngo Weinhold 			typedef CMAP8Writer Writer;
1368338b8dc3SIngo Weinhold 			typedef typename Reader::preferred_color_value_t color_value_t;
1369338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1370338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1371338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader,
1372338b8dc3SIngo Weinhold 				Writer(outData, paletteConverter));
1373338b8dc3SIngo Weinhold 			break;
1374338b8dc3SIngo Weinhold 		}
1375338b8dc3SIngo Weinhold 		case B_GRAY8:
1376338b8dc3SIngo Weinhold 		{
1377338b8dc3SIngo Weinhold 			typedef Gray8Writer Writer;
1378338b8dc3SIngo Weinhold 			typedef gray_color_value color_value_t;
1379338b8dc3SIngo Weinhold 			error = set_bits_worker<Reader, Writer, color_value_t>(
1380338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1381338b8dc3SIngo Weinhold 				outOffset, outBPR, rawOutBPR, reader, Writer(outData));
1382338b8dc3SIngo Weinhold 			break;
1383338b8dc3SIngo Weinhold 		}
1384338b8dc3SIngo Weinhold 		case B_GRAY1:
1385338b8dc3SIngo Weinhold 		{
1386338b8dc3SIngo Weinhold 			typedef Gray1Writer Writer;
1387338b8dc3SIngo Weinhold 			typedef gray_color_value color_value_t;
1388338b8dc3SIngo Weinhold 			error = set_bits_worker_gray1<Reader, Writer, color_value_t>(
1389338b8dc3SIngo Weinhold 				inData, inLength, inBPR, inRowSkip, outData, outLength,
1390338b8dc3SIngo Weinhold 				outOffset, outBPR, width, reader, Writer(outData));
1391338b8dc3SIngo Weinhold 			break;
1392338b8dc3SIngo Weinhold 		}
1393338b8dc3SIngo Weinhold 		// unsupported
1394338b8dc3SIngo Weinhold 		case B_NO_COLOR_SPACE:
1395338b8dc3SIngo Weinhold 		case B_YUV9: case B_YUV12:
1396338b8dc3SIngo Weinhold 		case B_UVL32: case B_UVLA32:
1397338b8dc3SIngo Weinhold 		case B_LAB32: case B_LABA32:
1398338b8dc3SIngo Weinhold 		case B_HSI32: case B_HSIA32:
1399338b8dc3SIngo Weinhold 		case B_HSV32: case B_HSVA32:
1400338b8dc3SIngo Weinhold 		case B_HLS32: case B_HLSA32:
1401338b8dc3SIngo Weinhold 		case B_CMY32: case B_CMYA32: case B_CMYK32:
1402338b8dc3SIngo Weinhold 		case B_UVL24: case B_LAB24: case B_HSI24:
1403338b8dc3SIngo Weinhold 		case B_HSV24: case B_HLS24: case B_CMY24:
1404338b8dc3SIngo Weinhold 		case B_YCbCr422: case B_YUV422:
1405338b8dc3SIngo Weinhold 		case B_YCbCr411: case B_YUV411:
1406338b8dc3SIngo Weinhold 		case B_YCbCr444: case B_YUV444:
1407338b8dc3SIngo Weinhold 		case B_YCbCr420: case B_YUV420:
1408338b8dc3SIngo Weinhold 		default:
1409338b8dc3SIngo Weinhold 			error = B_BAD_VALUE;
1410338b8dc3SIngo Weinhold 			break;
1411338b8dc3SIngo Weinhold 	}
1412338b8dc3SIngo Weinhold 	return error;
1413338b8dc3SIngo Weinhold }
1414338b8dc3SIngo Weinhold 
141564b2d169SAxel Dörfler 
141664b2d169SAxel Dörfler //	#pragma mark - Bitmap
141764b2d169SAxel Dörfler 
141864b2d169SAxel Dörfler 
141964b2d169SAxel Dörfler /*!	\brief Creates and initializes a BBitmap.
142064b2d169SAxel Dörfler 	\param bounds The bitmap dimensions.
142164b2d169SAxel Dörfler 	\param flags Creation flags.
142264b2d169SAxel Dörfler 	\param colorSpace The bitmap's color space.
142364b2d169SAxel Dörfler 	\param bytesPerRow The number of bytes per row the bitmap should use.
142464b2d169SAxel Dörfler 		   \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
142564b2d169SAxel Dörfler 		   value.
142664b2d169SAxel Dörfler 	\param screenID ???
142764b2d169SAxel Dörfler */
142864b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, uint32 flags, color_space colorSpace,
142964b2d169SAxel Dörfler 		int32 bytesPerRow, screen_id screenID)
143064b2d169SAxel Dörfler 	: fBasePtr(NULL),
143164b2d169SAxel Dörfler 	  fSize(0),
143264b2d169SAxel Dörfler 	  fColorSpace(B_NO_COLOR_SPACE),
143364b2d169SAxel Dörfler 	  fBounds(0, 0, -1, -1),
143464b2d169SAxel Dörfler 	  fBytesPerRow(0),
143564b2d169SAxel Dörfler 	  fServerToken(-1),
143664b2d169SAxel Dörfler 	  fToken(-1),
143764b2d169SAxel Dörfler 	  fArea(-1),
143864b2d169SAxel Dörfler 	  fOrigArea(-1),
143964b2d169SAxel Dörfler 	  fFlags(0),
144064b2d169SAxel Dörfler 	  fInitError(B_NO_INIT)
144164b2d169SAxel Dörfler {
144264b2d169SAxel Dörfler 	InitObject(bounds, colorSpace, flags, bytesPerRow, screenID);
144364b2d169SAxel Dörfler }
144464b2d169SAxel Dörfler 
144564b2d169SAxel Dörfler 
144664b2d169SAxel Dörfler /*!	\brief Creates and initializes a BBitmap.
144764b2d169SAxel Dörfler 	\param bounds The bitmap dimensions.
144864b2d169SAxel Dörfler 	\param colorSpace The bitmap's color space.
144964b2d169SAxel Dörfler 	\param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
145064b2d169SAxel Dörfler 		   it shall be possible to attach BView to the bitmap and draw into
145164b2d169SAxel Dörfler 		   it.
145264b2d169SAxel Dörfler 	\param needsContiguous If \c true a physically contiguous chunk of memory
145364b2d169SAxel Dörfler 		   will be allocated.
145464b2d169SAxel Dörfler */
145564b2d169SAxel Dörfler BBitmap::BBitmap(BRect bounds, color_space colorSpace, bool acceptsViews,
145664b2d169SAxel Dörfler 		bool needsContiguous)
145764b2d169SAxel Dörfler 	: fBasePtr(NULL),
145864b2d169SAxel Dörfler 	  fSize(0),
145964b2d169SAxel Dörfler 	  fColorSpace(B_NO_COLOR_SPACE),
146064b2d169SAxel Dörfler 	  fBounds(0, 0, -1, -1),
146164b2d169SAxel Dörfler 	  fBytesPerRow(0),
146264b2d169SAxel Dörfler 	  fServerToken(-1),
146364b2d169SAxel Dörfler 	  fToken(-1),
146464b2d169SAxel Dörfler 	  fArea(-1),
146564b2d169SAxel Dörfler 	  fOrigArea(-1),
146664b2d169SAxel Dörfler 	  fFlags(0),
146764b2d169SAxel Dörfler 	  fInitError(B_NO_INIT)
146864b2d169SAxel Dörfler {
146964b2d169SAxel Dörfler 	int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
147064b2d169SAxel Dörfler 				| (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
147164b2d169SAxel Dörfler 	InitObject(bounds, colorSpace, flags, B_ANY_BYTES_PER_ROW,
147264b2d169SAxel Dörfler 			   B_MAIN_SCREEN_ID);
147364b2d169SAxel Dörfler 
147464b2d169SAxel Dörfler }
147564b2d169SAxel Dörfler 
147664b2d169SAxel Dörfler 
147764b2d169SAxel Dörfler /*!	\brief Creates a BBitmap as a clone of another bitmap.
147864b2d169SAxel Dörfler 	\param source The source bitmap.
147964b2d169SAxel Dörfler 	\param acceptsViews \c true, if the bitmap shall accept BViews, i.e. if
148064b2d169SAxel Dörfler 		   it shall be possible to attach BView to the bitmap and draw into
148164b2d169SAxel Dörfler 		   it.
148264b2d169SAxel Dörfler 	\param needsContiguous If \c true a physically contiguous chunk of memory
148364b2d169SAxel Dörfler 		   will be allocated.
148464b2d169SAxel Dörfler */
148564b2d169SAxel Dörfler BBitmap::BBitmap(const BBitmap *source, bool acceptsViews,
148664b2d169SAxel Dörfler 		bool needsContiguous)
148764b2d169SAxel Dörfler 	: fBasePtr(NULL),
148864b2d169SAxel Dörfler 	  fSize(0),
148964b2d169SAxel Dörfler 	  fColorSpace(B_NO_COLOR_SPACE),
149064b2d169SAxel Dörfler 	  fBounds(0, 0, -1, -1),
149164b2d169SAxel Dörfler 	  fBytesPerRow(0),
149264b2d169SAxel Dörfler 	  fServerToken(-1),
149364b2d169SAxel Dörfler 	  fToken(-1),
149464b2d169SAxel Dörfler 	  fArea(-1),
149564b2d169SAxel Dörfler 	  fOrigArea(-1),
149664b2d169SAxel Dörfler 	  fFlags(0),
149764b2d169SAxel Dörfler 	  fInitError(B_NO_INIT)
149864b2d169SAxel Dörfler {
149964b2d169SAxel Dörfler 	if (source && source->IsValid()) {
150064b2d169SAxel Dörfler 		int32 flags = (acceptsViews ? B_BITMAP_ACCEPTS_VIEWS : 0)
150164b2d169SAxel Dörfler 			| (needsContiguous ? B_BITMAP_IS_CONTIGUOUS : 0);
150264b2d169SAxel Dörfler 		InitObject(source->Bounds(), source->ColorSpace(), flags,
150364b2d169SAxel Dörfler 			source->BytesPerRow(), B_MAIN_SCREEN_ID);
150464b2d169SAxel Dörfler 		if (InitCheck() == B_OK)
150564b2d169SAxel Dörfler 			memcpy(Bits(), source->Bits(), BytesPerRow());
150664b2d169SAxel Dörfler 	}
150764b2d169SAxel Dörfler }
150864b2d169SAxel Dörfler 
150964b2d169SAxel Dörfler 
151064b2d169SAxel Dörfler /*!	\brief Frees all resources associated with this object. */
151164b2d169SAxel Dörfler BBitmap::~BBitmap()
151264b2d169SAxel Dörfler {
151364b2d169SAxel Dörfler 	CleanUp();
151464b2d169SAxel Dörfler }
151564b2d169SAxel Dörfler 
151664b2d169SAxel Dörfler 
151764b2d169SAxel Dörfler /*!	\brief Unarchives a bitmap from a BMessage.
151864b2d169SAxel Dörfler 	\param data The archive.
151964b2d169SAxel Dörfler */
152064b2d169SAxel Dörfler BBitmap::BBitmap(BMessage *data)
152164b2d169SAxel Dörfler 	: BArchivable(data),
152264b2d169SAxel Dörfler 	  fBasePtr(NULL),
152364b2d169SAxel Dörfler 	  fSize(0),
152464b2d169SAxel Dörfler 	  fColorSpace(B_NO_COLOR_SPACE),
152564b2d169SAxel Dörfler 	  fBounds(0, 0, -1, -1),
152664b2d169SAxel Dörfler 	  fBytesPerRow(0),
152764b2d169SAxel Dörfler 	  fServerToken(-1),
152864b2d169SAxel Dörfler 	  fToken(-1),
152964b2d169SAxel Dörfler 	  fArea(-1),
153064b2d169SAxel Dörfler 	  fOrigArea(-1),
153164b2d169SAxel Dörfler 	  fFlags(0),
153264b2d169SAxel Dörfler 	  fInitError(B_NO_INIT)
153364b2d169SAxel Dörfler {
153464b2d169SAxel Dörfler 	BRect bounds;
153564b2d169SAxel Dörfler 	data->FindRect("_frame", &bounds);
153664b2d169SAxel Dörfler 
153764b2d169SAxel Dörfler 	color_space cspace;
153864b2d169SAxel Dörfler 	data->FindInt32("_cspace", (int32 *)&cspace);
153964b2d169SAxel Dörfler 
154064b2d169SAxel Dörfler 	int32 flags = 0;
154164b2d169SAxel Dörfler 	data->FindInt32("_bmflags", &flags);
154264b2d169SAxel Dörfler 
154364b2d169SAxel Dörfler 	int32 rowbytes = 0;
154464b2d169SAxel Dörfler 	data->FindInt32("_rowbytes", &rowbytes);
154564b2d169SAxel Dörfler 
154664b2d169SAxel Dörfler flags |= B_BITMAP_NO_SERVER_LINK;
154764b2d169SAxel Dörfler flags &= ~B_BITMAP_ACCEPTS_VIEWS;
154864b2d169SAxel Dörfler 	InitObject(bounds, cspace, flags, rowbytes, B_MAIN_SCREEN_ID);
154964b2d169SAxel Dörfler 
155064b2d169SAxel Dörfler 	if (data->HasData("_data", B_RAW_TYPE) && InitCheck() == B_OK) {
155164b2d169SAxel Dörfler 			ssize_t size = 0;
155264b2d169SAxel Dörfler 			const void *buffer;
155364b2d169SAxel Dörfler 			if (data->FindData("_data", B_RAW_TYPE, &buffer, &size) == B_OK)
155464b2d169SAxel Dörfler 				memcpy(fBasePtr, buffer, size);
155564b2d169SAxel Dörfler 	}
155664b2d169SAxel Dörfler 
155764b2d169SAxel Dörfler 	if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
155864b2d169SAxel Dörfler // 		BArchivable *obj;
155964b2d169SAxel Dörfler // 		BMessage message;
156064b2d169SAxel Dörfler // 		int i = 0;
156164b2d169SAxel Dörfler //
156264b2d169SAxel Dörfler // 		while (data->FindMessage("_view", i++, &message) == B_OK) {
156364b2d169SAxel Dörfler // 			obj = instantiate_object(&message);
156464b2d169SAxel Dörfler // 			BView *view = dynamic_cast<BView *>(obj);
156564b2d169SAxel Dörfler //
156664b2d169SAxel Dörfler // 			if (view)
156764b2d169SAxel Dörfler // 				AddChild(view);
156864b2d169SAxel Dörfler // 		}
156964b2d169SAxel Dörfler 	}
157064b2d169SAxel Dörfler }
157164b2d169SAxel Dörfler 
157264b2d169SAxel Dörfler 
157364b2d169SAxel Dörfler /*!	\brief Instantiates a BBitmap from an archive.
157464b2d169SAxel Dörfler 	\param data The archive.
157564b2d169SAxel Dörfler 	\return A bitmap reconstructed from the archive or \c NULL, if an error
157664b2d169SAxel Dörfler 			occured.
157764b2d169SAxel Dörfler */
157864b2d169SAxel Dörfler BArchivable *
157964b2d169SAxel Dörfler BBitmap::Instantiate(BMessage *data)
158064b2d169SAxel Dörfler {
158164b2d169SAxel Dörfler 	if (validate_instantiation(data, "BBitmap"))
158264b2d169SAxel Dörfler 		return new BBitmap(data);
158364b2d169SAxel Dörfler 
158464b2d169SAxel Dörfler 	return NULL;
158564b2d169SAxel Dörfler }
158664b2d169SAxel Dörfler 
158764b2d169SAxel Dörfler 
158864b2d169SAxel Dörfler /*!	\brief Archives the BBitmap object.
158964b2d169SAxel Dörfler 	\param data The archive.
159064b2d169SAxel Dörfler 	\param deep \c true, if child object shall be archived as well, \c false
159164b2d169SAxel Dörfler 		   otherwise.
159264b2d169SAxel Dörfler 	\return \c B_OK, if everything went fine, an error code otherwise.
159364b2d169SAxel Dörfler */
159464b2d169SAxel Dörfler status_t
159564b2d169SAxel Dörfler BBitmap::Archive(BMessage *data, bool deep) const
159664b2d169SAxel Dörfler {
159764b2d169SAxel Dörfler 	BArchivable::Archive(data, deep);
159864b2d169SAxel Dörfler 
159964b2d169SAxel Dörfler 	data->AddRect("_frame", fBounds);
160064b2d169SAxel Dörfler 	data->AddInt32("_cspace", (int32)fColorSpace);
160164b2d169SAxel Dörfler 	data->AddInt32("_bmflags", fFlags);
160264b2d169SAxel Dörfler 	data->AddInt32("_rowbytes", fBytesPerRow);
160364b2d169SAxel Dörfler 
160464b2d169SAxel Dörfler 	if (deep) {
160564b2d169SAxel Dörfler 		if (fFlags & B_BITMAP_ACCEPTS_VIEWS) {
160664b2d169SAxel Dörfler //			BMessage views;
160764b2d169SAxel Dörfler // 			for (int32 i = 0; i < CountChildren(); i++) {
160864b2d169SAxel Dörfler // 				if (ChildAt(i)->Archive(&views, deep))
160964b2d169SAxel Dörfler // 					data->AddMessage("_views", &views);
161064b2d169SAxel Dörfler // 			}
161164b2d169SAxel Dörfler 		}
161264b2d169SAxel Dörfler 		// Note: R5 does not archive the data if B_BITMAP_IS_CONTIGNUOUS is
161364b2d169SAxel Dörfler 		// true and it does save all formats as B_RAW_TYPE and it does save
161464b2d169SAxel Dörfler 		// the data even if B_BITMAP_ACCEPTS_VIEWS is set (as opposed to
161564b2d169SAxel Dörfler 		// the BeBook)
161664b2d169SAxel Dörfler 
161764b2d169SAxel Dörfler 		data->AddData("_data", B_RAW_TYPE, fBasePtr, fSize);
161864b2d169SAxel Dörfler 	}
161964b2d169SAxel Dörfler 
162064b2d169SAxel Dörfler 	return B_OK;
162164b2d169SAxel Dörfler }
162264b2d169SAxel Dörfler 
162364b2d169SAxel Dörfler 
162464b2d169SAxel Dörfler /*!	\brief Returns the result from the construction.
162564b2d169SAxel Dörfler 	\return \c B_OK, if the object is properly initialized, an error code
162664b2d169SAxel Dörfler 			otherwise.
162764b2d169SAxel Dörfler */
162864b2d169SAxel Dörfler status_t
162964b2d169SAxel Dörfler BBitmap::InitCheck() const
163064b2d169SAxel Dörfler {
163164b2d169SAxel Dörfler 	return fInitError;
163264b2d169SAxel Dörfler }
163364b2d169SAxel Dörfler 
163464b2d169SAxel Dörfler 
163564b2d169SAxel Dörfler /*!	\brief Returns whether or not the BBitmap object is valid.
163664b2d169SAxel Dörfler 	\return \c true, if the object is properly initialized, \c false otherwise.
163764b2d169SAxel Dörfler */
163864b2d169SAxel Dörfler bool
163964b2d169SAxel Dörfler BBitmap::IsValid() const
164064b2d169SAxel Dörfler {
164164b2d169SAxel Dörfler 	return (InitCheck() == B_OK);
164264b2d169SAxel Dörfler }
164364b2d169SAxel Dörfler 
164464b2d169SAxel Dörfler 
164564b2d169SAxel Dörfler status_t
164664b2d169SAxel Dörfler BBitmap::LockBits(uint32 *state)
164764b2d169SAxel Dörfler {
164864b2d169SAxel Dörfler 	return B_ERROR;
164964b2d169SAxel Dörfler }
165064b2d169SAxel Dörfler 
165164b2d169SAxel Dörfler 
165264b2d169SAxel Dörfler void
165364b2d169SAxel Dörfler BBitmap::UnlockBits()
165464b2d169SAxel Dörfler {
165564b2d169SAxel Dörfler }
165664b2d169SAxel Dörfler 
165764b2d169SAxel Dörfler 
165864b2d169SAxel Dörfler /*! \brief Returns the ID of the area the bitmap data reside in.
165964b2d169SAxel Dörfler 	\return The ID of the area the bitmap data reside in.
166064b2d169SAxel Dörfler */
166164b2d169SAxel Dörfler area_id
166264b2d169SAxel Dörfler BBitmap::Area() const
166364b2d169SAxel Dörfler {
166464b2d169SAxel Dörfler 	return fArea;
166564b2d169SAxel Dörfler }
166664b2d169SAxel Dörfler 
166764b2d169SAxel Dörfler 
166864b2d169SAxel Dörfler /*!	\brief Returns the pointer to the bitmap data.
166964b2d169SAxel Dörfler 	\return The pointer to the bitmap data.
167064b2d169SAxel Dörfler */
167164b2d169SAxel Dörfler void *
167264b2d169SAxel Dörfler BBitmap::Bits() const
167364b2d169SAxel Dörfler {
167464b2d169SAxel Dörfler 	return fBasePtr;
167564b2d169SAxel Dörfler }
167664b2d169SAxel Dörfler 
167764b2d169SAxel Dörfler 
167864b2d169SAxel Dörfler /*!	\brief Returns the size of the bitmap data.
167964b2d169SAxel Dörfler 	\return The size of the bitmap data.
168064b2d169SAxel Dörfler */
168164b2d169SAxel Dörfler int32
168264b2d169SAxel Dörfler BBitmap::BitsLength() const
168364b2d169SAxel Dörfler {
168464b2d169SAxel Dörfler 	return fSize;
168564b2d169SAxel Dörfler }
168664b2d169SAxel Dörfler 
168764b2d169SAxel Dörfler 
168864b2d169SAxel Dörfler /*!	\brief Returns the number of bytes used to store a row of bitmap data.
168964b2d169SAxel Dörfler 	\return The number of bytes used to store a row of bitmap data.
169064b2d169SAxel Dörfler */
169164b2d169SAxel Dörfler int32
169264b2d169SAxel Dörfler BBitmap::BytesPerRow() const
169364b2d169SAxel Dörfler {
169464b2d169SAxel Dörfler 	return fBytesPerRow;
169564b2d169SAxel Dörfler }
169664b2d169SAxel Dörfler 
169764b2d169SAxel Dörfler 
169864b2d169SAxel Dörfler /*!	\brief Returns the bitmap's color space.
169964b2d169SAxel Dörfler 	\return The bitmap's color space.
170064b2d169SAxel Dörfler */
170164b2d169SAxel Dörfler color_space
170264b2d169SAxel Dörfler BBitmap::ColorSpace() const
170364b2d169SAxel Dörfler {
170464b2d169SAxel Dörfler 	return fColorSpace;
170564b2d169SAxel Dörfler }
170664b2d169SAxel Dörfler 
170764b2d169SAxel Dörfler 
170864b2d169SAxel Dörfler /*!	\brief Returns the bitmap's dimensions.
170964b2d169SAxel Dörfler 	\return The bitmap's dimensions.
171064b2d169SAxel Dörfler */
171164b2d169SAxel Dörfler BRect
171264b2d169SAxel Dörfler BBitmap::Bounds() const
171364b2d169SAxel Dörfler {
171464b2d169SAxel Dörfler 	return fBounds;
171564b2d169SAxel Dörfler }
171664b2d169SAxel Dörfler 
171764b2d169SAxel Dörfler 
1718338b8dc3SIngo Weinhold /*!	\brief Assigns data to the bitmap.
1719338b8dc3SIngo Weinhold 
1720338b8dc3SIngo Weinhold 	Data are directly written into the bitmap's data buffer, being converted
1721338b8dc3SIngo Weinhold 	beforehand, if necessary. Some conversions work rather unintuitively:
1722338b8dc3SIngo Weinhold 	- \c B_RGB32: The source buffer is supposed to contain \c B_RGB24_BIG
1723338b8dc3SIngo Weinhold 	  data without padding at the end of the rows.
1724338b8dc3SIngo Weinhold 	- \c B_RGB32: The source buffer is supposed to contain \c B_CMAP8
1725338b8dc3SIngo Weinhold 	  data without padding at the end of the rows.
1726338b8dc3SIngo Weinhold 	- other color spaces: The source buffer is supposed to contain data
1727338b8dc3SIngo Weinhold 	  according to the specified color space being rowwise padded to int32.
1728338b8dc3SIngo Weinhold 
1729338b8dc3SIngo Weinhold 	The currently supported source/target color spaces are
1730338b8dc3SIngo Weinhold 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1731338b8dc3SIngo Weinhold 
1732338b8dc3SIngo Weinhold 	\note As this methods is apparently a bit strange to use, OBOS introduces
1733338b8dc3SIngo Weinhold 		  ImportBits() methods, which are recommended to be used instead.
1734338b8dc3SIngo Weinhold 
1735338b8dc3SIngo Weinhold 	\param data The data to be copied.
1736338b8dc3SIngo Weinhold 	\param length The length in bytes of the data to be copied.
1737338b8dc3SIngo Weinhold 	\param offset The offset (in bytes) relative to beginning of the bitmap
1738338b8dc3SIngo Weinhold 		   data specifying the position at which the source data shall be
1739338b8dc3SIngo Weinhold 		   written.
1740338b8dc3SIngo Weinhold 	\param colorSpace Color space of the source data.
1741338b8dc3SIngo Weinhold */
1742338b8dc3SIngo Weinhold void
1743338b8dc3SIngo Weinhold BBitmap::SetBits(const void *data, int32 length, int32 offset,
1744338b8dc3SIngo Weinhold 	color_space colorSpace)
1745338b8dc3SIngo Weinhold {
1746338b8dc3SIngo Weinhold 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1747338b8dc3SIngo Weinhold 	// check params
1748338b8dc3SIngo Weinhold 	if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1749338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
1750338b8dc3SIngo Weinhold 	int32 width = 0;
1751338b8dc3SIngo Weinhold 	if (error == B_OK)
1752338b8dc3SIngo Weinhold 		width = fBounds.IntegerWidth() + 1;
1753338b8dc3SIngo Weinhold 	int32 inBPR = -1;
1754338b8dc3SIngo Weinhold 	// tweaks to mimic R5 behavior
1755338b8dc3SIngo Weinhold 	if (error == B_OK) {
1756338b8dc3SIngo Weinhold 		// B_RGB32 means actually unpadded B_RGB24_BIG
1757338b8dc3SIngo Weinhold 		if (colorSpace == B_RGB32) {
1758338b8dc3SIngo Weinhold 			colorSpace = B_RGB24_BIG;
1759338b8dc3SIngo Weinhold 			inBPR = width * 3;
1760338b8dc3SIngo Weinhold 		// If in color space is B_CMAP8, but the bitmap's is another one,
1761338b8dc3SIngo Weinhold 		// ignore source data row padding.
1762338b8dc3SIngo Weinhold 		} else if (colorSpace == B_CMAP8 && fColorSpace != B_CMAP8)
1763338b8dc3SIngo Weinhold 			inBPR = width;
1764338b8dc3SIngo Weinhold 	}
1765338b8dc3SIngo Weinhold 	// call the sane method, which does the actual work
1766338b8dc3SIngo Weinhold 	if (error == B_OK)
1767338b8dc3SIngo Weinhold 		error = ImportBits(data, length, inBPR, offset, colorSpace);
1768338b8dc3SIngo Weinhold }
1769338b8dc3SIngo Weinhold 
177064b2d169SAxel Dörfler 
1771338b8dc3SIngo Weinhold /*!	\brief Assigns data to the bitmap.
1772338b8dc3SIngo Weinhold 
1773338b8dc3SIngo Weinhold 	Data are directly written into the bitmap's data buffer, being converted
1774338b8dc3SIngo Weinhold 	beforehand, if necessary. Unlike for SetBits(), the meaning of
1775338b8dc3SIngo Weinhold 	\a colorSpace is exactly the expected one here, i.e. the source buffer
1776338b8dc3SIngo Weinhold 	is supposed to contain data of that color space. \a bpr specifies how
1777338b8dc3SIngo Weinhold 	many bytes the source contains per row. \c B_ANY_BYTES_PER_ROW can be
1778338b8dc3SIngo Weinhold 	supplied, if standard padding to int32 is used.
1779338b8dc3SIngo Weinhold 
1780338b8dc3SIngo Weinhold 	The currently supported source/target color spaces are
1781338b8dc3SIngo Weinhold 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1782338b8dc3SIngo Weinhold 
1783338b8dc3SIngo Weinhold 	\param data The data to be copied.
1784338b8dc3SIngo Weinhold 	\param length The length in bytes of the data to be copied.
1785338b8dc3SIngo Weinhold 	\param bpr The number of bytes per row in the source data.
1786338b8dc3SIngo Weinhold 	\param offset The offset (in bytes) relative to beginning of the bitmap
1787338b8dc3SIngo Weinhold 		   data specifying the position at which the source data shall be
1788338b8dc3SIngo Weinhold 		   written.
1789338b8dc3SIngo Weinhold 	\param colorSpace Color space of the source data.
1790338b8dc3SIngo Weinhold 	\return
1791338b8dc3SIngo Weinhold 	- \c B_OK: Everything went fine.
1792338b8dc3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a data, invalid \a bpr or \a offset, or
1793338b8dc3SIngo Weinhold 	  unsupported \a colorSpace.
1794338b8dc3SIngo Weinhold */
1795338b8dc3SIngo Weinhold status_t
1796338b8dc3SIngo Weinhold BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset,
1797338b8dc3SIngo Weinhold 	color_space colorSpace)
1798338b8dc3SIngo Weinhold {
1799338b8dc3SIngo Weinhold 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1800338b8dc3SIngo Weinhold 	// check params
1801338b8dc3SIngo Weinhold 	if (error == B_OK && (data == NULL || offset > fSize || length < 0))
1802338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
1803338b8dc3SIngo Weinhold 	// get BPR
1804338b8dc3SIngo Weinhold 	int32 width = 0;
1805338b8dc3SIngo Weinhold 	int32 inRowSkip = 0;
1806338b8dc3SIngo Weinhold 	if (error == B_OK) {
1807338b8dc3SIngo Weinhold 		width = fBounds.IntegerWidth() + 1;
1808338b8dc3SIngo Weinhold 		if (bpr < 0)
1809338b8dc3SIngo Weinhold 			bpr = get_bytes_per_row(colorSpace, width);
1810338b8dc3SIngo Weinhold 		inRowSkip = bpr - get_raw_bytes_per_row(colorSpace, width);
1811338b8dc3SIngo Weinhold 		if (inRowSkip < 0)
1812338b8dc3SIngo Weinhold 			error = B_BAD_VALUE;
1813338b8dc3SIngo Weinhold 	}
1814338b8dc3SIngo Weinhold 	if (error != B_OK) {
1815338b8dc3SIngo Weinhold 		// catch error case
1816338b8dc3SIngo Weinhold 	} else if (colorSpace == fColorSpace && bpr == fBytesPerRow) {
1817338b8dc3SIngo Weinhold 		length = min(length, fSize - offset);
1818338b8dc3SIngo Weinhold 		memcpy((char*)fBasePtr + offset, data, length);
1819338b8dc3SIngo Weinhold 	} else {
1820338b8dc3SIngo Weinhold 		// TODO: Retrieve color map from BScreen, when available:
1821338b8dc3SIngo Weinhold 		// PaletteConverter paletteConverter(BScreen().ColorMap());
1822338b8dc3SIngo Weinhold 		const PaletteConverter &paletteConverter = *palette_converter();
1823338b8dc3SIngo Weinhold 		int32 rawOutBPR = get_raw_bytes_per_row(fColorSpace, width);
1824338b8dc3SIngo Weinhold 		switch (colorSpace) {
1825338b8dc3SIngo Weinhold 			// supported
1826338b8dc3SIngo Weinhold 			case B_RGB32: case B_RGBA32:
1827338b8dc3SIngo Weinhold 			{
1828338b8dc3SIngo Weinhold 				typedef RGB24Reader<rgb32_pixel> Reader;
1829338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1830338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1831338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1832338b8dc3SIngo Weinhold 				break;
1833338b8dc3SIngo Weinhold 			}
1834338b8dc3SIngo Weinhold 			case B_RGB32_BIG: case B_RGBA32_BIG:
1835338b8dc3SIngo Weinhold 			{
1836338b8dc3SIngo Weinhold 				typedef RGB24Reader<rgb32_big_pixel> Reader;
1837338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1838338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1839338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1840338b8dc3SIngo Weinhold 				break;
1841338b8dc3SIngo Weinhold 			}
1842338b8dc3SIngo Weinhold 			case B_RGB24:
1843338b8dc3SIngo Weinhold 			{
1844338b8dc3SIngo Weinhold 				typedef RGB24Reader<rgb24_pixel> Reader;
1845338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1846338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1847338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1848338b8dc3SIngo Weinhold 				break;
1849338b8dc3SIngo Weinhold 			}
1850338b8dc3SIngo Weinhold 			case B_RGB24_BIG:
1851338b8dc3SIngo Weinhold 			{
1852338b8dc3SIngo Weinhold 				typedef RGB24Reader<rgb24_big_pixel> Reader;
1853338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1854338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1855338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1856338b8dc3SIngo Weinhold 				break;
1857338b8dc3SIngo Weinhold 			}
1858338b8dc3SIngo Weinhold 			case B_RGB16:
1859338b8dc3SIngo Weinhold 			{
1860338b8dc3SIngo Weinhold 				typedef RGB16Reader<rgb16_pixel> Reader;
1861338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1862338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1863338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1864338b8dc3SIngo Weinhold 				break;
1865338b8dc3SIngo Weinhold 			}
1866338b8dc3SIngo Weinhold 			case B_RGB16_BIG:
1867338b8dc3SIngo Weinhold 			{
1868338b8dc3SIngo Weinhold 				typedef RGB16Reader<rgb16_big_pixel> Reader;
1869338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1870338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1871338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1872338b8dc3SIngo Weinhold 				break;
1873338b8dc3SIngo Weinhold 			}
1874338b8dc3SIngo Weinhold 			case B_RGB15: case B_RGBA15:
1875338b8dc3SIngo Weinhold 			{
1876338b8dc3SIngo Weinhold 				typedef RGB15Reader<rgb16_pixel> Reader;
1877338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1878338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1879338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1880338b8dc3SIngo Weinhold 				break;
1881338b8dc3SIngo Weinhold 			}
1882338b8dc3SIngo Weinhold 			case B_RGB15_BIG: case B_RGBA15_BIG:
1883338b8dc3SIngo Weinhold 			{
1884338b8dc3SIngo Weinhold 				typedef RGB15Reader<rgb16_big_pixel> Reader;
1885338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1886338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1887338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1888338b8dc3SIngo Weinhold 				break;
1889338b8dc3SIngo Weinhold 			}
1890338b8dc3SIngo Weinhold 			case B_CMAP8:
1891338b8dc3SIngo Weinhold 			{
1892338b8dc3SIngo Weinhold 				typedef CMAP8Reader Reader;
1893338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1894338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1895338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data, paletteConverter),
1896338b8dc3SIngo Weinhold 					paletteConverter);
1897338b8dc3SIngo Weinhold 				break;
1898338b8dc3SIngo Weinhold 			}
1899338b8dc3SIngo Weinhold 			case B_GRAY8:
1900338b8dc3SIngo Weinhold 			{
1901338b8dc3SIngo Weinhold 				typedef Gray8Reader Reader;
1902338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1903338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1904338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1905338b8dc3SIngo Weinhold 				break;
1906338b8dc3SIngo Weinhold 			}
1907338b8dc3SIngo Weinhold 			case B_GRAY1:
1908338b8dc3SIngo Weinhold 			{
1909338b8dc3SIngo Weinhold 				typedef Gray1Reader Reader;
1910338b8dc3SIngo Weinhold 				error = set_bits<Reader>(data, length, bpr, inRowSkip,
1911338b8dc3SIngo Weinhold 					fBasePtr, fSize, offset, fBytesPerRow, rawOutBPR,
1912338b8dc3SIngo Weinhold 					fColorSpace, width, Reader(data), paletteConverter);
1913338b8dc3SIngo Weinhold 				break;
1914338b8dc3SIngo Weinhold 			}
1915338b8dc3SIngo Weinhold 			// unsupported
1916338b8dc3SIngo Weinhold 			case B_NO_COLOR_SPACE:
1917338b8dc3SIngo Weinhold 			case B_YUV9: case B_YUV12:
1918338b8dc3SIngo Weinhold 			case B_UVL32: case B_UVLA32:
1919338b8dc3SIngo Weinhold 			case B_LAB32: case B_LABA32:
1920338b8dc3SIngo Weinhold 			case B_HSI32: case B_HSIA32:
1921338b8dc3SIngo Weinhold 			case B_HSV32: case B_HSVA32:
1922338b8dc3SIngo Weinhold 			case B_HLS32: case B_HLSA32:
1923338b8dc3SIngo Weinhold 			case B_CMY32: case B_CMYA32: case B_CMYK32:
1924338b8dc3SIngo Weinhold 			case B_UVL24: case B_LAB24: case B_HSI24:
1925338b8dc3SIngo Weinhold 			case B_HSV24: case B_HLS24: case B_CMY24:
1926338b8dc3SIngo Weinhold 			case B_YCbCr422: case B_YUV422:
1927338b8dc3SIngo Weinhold 			case B_YCbCr411: case B_YUV411:
1928338b8dc3SIngo Weinhold 			case B_YCbCr444: case B_YUV444:
1929338b8dc3SIngo Weinhold 			case B_YCbCr420: case B_YUV420:
1930338b8dc3SIngo Weinhold 			default:
1931338b8dc3SIngo Weinhold 				error = B_BAD_VALUE;
1932338b8dc3SIngo Weinhold 				break;
1933338b8dc3SIngo Weinhold 		}
1934338b8dc3SIngo Weinhold 	}
1935338b8dc3SIngo Weinhold 	return error;
1936338b8dc3SIngo Weinhold }
1937338b8dc3SIngo Weinhold 
193864b2d169SAxel Dörfler 
1939338b8dc3SIngo Weinhold /*!	\briefly Assigns another bitmap's data to this bitmap.
1940338b8dc3SIngo Weinhold 
1941338b8dc3SIngo Weinhold 	The supplied bitmap must have the exactly same dimensions as this bitmap.
1942338b8dc3SIngo Weinhold 	Its data are converted to the color space of this bitmap.
1943338b8dc3SIngo Weinhold 
1944338b8dc3SIngo Weinhold 	The currently supported source/target color spaces are
1945338b8dc3SIngo Weinhold 	\c B_RGB{32,24,16,15}[_BIG], \c B_CMAP8 and \c B_GRAY{8,1}.
1946338b8dc3SIngo Weinhold 
1947338b8dc3SIngo Weinhold 	\param bitmap The source bitmap.
1948338b8dc3SIngo Weinhold 	\return
1949338b8dc3SIngo Weinhold 	- \c B_OK: Everything went fine.
1950338b8dc3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a bitmap, or \a bitmap has other dimensions,
1951338b8dc3SIngo Weinhold 	  or the conversion from or to one of the color spaces is not supported.
1952338b8dc3SIngo Weinhold */
1953338b8dc3SIngo Weinhold status_t
1954338b8dc3SIngo Weinhold BBitmap::ImportBits(const BBitmap *bitmap)
1955338b8dc3SIngo Weinhold {
1956338b8dc3SIngo Weinhold 	status_t error = (InitCheck() == B_OK ? B_OK : B_NO_INIT);
1957338b8dc3SIngo Weinhold 	// check param
1958338b8dc3SIngo Weinhold 	if (error == B_OK && bitmap == NULL)
1959338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
1960338b8dc3SIngo Weinhold 	if (error == B_OK && bitmap->InitCheck() != B_OK)
1961338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
1962338b8dc3SIngo Weinhold 	if (error == B_OK && bitmap->Bounds() != fBounds)
1963338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
1964338b8dc3SIngo Weinhold 	// set bits
1965338b8dc3SIngo Weinhold 	if (error == B_OK) {
1966338b8dc3SIngo Weinhold 		error = ImportBits(bitmap->Bits(), bitmap->BitsLength(),
1967338b8dc3SIngo Weinhold 			bitmap->BytesPerRow(), 0, bitmap->ColorSpace());
1968338b8dc3SIngo Weinhold 	}
1969338b8dc3SIngo Weinhold 	return error;
1970338b8dc3SIngo Weinhold }
1971338b8dc3SIngo Weinhold 
197264b2d169SAxel Dörfler 
1973338b8dc3SIngo Weinhold status_t
1974338b8dc3SIngo Weinhold BBitmap::GetOverlayRestrictions(overlay_restrictions *restrictions) const
1975338b8dc3SIngo Weinhold {
1976338b8dc3SIngo Weinhold 	// TODO: Implement
1977338b8dc3SIngo Weinhold 	return B_ERROR;
1978338b8dc3SIngo Weinhold }
1979338b8dc3SIngo Weinhold 
198064b2d169SAxel Dörfler 
1981338b8dc3SIngo Weinhold status_t
1982338b8dc3SIngo Weinhold BBitmap::Perform(perform_code d, void *arg)
1983338b8dc3SIngo Weinhold {
1984338b8dc3SIngo Weinhold 	return BArchivable::Perform(d, arg);
1985338b8dc3SIngo Weinhold }
1986338b8dc3SIngo Weinhold 
198764b2d169SAxel Dörfler 
1988338b8dc3SIngo Weinhold // FBC
1989338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap1() {}
1990338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap2() {}
1991338b8dc3SIngo Weinhold void BBitmap::_ReservedBitmap3() {}
1992338b8dc3SIngo Weinhold 
199364b2d169SAxel Dörfler 
1994338b8dc3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1995338b8dc3SIngo Weinhold */
1996338b8dc3SIngo Weinhold BBitmap::BBitmap(const BBitmap &)
1997338b8dc3SIngo Weinhold {
1998338b8dc3SIngo Weinhold }
1999338b8dc3SIngo Weinhold 
200064b2d169SAxel Dörfler 
2001338b8dc3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
2002338b8dc3SIngo Weinhold */
2003338b8dc3SIngo Weinhold BBitmap &
2004338b8dc3SIngo Weinhold BBitmap::operator=(const BBitmap &)
2005338b8dc3SIngo Weinhold {
2006338b8dc3SIngo Weinhold 	return *this;
2007338b8dc3SIngo Weinhold }
2008338b8dc3SIngo Weinhold 
200964b2d169SAxel Dörfler 
2010338b8dc3SIngo Weinhold char *
2011338b8dc3SIngo Weinhold BBitmap::get_shared_pointer() const
2012338b8dc3SIngo Weinhold {
2013338b8dc3SIngo Weinhold 	return NULL;	// not implemented
2014338b8dc3SIngo Weinhold }
2015338b8dc3SIngo Weinhold 
201664b2d169SAxel Dörfler 
2017338b8dc3SIngo Weinhold int32
2018338b8dc3SIngo Weinhold BBitmap::get_server_token() const
2019338b8dc3SIngo Weinhold {
2020338b8dc3SIngo Weinhold 	return fServerToken;
2021338b8dc3SIngo Weinhold }
2022338b8dc3SIngo Weinhold 
202364b2d169SAxel Dörfler 
2024338b8dc3SIngo Weinhold /*!	\brief Initializes the bitmap.
2025338b8dc3SIngo Weinhold 	\param bounds The bitmap dimensions.
2026338b8dc3SIngo Weinhold 	\param colorSpace The bitmap's color space.
2027338b8dc3SIngo Weinhold 	\param flags Creation flags.
2028338b8dc3SIngo Weinhold 	\param bytesPerRow The number of bytes per row the bitmap should use.
2029338b8dc3SIngo Weinhold 		   \c B_ANY_BYTES_PER_ROW to let the constructor choose an appropriate
2030338b8dc3SIngo Weinhold 		   value.
2031338b8dc3SIngo Weinhold 	\param screenID ???
2032338b8dc3SIngo Weinhold */
2033338b8dc3SIngo Weinhold void
2034338b8dc3SIngo Weinhold BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags,
2035338b8dc3SIngo Weinhold 	int32 bytesPerRow, screen_id screenID)
2036338b8dc3SIngo Weinhold {
2037338b8dc3SIngo Weinhold //printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n",
2038338b8dc3SIngo Weinhold //	   bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow);
2039338b8dc3SIngo Weinhold 
2040338b8dc3SIngo Weinhold 	// TODO: Hanlde setting up the offscreen window if we're such a bitmap!
2041338b8dc3SIngo Weinhold 
2042338b8dc3SIngo Weinhold 	// TODO: Should we handle rounding of the "bounds" here? How does R5 behave?
2043338b8dc3SIngo Weinhold 
2044338b8dc3SIngo Weinhold 	status_t error = B_OK;
2045338b8dc3SIngo Weinhold 
2046338b8dc3SIngo Weinhold //#ifdef RUN_WITHOUT_APP_SERVER
2047338b8dc3SIngo Weinhold 	flags |= B_BITMAP_NO_SERVER_LINK;
2048338b8dc3SIngo Weinhold //#endif	// RUN_WITHOUT_APP_SERVER
2049338b8dc3SIngo Weinhold flags &= ~B_BITMAP_ACCEPTS_VIEWS;
2050338b8dc3SIngo Weinhold 
2051338b8dc3SIngo Weinhold 	CleanUp();
2052338b8dc3SIngo Weinhold 
2053338b8dc3SIngo Weinhold 	// check params
2054338b8dc3SIngo Weinhold 	if (!bounds.IsValid() || !bitmaps_support_space(colorSpace, NULL))
2055338b8dc3SIngo Weinhold 		error = B_BAD_VALUE;
2056338b8dc3SIngo Weinhold 	if (error == B_OK) {
2057338b8dc3SIngo Weinhold 		int32 bpr = get_bytes_per_row(colorSpace, bounds.IntegerWidth() + 1);
2058338b8dc3SIngo Weinhold 		if (bytesPerRow < 0)
2059338b8dc3SIngo Weinhold 			bytesPerRow = bpr;
2060338b8dc3SIngo Weinhold 		else if (bytesPerRow < bpr)
2061338b8dc3SIngo Weinhold // NOTE: How does R5 behave?
2062338b8dc3SIngo Weinhold 			error = B_BAD_VALUE;
2063338b8dc3SIngo Weinhold 	}
2064338b8dc3SIngo Weinhold 	// allocate the bitmap buffer
2065338b8dc3SIngo Weinhold 	if (error == B_OK) {
2066338b8dc3SIngo Weinhold 		// NOTE: Maybe the code would look more robust if the
2067338b8dc3SIngo Weinhold 		// "size" was not calculated here when we ask the server
2068338b8dc3SIngo Weinhold 		// to allocate the bitmap. -Stephan
2069338b8dc3SIngo Weinhold 		int32 size = bytesPerRow * (bounds.IntegerHeight() + 1);
2070338b8dc3SIngo Weinhold 
2071338b8dc3SIngo Weinhold 		if (flags & B_BITMAP_NO_SERVER_LINK) {
2072338b8dc3SIngo Weinhold 			fBasePtr = malloc(size);
2073338b8dc3SIngo Weinhold 			if (fBasePtr) {
2074338b8dc3SIngo Weinhold 				fSize = size;
2075338b8dc3SIngo Weinhold 				fColorSpace = colorSpace;
2076338b8dc3SIngo Weinhold 				fBounds = bounds;
2077338b8dc3SIngo Weinhold 				fBytesPerRow = bytesPerRow;
2078338b8dc3SIngo Weinhold 				fFlags = flags;
2079338b8dc3SIngo Weinhold 			} else
2080338b8dc3SIngo Weinhold 				error = B_NO_MEMORY;
2081338b8dc3SIngo Weinhold 		} else {
2082338b8dc3SIngo Weinhold // 			// Ask the server (via our owning application) to create a bitmap.
2083338b8dc3SIngo Weinhold // 			BPrivate::AppServerLink link;
2084338b8dc3SIngo Weinhold //
2085338b8dc3SIngo Weinhold // 			// Attach Data:
2086338b8dc3SIngo Weinhold // 			// 1) BRect bounds
2087338b8dc3SIngo Weinhold // 			// 2) color_space space
2088338b8dc3SIngo Weinhold // 			// 3) int32 bitmap_flags
2089338b8dc3SIngo Weinhold // 			// 4) int32 bytes_per_row
2090338b8dc3SIngo Weinhold // 			// 5) int32 screen_id::id
2091338b8dc3SIngo Weinhold // 			link.StartMessage(AS_CREATE_BITMAP);
2092338b8dc3SIngo Weinhold // 			link.Attach<BRect>(bounds);
2093338b8dc3SIngo Weinhold // 			link.Attach<color_space>(colorSpace);
2094338b8dc3SIngo Weinhold // 			link.Attach<int32>((int32)flags);
2095338b8dc3SIngo Weinhold // 			link.Attach<int32>(bytesPerRow);
2096338b8dc3SIngo Weinhold // 			link.Attach<int32>(screenID.id);
2097338b8dc3SIngo Weinhold //
2098338b8dc3SIngo Weinhold // 			// Reply Code: SERVER_TRUE
2099338b8dc3SIngo Weinhold // 			// Reply Data:
2100338b8dc3SIngo Weinhold // 			//	1) int32 server token
2101338b8dc3SIngo Weinhold // 			//	2) area_id id of the area in which the bitmap data resides
2102338b8dc3SIngo Weinhold // 			//	3) int32 area pointer offset used to calculate fBasePtr
2103338b8dc3SIngo Weinhold //
2104338b8dc3SIngo Weinhold // 			// alternatively, if something went wrong
2105338b8dc3SIngo Weinhold // 			// Reply Code: SERVER_FALSE
2106338b8dc3SIngo Weinhold // 			// Reply Data:
2107338b8dc3SIngo Weinhold // 			//		None
2108338b8dc3SIngo Weinhold // 			int32 code = SERVER_FALSE;
2109338b8dc3SIngo Weinhold // 			error = link.FlushWithReply(code);
2110338b8dc3SIngo Weinhold //
2111338b8dc3SIngo Weinhold // 			if (error >= B_OK) {
2112338b8dc3SIngo Weinhold // 				// *communication* with server successful
2113338b8dc3SIngo Weinhold // 				if (code == SERVER_TRUE) {
2114338b8dc3SIngo Weinhold // 					// server side success
2115338b8dc3SIngo Weinhold // 					// Get token
2116338b8dc3SIngo Weinhold // 					area_id bmparea;
2117338b8dc3SIngo Weinhold // 					int32 areaoffset;
2118338b8dc3SIngo Weinhold //
2119338b8dc3SIngo Weinhold // 					link.Read<int32>(&fServerToken);
2120338b8dc3SIngo Weinhold // 					link.Read<area_id>(&bmparea);
2121338b8dc3SIngo Weinhold // 					link.Read<int32>(&areaoffset);
2122338b8dc3SIngo Weinhold //
2123338b8dc3SIngo Weinhold // 					// Get the area in which the data resides
2124338b8dc3SIngo Weinhold // 					fArea = clone_area("shared bitmap area",
2125338b8dc3SIngo Weinhold // 									   (void**)&fBasePtr,
2126338b8dc3SIngo Weinhold // 									   B_ANY_ADDRESS,
2127338b8dc3SIngo Weinhold // 									   B_READ_AREA | B_WRITE_AREA,
2128338b8dc3SIngo Weinhold // 									   bmparea);
2129338b8dc3SIngo Weinhold //
2130338b8dc3SIngo Weinhold // 					// Jump to the location in the area
2131338b8dc3SIngo Weinhold // 					fBasePtr = (int8*)fBasePtr + areaoffset;
2132338b8dc3SIngo Weinhold //
2133338b8dc3SIngo Weinhold // 					fSize = size;
2134338b8dc3SIngo Weinhold // 					fColorSpace = colorSpace;
2135338b8dc3SIngo Weinhold // 					fBounds = bounds;
2136338b8dc3SIngo Weinhold // 					fBytesPerRow = bytesPerRow;
2137338b8dc3SIngo Weinhold // 					fFlags = flags;
2138338b8dc3SIngo Weinhold // 				} else {
2139338b8dc3SIngo Weinhold // 					// server side error, we assume:
2140338b8dc3SIngo Weinhold // 					error = B_NO_MEMORY;
2141338b8dc3SIngo Weinhold // 				}
2142338b8dc3SIngo Weinhold // 			}
2143338b8dc3SIngo Weinhold // 			// NOTE: not "else" to handle B_NO_MEMORY on server side!
2144338b8dc3SIngo Weinhold // 			if (error < B_OK) {
2145338b8dc3SIngo Weinhold // 				fBasePtr = NULL;
2146338b8dc3SIngo Weinhold // 				fServerToken = -1;
2147338b8dc3SIngo Weinhold // 				fArea = -1;
2148338b8dc3SIngo Weinhold // 				// NOTE: why not "0" in case of error?
2149338b8dc3SIngo Weinhold // 				fFlags = flags;
2150338b8dc3SIngo Weinhold // 			}
2151338b8dc3SIngo Weinhold 		}
2152338b8dc3SIngo Weinhold //		fWindow = NULL;
2153338b8dc3SIngo Weinhold 		fToken = -1;
2154338b8dc3SIngo Weinhold 		fOrigArea = -1;
2155338b8dc3SIngo Weinhold 	}
2156338b8dc3SIngo Weinhold 
2157338b8dc3SIngo Weinhold 	fInitError = error;
2158338b8dc3SIngo Weinhold 	// TODO: on success, handle clearing to white if the flags say so. Needs to be
2159338b8dc3SIngo Weinhold 	// dependent on color space.
2160338b8dc3SIngo Weinhold 
2161338b8dc3SIngo Weinhold 	if (fInitError == B_OK) {
2162338b8dc3SIngo Weinhold 		if (flags & B_BITMAP_ACCEPTS_VIEWS) {
2163338b8dc3SIngo Weinhold // 			fWindow = new BWindow(Bounds(), fServerToken);
2164338b8dc3SIngo Weinhold // 			// A BWindow starts life locked and is unlocked
2165338b8dc3SIngo Weinhold // 			// in Show(), but this window is never shown and
2166338b8dc3SIngo Weinhold // 			// it's message loop is never started.
2167338b8dc3SIngo Weinhold // 			fWindow->Unlock();
2168338b8dc3SIngo Weinhold 		}
2169338b8dc3SIngo Weinhold 	}
2170338b8dc3SIngo Weinhold }
2171338b8dc3SIngo Weinhold 
217264b2d169SAxel Dörfler 
2173338b8dc3SIngo Weinhold /*!	\brief Cleans up any memory allocated by the bitmap or
2174338b8dc3SIngo Weinhold 		   informs the server to do so.
2175338b8dc3SIngo Weinhold */
2176338b8dc3SIngo Weinhold void
2177338b8dc3SIngo Weinhold BBitmap::CleanUp()
2178338b8dc3SIngo Weinhold {
2179338b8dc3SIngo Weinhold 	if (fBasePtr) {
2180338b8dc3SIngo Weinhold 		if (fFlags & B_BITMAP_NO_SERVER_LINK) {
2181338b8dc3SIngo Weinhold 			free(fBasePtr);
2182338b8dc3SIngo Weinhold 		} else {
2183338b8dc3SIngo Weinhold // 			BPrivate::AppServerLink link;
2184338b8dc3SIngo Weinhold // 			// AS_DELETE_BITMAP:
2185338b8dc3SIngo Weinhold // 			// Attached Data:
2186338b8dc3SIngo Weinhold // 			//	1) int32 server token
2187338b8dc3SIngo Weinhold //
2188338b8dc3SIngo Weinhold // 			// Reply Code: SERVER_TRUE if successful,
2189338b8dc3SIngo Weinhold // 			//			   SERVER_FALSE if the buffer was already deleted
2190338b8dc3SIngo Weinhold // 			// Reply Data: none
2191338b8dc3SIngo Weinhold // //			status_t freestat;
2192338b8dc3SIngo Weinhold // 			int32 code = SERVER_FALSE;
2193338b8dc3SIngo Weinhold // 			link.StartMessage(AS_DELETE_BITMAP);
2194338b8dc3SIngo Weinhold // 			link.Attach<int32>(fServerToken);
2195338b8dc3SIngo Weinhold // 			link.FlushWithReply(code);
2196338b8dc3SIngo Weinhold // 			if (code == SERVER_FALSE) {
2197338b8dc3SIngo Weinhold // 				// TODO: Find out if "SERVER_FALSE if the buffer
2198338b8dc3SIngo Weinhold // 				// was already deleted" is true. If not, maybe we
2199338b8dc3SIngo Weinhold // 				// need to take additional action.
2200338b8dc3SIngo Weinhold // 			}
2201338b8dc3SIngo Weinhold // 			fArea = -1;
2202338b8dc3SIngo Weinhold // 			fServerToken = -1;
2203338b8dc3SIngo Weinhold 		}
2204338b8dc3SIngo Weinhold 		fBasePtr = NULL;
2205338b8dc3SIngo Weinhold 	}
2206338b8dc3SIngo Weinhold }
2207338b8dc3SIngo Weinhold 
220864b2d169SAxel Dörfler 
2209338b8dc3SIngo Weinhold void
2210338b8dc3SIngo Weinhold BBitmap::AssertPtr()
2211338b8dc3SIngo Weinhold {
2212338b8dc3SIngo Weinhold }
2213338b8dc3SIngo Weinhold 
2214